2015-12-11 32 views
0

我得到一個數據均勻性問題很少的json字符串。 例如,json字符串中的一個字段返回字符串列表,而其他json字符串中的相同字段返回字典(鍵值對)。如何覆蓋JavaScriptSerializer.Deserialize <T>()

我的類,其中包含解析的json值具有作爲列表字段的屬性。 由於此數據一致性問題,json字符串未正確解析。

以下是我的代碼來解析JSON字符串

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
myClass mc = serializer.Deserialize<myClass>(jsonString); 

在那裏與我可以編寫自定義代碼來解析JSON字符串,並映射它MYCLASS什麼辦法?

+0

你知道什麼時候它是返回列表和字典,或者它是隨機的嗎? – mybirthname

+0

它返回json的第三方api。我不知道什麼時候會返回列表和字典。 –

+1

您可以爲自己編寫['JavaScriptConverter'](https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptconverter%28v=vs.110%29.aspx)類。除此之外,我還需要一些具體的問題。 – dbc

回答

1

你沒有給出你正在努力完成的具體事例,這意味着我們需要自己做一個例子。考慮下面的類:

public class myClass 
{ 
    public Dictionary<string, string> data { get; set; } 
} 

,並考慮以下兩個JSON字符串:

{"data": ["zero", 1, "two"]} 
{"data": {"0": "zero", "1":1, "2":"two"}} 

好像你可能想同樣分析這些,與陣列被轉換爲Dictionary<string, string>的鍵是數組指數。這可以用下面的JavaScriptConverter來完成:

public class myClassConverter : JavaScriptConverter 
{ 
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) 
    { 
     var myClass = new myClass(); 

     object data; 
     if (dictionary.TryGetValue("data", out data)) 
     { 
      if (data.IsJsonArray()) 
      { 
       myClass.data = data.AsJsonArray() 
        .Select((o, i) => new KeyValuePair<int, object>(i, o)) 
        .ToDictionary(p => p.Key.ToString(NumberFormatInfo.InvariantInfo), p => serializer.ConvertToType<string>(p.Value)); 
      } 
      else if (data.IsJsonObject()) 
      { 
       myClass.data = data.AsJsonObject() 
        .ToDictionary(p => p.Key, p => serializer.ConvertToType<string>(p.Value)); 
      } 
     } 

     return myClass; 
    } 

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override IEnumerable<Type> SupportedTypes 
    { 
     get { return new [] { typeof(myClass) }; } 
    } 
} 

public static class JavaScriptSerializerObjectExtensions 
{ 
    public static bool IsJsonArray(this object obj) 
    { 
     if (obj is string || obj.IsJsonObject()) 
      return false; 
     return obj is IEnumerable; 
    } 

    public static IEnumerable<object> AsJsonArray(this object obj) 
    { 
     return (obj as IEnumerable).Cast<object>(); 
    } 

    public static bool IsJsonObject(this object obj) 
    { 
     return obj is IDictionary<string, object>; 
    } 

    public static IDictionary<string, object> AsJsonObject(this object obj) 
    { 
     return obj as IDictionary<string, object>; 
    } 
} 

IDictionary<string, object>傳遞給Deserialize()對應於JSON對象的鍵/值對被轉換。對於特定鍵(在這種情況下爲"data"),如果該值依次爲JSON對象,則object值爲IDictionary<string, object>;如果該值爲JSON數組,則值爲IEnumerable(具體爲ArrayList)。通過根據適當的類型測試該值,可以進行轉換。

該轉換器只做反序列化。像這樣使用它:

 var jsonString1 = @"{""data"": [""zero"", 1, ""two""]}"; 
     var jsonString2 = @"{""data"": {""0"": ""zero"", ""1"":1, ""2"":""two""}}"; 

     var deserializer = new JavaScriptSerializer(); 
     deserializer.RegisterConverters(new JavaScriptConverter[] { new myClassConverter() }); 

     var newJson1 = new JavaScriptSerializer().Serialize(deserializer.Deserialize<myClass>(jsonString1)); 
     var newJson2 = new JavaScriptSerializer().Serialize(deserializer.Deserialize<myClass>(jsonString2)); 

     Console.WriteLine(newJson1); // Prints {"data":{"0":"zero","1":"1","2":"two"}} 
     Console.WriteLine(newJson2); // Prints {"data":{"0":"zero","1":"1","2":"two"}} 

     Debug.Assert(newJson1 == newJson2); // No assert