json.net:序列化从ObservableCollection派生的类型时出现问题
本文关键字:类型 问题 派生 net 序列化 ObservableCollection json | 更新日期: 2023-09-27 18:21:24
我有一个扩展基本ObservableCollection<T>
类的类(添加了更多属性)。当我使用json.net序列化类时,它会省略添加的属性。例如,以下类:
public class ObservableCollectionExt : ObservableCollection<int>
{
[DataMember]
public string MyData1 { get; set; }
[DataMember]
public string MyData2 { get; set; }
public ObservableCollectionExt()
{
}
[JsonConstructor]
public ObservableCollectionExt(string mydata1, string mydata2)
{
MyData1 = mydata1;
MyData2 = mydata2;
}
public static ObservableCollectionExt Create()
{
ObservableCollectionExt coll = new ObservableCollectionExt("MyData1", "MyData2");
coll.Add(1);
coll.Add(2);
coll.Add(3);
return coll;
}
}
按如下方式序列化(缺少MyData1
和MyData2
的值):
{"$type":"Test1.ObservableCollectionExt,Test1","$values":[1.2.3.]}
如何在序列化的数据中包含额外的属性?
您可能需要一个自定义转换器。不确定这是否是最好的方法,但它似乎奏效了。
public class MyCustomConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ObservableCollectionExt);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
ObservableCollectionExt result = new ObservableCollectionExt();
string type = null;
int i;
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName)
type = reader.Value.ToString();
else if (reader.TokenType == JsonToken.EndObject)
return result;
else if (!string.IsNullOrEmpty(type) && reader.Value != null)
{
switch (type)
{
case "mydata1":
{
result.MyData1 = reader.Value.ToString();
break;
}
case "mydata2":
{
result.MyData2 = reader.Value.ToString();
break;
}
case "elements":
{
if (int.TryParse(reader.Value.ToString(), out i))
result.Add(i);
break;
}
}
}
}
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
ObservableCollectionExt o = (ObservableCollectionExt)value;
writer.WriteStartObject();
writer.WritePropertyName("mydata1");
writer.WriteValue(o.MyData1);
writer.WritePropertyName("mydata2");
writer.WriteValue(o.MyData2);
writer.WritePropertyName("elements");
writer.WriteStartArray();
foreach (var val in o)
writer.WriteValue(val);
writer.WriteEndArray();
writer.WriteEndObject();
}
}
这会产生如下字符串:{'"mydata1'":'"MyData1'",'"mydata2'":'"MyData2'",'"elements'":[1,2,3]}
使用这样的转换器:
ObservableCollectionExt o = ObservableCollectionExt.Create();
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new MyCustomConverter());
string serialized = JsonConvert.SerializeObject(o, settings);
ObservableCollectionExt deserialized = JsonConvert.DeserializeObject<ObservableCollectionExt>(serialized, settings);
编辑:
我意识到,当自定义属性不是复杂类型时,转换器只适用于简单的情况。还有另一种方法,一种匿名类型的变通方法:
ObservableCollectionExt o = ObservableCollectionExt.Create();
string serialized = JsonConvert.SerializeObject(new { MyData1 = o.MyData1, MyData2 = o.MyData2, coll = o });
var anonType = new { MyData1 = null as object, MyData2 = null as object, coll = null as object };
dynamic d = JsonConvert.DeserializeAnonymousType(serialized, anonType);
ObservableCollectionExt deserialized = new ObservableCollectionExt(d.MyData1, d.MyData2);
foreach (var elem in d.coll)
deserialized.Add((int)elem);