我想序列化可能包含Dictionary<string, object>
值或其他类型值的System.Drawing.Color
。我使用TypeNameHandling.Auto
创建了一个序列化程序,这适用于大多数类,但不适用于Color
。
示例代码:(DotNetFiddle:https://dotnetfiddle.net/UvphQO)
public class Program
{
class A { }
class B { }
public static void Main()
{
Dictionary<string, object> dict = new Dictionary<string, object>();
dict["Foo"] = new A();
dict["Bar"] = new B();
dict["Baz"] = new object();
dict["Rainbow"] = Color.FromArgb(20, 20, 20, 20);
var ser = new JsonSerializer
{
TypeNameHandling = TypeNameHandling.Auto
};
var w = new JsonTextWriter(Console.Out)
{
Formatting = Formatting.Indented
};
ser.Serialize(w, dict);
}
}
结果输出:
{
"Foo": {
"$type": "Program+A, mi1i2eqo"
},
"Bar": {
"$type": "Program+B, mi1i2eqo"
},
"Baz": {},
"Rainbow": "20, 20, 20, 20"
}
正如所料,字典中A
或B
的实例具有重建所需的$type
元数据。但Color
的实例却没有。当这个json被反序列化时,dict["Rainbow"]
是System.String
。
我有很多方法可以解决这个问题,但首选的解决方案是弄清楚为什么序列化程序在这种情况下使用$type
执行看似不正确的操作。
答案 0 :(得分:1)
问题是System.Drawing.Color
有一个关联的TypeConverter
,Json.Net使用它将类型转换为字符串值并返回。但是,由于输出值是字符串(不是复杂对象),因此Json.Net不会为其输出任何类型信息。如果您的属性被定义为object
而不是强类型,则会在反序列化期间导致问题:Json.Net无法找到TypeConverter
,因此无法转换字符串值返回Color
。
解决此问题的一种方法是将Color
包装在另一个具有颜色值的强类型属性的类中。
class ColorHolder
{
public System.Drawing.Color Value { get; set; }
}
然后,Json.Net将写出包装类的类型信息,这将允许嵌套的Color
结构正确反序列化。这是一个往返演示:
class Program
{
static void Main(string[] args)
{
Dictionary<string, object> dict = new Dictionary<string, object>();
dict["Rainbow"] = new ColorHolder { Value = Color.FromArgb(10, 20, 30, 40) };
JsonSerializerSettings settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(dict, settings);
Console.WriteLine(json);
Console.WriteLine();
var d = JsonConvert.DeserializeObject<Dictionary<string, object>>(json, settings);
ColorHolder holder = (ColorHolder)d["Rainbow"];
Console.WriteLine("A=" + holder.Value.A);
Console.WriteLine("R=" + holder.Value.R);
Console.WriteLine("G=" + holder.Value.G);
Console.WriteLine("B=" + holder.Value.B);
}
}
输出:
{
"Rainbow": {
"$type": "JsonTest.ColorHolder, JsonTest",
"Value": "10, 20, 30, 40"
}
}
A=10
R=20
G=30
B=40
答案 1 :(得分:0)
System.Drawing.Color
是一个结构,而不是.NET中的类。这听起来像是你问题的答案。尝试用类包装它,或者创建自己的颜色类,它应该解决它。