在JSON.NET中处理错误的合同类型

时间:2014-04-29 20:59:22

标签: json.net

当合约类型不匹配时,是否可以跳过json的一部分。也就是说,我收到一个不符合模式的json响应 - null对象被序列化为空数组(“谢谢”到php序列化程序)。所以,而不是“null”或“{}”,我得到“[]”。

到目前为止,我尝试使用JsonSerializerSettings中提供的Error事件处理程序。但是,这种方法相当丑陋,因为Json.net不会返回有意义的异常类型。

有效回复示例:

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

无效回复示例

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

1 个答案:

答案 0 :(得分:1)

您可以使用自定义JsonConverter来处理此问题。转换器可以检测JSON中opts属性的格式,然后对其进行反序列化或在目标对象中将其值设置为null。以下是我将如何编写转换器:

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)