如何处理JSON.NET解析中的错误



我正在使用json.net进行json避难所化。有时我读的JSON字符串不正确(由于我不产生它,因此无法修复)。特别是在一个特定的地方,应该有一个字符串,有时会有一个序列化对象。然后,JSON.NET抱怨要找到一个对象期望字符串的对象。

我发现我可以通过在JsonSerializerSettings中使用Error拦截这一点,还可以通过设置ErrorContext.Handled忽略JSON.NET忽略问题。但是我想做更多的事情。如果我可以查看序列化对象,我可以弄清楚字符串应该是什么,从理论上讲,请提供正确的答案。在实践中,我无法弄清楚我们该怎么做。特别是在错误处理程序中:

  • 如何访问解析器绊倒的字符串(请注意,如果设置了ErrorContext.Handled,解析器可以成功继续,以便可以正确确定问题字符串的启动和结束)?
  • )?
  • 如何向解析器提供正确的字符串,或者可以访问当前解析的对象,以便我可以手动设置值?

[编辑]按照要求的简化示例:

我要解析的错误JSON字符串:

{
    "id": 2623,
    "name": {
        "a": 39,
        "b": 0.49053320637463277,
        "c": "cai5z+A=",
        "name": "22"
    },
    "children": [
        {
            "id": 3742,
            "name": {
                "a": 37,
                "b": 0.19319664789046936,
                "c": "Me/KKPY=",
                "name": "50"
            },
            "children": [
                {
                    "id": 1551,
                    "name": {
                        "a": 47,
                        "b": 0.6935373953047849,
                        "c": "qkGkMwY=",
                        "name": "9"
                    },
                    "children": []
                },
                {
                    "id": 4087,
                    "name": {
                        "a": 5,
                        "b": 0.42905938319352427,
                        "c": "VQ+yH6o=",
                        "name": "84"
                    },
                    "children": []
                },
                {
                    "id": 614,
                    "name": {
                        "a": 19,
                        "b": 0.7610801005554758,
                        "c": "czjTK1s=",
                        "name": "11"
                    },
                    "children": []
                }
            ]
        },
        {
            "id": 3382,
            "name": {
                "a": 9,
                "b": 0.36416331043660793,
                "c": "lnoHrd0=",
                "name": "59"
            },
            "children": [
                {
                    "id": 4354,
                    "name": {
                        "a": 17,
                        "b": 0.8741648112769075,
                        "c": "CD2i2I0=",
                        "name": "24"
                    },
                    "children": []
                },
                {
                    "id": 2533,
                    "name": {
                        "a": 52,
                        "b": 0.8839575992356788,
                        "c": "BxFEzVI=",
                        "name": "60"
                    },
                    "children": []
                },
                {
                    "id": 5733,
                    "name": {
                        "a": 4,
                        "b": 0.7230552787534219,
                        "c": "Un7lJGM=",
                        "name": "30"
                    },
                    "children": []
                }
            ]
        },
        {
            "id": 9614,
            "name": {
                "a": 81,
                "b": 0.4015882813379114,
                "c": "dKgyRZk=",
                "name": "63"
            },
            "children": [
                {
                    "id": 7831,
                    "name": {
                        "a": 81,
                        "b": 0.2784254314743101,
                        "c": "xZur64o=",
                        "name": "94"
                    },
                    "children": []
                },
                {
                    "id": 6293,
                    "name": {
                        "a": 73,
                        "b": 0.32629523068959604,
                        "c": "lMkosP4=",
                        "name": "93"
                    },
                    "children": []
                },
                {
                    "id": 5253,
                    "name": {
                        "a": 13,
                        "b": 0.19240453242901923,
                        "c": "oOPZ3tA=",
                        "name": "5"
                    },
                    "children": []
                }
            ]
        }
    ]
}

在这里上课,将其解析为:

class Node
{
     [JsonProperty]
    int id;
     [JsonProperty]
    string name;
     [JsonProperty]
    List<Node> children;
}

