2014-09-10 67 views
0

我有一個類擴展了基本的ObservableCollection<T>類(增加了一些屬性)。當我使用json.net序列化類時,它省略了添加的屬性。例如,下面的類:json.net:從ObservableCollection派生的序列化類型的問題

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; 
    } 

} 

被序列如下(帶有值MyData1MyData2缺失):

{ 「$類型」: 「Test1.ObservableCollectionExt,測試1」, 「$值「:[1 , 2,] }

如何可以包括在序列化的數據的額外屬性?

回答

1

您可能需要自定義轉換器。不知道這是做到這一點的最佳方式,但它似乎工作。

 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); 
+1

使用轉換器工作,但是,由於額外的屬性,在我的情況,實際上是其他複雜的類型,我會寫串行/解串碼所有這些 - 相當艱鉅的任務!我希望有一個更簡單的解決方案。 – user2774635 2014-09-10 11:29:03

+0

你是對的,看到我更新的答案,我找到了另一種方式。 – parachutingturtle 2014-09-10 12:06:26

+0

謝謝,這工作! – user2774635 2014-09-10 16:25:29