2014-04-29 12 views
2

當合同類型不匹配時,是否可以跳過部分json?也就是說,我收到一個不符合模式的json響應 - 空對象被串行化爲空數組(「php」序列化程序「謝謝」)。所以,而不是「空」或「{}」我得到「[]」。在JSON.NET中處理錯誤的合同類型

到目前爲止,我嘗試使用JsonSerializerSettings中提供的錯誤事件處理程序。但是,這種方法相當難看,因爲Json.net沒有返回有意義的異常類型。有效響應的

例:無效響應

{ 
    "key": "key", 
    "id": "id", 
    "status": "status", 
    "opts": { 
     "start": 42, 
     "limit": 12 
     } 
    } 
} 

{ 
    "key": "key", 
    "id": "id", 
    "status": "status", 
    "opts": [] 
} 

回答

1

您可以使用自定義JsonConverter處理這個問題。轉換器可以檢測JSON中opts屬性的格式,然後將其反序列化或將其值設置爲目標對象中的空值。以下是我會寫的轉換器:

class OptsConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(Opts)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JToken token = JToken.Load(reader); 
     if (token.Type == JTokenType.Object) 
     { 
      return new Opts 
      { 
       start = (int)token["start"], 
       limit = (int)token["limit"] 
      }; 
     } 
     return null; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

這裏是一個演示:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string valid = @" 
     { 
      ""key"": ""key"", 
      ""id"": ""id"", 
      ""status"": ""status"", 
      ""opts"": { 
       ""start"": 42, 
       ""limit"": 12 
      } 
     }"; 

     DeserializeAndWriteToConsole(valid); 

     string invalid = @" 
     { 
      ""key"": ""key"", 
      ""id"": ""id"", 
      ""status"": ""status"", 
      ""opts"": [] 
     }"; 

     DeserializeAndWriteToConsole(invalid); 
    } 

    private static void DeserializeAndWriteToConsole(string json) 
    { 
     RootObject root = JsonConvert.DeserializeObject<RootObject>(json, new OptsConverter()); 

     Console.WriteLine("key: " + root.key); 
     Console.WriteLine("id: " + root.id); 
     Console.WriteLine("status: " + root.status); 
     if (root.opts != null) 
     { 
      Console.WriteLine("opts.start: " + root.opts.start); 
      Console.WriteLine("opts.limit: " + root.opts.limit); 
     } 
     else 
     { 
      Console.WriteLine("opts: (null)"); 
     } 

     Console.WriteLine(); 
    } 
} 

public class RootObject 
{ 
    public string key { get; set; } 
    public string id { get; set; } 
    public string status { get; set; } 
    public Opts opts { get; set; } 
} 

public class Opts 
{ 
    public int start { get; set; } 
    public int limit { get; set; } 
} 

輸出:

key: key 
id: id 
status: status 
opts.start: 42 
opts.limit: 12 

key: key 
id: id 
status: status 
opts: (null) 
+0

哦,這只是一個普通的例子。其實我有50多個班。所以,我不能將這種方法用於每一個班級。無論如何,謝謝你的幫助。 – user876301

相關問題