您可以看到它的期望是字符串name,但有时会错误地获取一个序列化对象(其中包含所讨论的字符串作为成员)。这仅发生在某些JSON字符串中,而不会发生在其他字符串中,因此我不能仅更改匹配节点的类定义。

[编辑2]根据我的API,"正确"的JSON字符串看起来像这样:

{
    "id": 2623,
    "name": "22",
    "children": [
        {
            "id": 3742,
            "name": "50",
            "children": [
                {
                    "id": 1551,
                    "name": "9",
                    "children": []
                },
                {
                    "id": 4087,
                    "name":"84",
                    "children": []
                },
                ...

试图在事实后检测错误,然后从错误点上恢复出现,如您所见。幸运的是,您所描述的问题可以使用自定义JsonConverter以直接的方式解决。这个想法是让转换器将数据读取为临时结构,该结构可以处理形式(对象或字符串),查询类型,然后从那里构造Node

这是转换器的代码:

class NodeConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Node));
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        Node node = new Node();
        node.id = (int)jo["id"];
        JToken name = jo["name"];
        if (name.Type == JTokenType.String)
        {
            // The name is a string at the current level
            node.name = (string)name;
        }
        else
        {
            // The name is one level down inside an object
            node.name = (string)name["name"];
        }
        node.children = jo["children"].ToObject<List<Node>>(serializer);
        return node;
    }
    public override bool CanWrite
    {
        get { return false; }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用转换器,请在您的Node类中添加[JsonConverter]属性:

[JsonConverter(typeof(NodeConverter))]
class Node
{
    public int id { get; set; }
    public string name { get; set; }
    public List<Node> children { get; set; }
}

然后您可以按正常方式进行审理:

Node node = JsonConvert.DeserializeObject<Node>(json);

这是一个完整的演示,显示了动作中的转换器。出于插图目的,我创建了一个新的JSON字符串,其中包含您在问题中描述的"好"one_answers"坏"节点的组合。

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""id"": 2623,
            ""name"": {
                ""a"": 39,
                ""b"": 0.49053320637463277,
                ""c"": ""cai5z+A="",
                ""name"": ""22""
            },
            ""children"": [
                {
                    ""id"": 3741,
                    ""name"": ""50"",
                    ""children"": [
                        {
                            ""id"": 1550,
                            ""name"": ""9"",
                            ""children"": []
                        },
                        {
                            ""id"": 4088,
                            ""name"": {
                                ""a"": 5,
                                ""b"": 0.42905938319352427,
                                ""c"": ""VQ+yH6o="",
                                ""name"": ""85""
                            },
                            ""children"": []
                        }
                    ]
                },
                {
                    ""id"": 3742,
                    ""name"": {
                        ""a"": 37,
                        ""b"": 0.19319664789046936,
                        ""c"": ""Me/KKPY="",
                        ""name"": ""51""
                    },
                    ""children"": [
                        {
                            ""id"": 1551,
                            ""name"": {
                                ""a"": 47,
                                ""b"": 0.6935373953047849,
                                ""c"": ""qkGkMwY="",
                                ""name"": ""10""
                            },
                            ""children"": []
                        },
                        {
                            ""id"": 4087,
                            ""name"": ""84"",
                            ""children"": []
                        }
                    ]
                }
            ]
        }";
        Node node = JsonConvert.DeserializeObject<Node>(json);
        DumpNode(node, "");
    }
    private static void DumpNode(Node node, string indent)
    {
        Console.WriteLine(indent + "id = " + node.id + ", name = " + node.name);
        foreach(Node child in node.children)
        {
            DumpNode(child, indent + "    ");
        }
    }
}

输出:

id = 2623, name = 22
    id = 3741, name = 50
        id = 1550, name = 9
        id = 4088, name = 85
    id = 3742, name = 51
        id = 1551, name = 10
        id = 4087, name = 84

相关内容

  • 没有找到相关文章

最新更新