2014-11-24 58 views
0

我有這樣的結構:通過屬性名稱更改JSON.net內容?

List<dynamic> lst = new List<dynamic>(); 
    lst.Add(new{objId = 1,myOtherColumn = 5}); 
    lst.Add(new{objId = 2,myOtherColumn = 6}); 
    lst.Add(new{lala = "asd" ,lala2 = 7}); 

我通過其序列:

string st= JsonConvert.SerializeObject(lst); 

問:

我怎樣才能使串行只改變值的objId」屬性,到別的東西?

我知道我應該使用class Myconverter : JsonConverter,但我沒有找到任何保持默認行爲的示例,另外 - 允許我添加序列化的條件邏輯。

+0

看起來相當棘手。正如你所說,你想要使用一個自定義的'JsonConverter',但是由於你使用的是匿名類型,轉換器中的'CanConvert'方法不能輕易地說「是的,我可以處理這種類型」。 – 2014-11-24 12:06:49

+0

@JamesThorpe如果它有幫助,我不想複雜的東西,所以我把這個簡單的代碼,但在現實中,數據可以是任何東西:http://i.stack.imgur.com/Z0M06.jpg – 2014-11-24 12:11:41

回答

2

這裏有一個轉換器可以處理它,至少對於你的例子中的簡單對象。它會查找包含objId屬性的對象,然後序列化它在其上找到的所有屬性。您可能需要擴大它來對付其他成員類型/更復雜的性能要求:

class MyConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     writer.WriteStartObject(); 
     foreach (var prop in value.GetType().GetProperties()) { 
      writer.WritePropertyName(prop.Name); 
      if (prop.Name == "objId") { 
       //modify objId values for example 
       writer.WriteValue(Convert.ToInt32(prop.GetValue(value, null)) + 10); 
      } else { 
       writer.WriteValue(prop.GetValue(value, null)); 
      }     
     } 
     writer.WriteEndObject(); 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     //only attempt to handle types that have an objId property 
     return (objectType.GetProperties().Count(p => p.Name == "objId") == 1); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

或者,你可以使用一個轉換器,指定它只會轉換int類型,然後查詢其中的JSON路徑你在做任何轉換之前。這有利於不需要處理匿名類型的所有其他成員。

class MyConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     if (writer.Path.EndsWith(".objId")) { 
      writer.WriteValue(Convert.ToInt32(value) + 10); 
     } 
     else { 
      writer.WriteValue(value); 
     } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof (int); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
}