2014-04-29 30 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

相关问题