2014-05-08 94 views
1

我正在使用JSON.NET並且必須反序列化此結構。JSON反序列化「unhandy」字典

"NameValue": [ 
    { 
     "Name": "CONO", 
     "Value": "001" 
    }, 
    { 
     "Name": "DIVI", 
     "Value": " " 
    }, 
    { 
     "Name": "LNCD", 
     "Value": "DE" 
    }, 
    { 
     "Name": "CUNO", 
     "Value": "#AT-VORL " 
    }, 
] 

這是一個較大的對象的一部分,我想反序列化到MyType。我可以有一個屬性NameValue,這是一個鍵入對象的列表MyNameValue,它有兩個屬性NameValue。但這只是一個字典的怪異表示(名字永遠不會重疊),所以我想要一個.NET字典,它會更方便。

如何在我的類上使用屬性來實現此目的?

什麼樣的作品是這樣的:

private class JsonResponseRecord 
    { 
     public string RowIndex { get; set; } 

     [JsonProperty(PropertyName = "NameValue")] 
     public List<KeyValuePair<string, string>> Values { get; set; } 
    } 

但它與所有的按鍵都null而值是否正確填寫KeyValuePairs的列表結束。我想他會要求JSON有"Key"而不是"Name"


要明確:我想有一個Dictionary<string, string>類型Values屬性一樣的:

private class JsonResponseRecord 
    { 
     public string RowIndex { get; set; } 

     [JsonProperty(PropertyName = "NameValue")] 
     public Dictionary<string, string> Values { get; set; } 
    } 
+0

我想可能期望的「鑰匙」,而不是「名」,但是這必須是相當容易,雖然克服了,最壞的情況下,你可以使用動態類型,以填補KeyValuePair或將它反序列化爲一個具有正確名稱的類,也可能是一個選項。 – Viezevingertjes

回答

1

我能用自定義轉換器做到這一點。如果這可能與JSON.NET標準,我將不勝感激輸入。

這纔是我的接收對象:

internal class ResponseRecord 
{ 
    public string RowIndex { get; set; } 

    [JsonProperty(PropertyName = "NameValue"), JsonConverter(typeof(JsonNameValueListToDictionaryConverter))] 
    public Dictionary<string, string> Values { get; set; } 
} 

這是轉換器代碼:

/// <summary> 
/// Converts the NameValue-array with object containing name and value to a Dictionary. 
/// </summary> 
internal class JsonNameValueListToDictionaryConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotSupportedException(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     Dictionary<string, string> dictionary = existingValue as Dictionary<string, string> ?? new Dictionary<string, string>(); 

     if (reader.TokenType == JsonToken.StartArray) 
     { 
      int startDepth = reader.Depth; 
      while (reader.Read()) 
      { 
       if ((reader.Depth == startDepth) && (reader.TokenType == JsonToken.EndArray)) break; 

       if (reader.TokenType == JsonToken.StartObject) 
       { 
        KeyValuePair<string, string> kvp = GetKeyValueFromJsonObject(reader, "Name", "Value"); 
        dictionary[kvp.Key] = kvp.Value; // always override existing keys 
       } 
       else 
       { 
        throw new NotSupportedException(String.Format("Unexpected JSON token '{0}' while reading special Dictionary", reader.TokenType)); 
       } 
      } 
     } 

     return dictionary; 
    } 

    private KeyValuePair<string, string> GetKeyValueFromJsonObject(JsonReader reader, string propNameKey, string propNameValue) 
    { 
     string key = null; 
     string value = null; 
     int startDepth = reader.Depth; 
     while (reader.Read()) 
     { 
      if ((reader.TokenType == JsonToken.EndObject) && (reader.Depth == startDepth)) break; 

      if (reader.TokenType == JsonToken.PropertyName) 
      { 
       string propName = reader.Value as string; 
       if (propName == null) continue; 
       if (propName.Equals(propNameKey, StringComparison.InvariantCulture)) 
       { 
        key = reader.ReadAsString(); 
       } 
       else if (propName.Equals(propNameValue, StringComparison.InvariantCulture)) 
       { 
        value = reader.ReadAsString(); 
       } 
      } 
     } 
     return new KeyValuePair<string, string>(key, value); 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return (objectType.Equals(typeof(Dictionary<string, string>))); 
    } 

} 
1

使用JSON.NET,選擇性粘貼 「作爲JSON類」,它給你: -

public class Rootobject 
{ 
public Namevalue[] NameValue { get; set; } 
} 

public class Namevalue 
{ 
public string Name { get; set; } 
public string Value { get; set; } 
} 
+0

是的,但這意味着我將通過循環訪問數組並將「Name」與「DIVI」進行比較,並在發現時使用「Value」來訪問密鑰「DIVI」。當讀到字典時,這是相當容易和快速的。 – ZoolWay

2

首先一點校正,您張貼的JSON字符串。它應該是這樣的:

var json = { 
     "NameValue": [ 
     { 
      "Name": "CONO", 
      "Value": "001" 
     }, 
     { 
      "Name": "DIVI", 
      "Value": " " 
     }, 
     { 
      "Name": "LNCD", 
      "Value": "DE" 
     }, 
     { 
      "Name": "CUNO", 
      "Value": "#AT-VORL " 
     } 
     ] 
    } 

可以acchieve你想要使用JSON.NET內置Linq to JSON。這裏是samlple代碼:

var jObject = JObject.Parse(json); 
    var jsonResponseRecordObj = new JsonResponseRecord 
       { 
        Values = 
         jObject["NameValue"].ToDictionary(row => (string) row["Name"], row => (string) row["Value"]) 
       };