如何反序列化无效的json?截断的对象列表

use*_*518 5 json json.net

我的json文件主要是一个包含对象的数组,但是列表不完整,所以我不能使用最后一个条目。我想反序列化文件的其余部分,同时丢弃最后一个无效的条目

[ { "key" : "value1" }, { "key " : "value2"}, { "key 
Run Code Online (Sandbox Code Playgroud)

请告诉我是否可以使用Newtonsoft.Json库,还是需要一些预处理。

谢谢!

dbc*_*dbc 6

看起来像在Json.NET 8.0.3上,您可以将字符串从a JsonTextReader传输到a JTokenWriter并通过捕获并吞下JsonReaderException在分析截断的JSON时抛出的结果来获得部分结果:

JToken root;
string exceptionPath = null;
using (var textReader = new StringReader(badJson))
using (var jsonReader = new JsonTextReader(textReader))
using (JTokenWriter jsonWriter = new JTokenWriter())
{
    try
    {
        jsonWriter.WriteToken(jsonReader);
    }
    catch (JsonReaderException ex)
    {
        exceptionPath = ex.Path;
        Debug.WriteLine(ex);
    }
    root = jsonWriter.Token;
}

Console.WriteLine(root);
if (exceptionPath != null)
{
    Console.WriteLine("Error occurred with token: ");
    var badToken = root.SelectToken(exceptionPath);
    Console.WriteLine(badToken);
}
Run Code Online (Sandbox Code Playgroud)

结果是:

[
  {
    "key": "value1"
  },
  {
    "key ": "value2"
  },
  {}
]
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用完成反序列化部分对象JToken.ToObject。您也可以使用删除不完整的数组条目badToken.Remove()

最好不要首先生成无效的JSON。我也不完全确定这是Json.NET的文档功能,因此它可能不适用于将来的Json.NET版本。(例如,可以想象的是,Newtonsoft可以更改其算法,使其JTokenWriter.Token仅在写入成功时才设置。)

  • 惊人!仍可在Json.NET 11.0.2中使用! (2认同)

Tox*_*ron 2

您可以使用 JsonReader 类并尝试尽可能解析。像下面的代码这样的东西将解析尽可能多的属性,然后抛出异常。当然,如果您想反序列化为具体的类,则可以这样做。

public Partial FromJson(JsonReader reader)
{
    while (reader.Read())
    {
        // Break on EndObject
        if (reader.TokenType == JsonToken.EndObject)
            break;

        // Only look for properties
        if (reader.TokenType != JsonToken.PropertyName)
            continue;

        switch ((string) reader.Value)
        {
            case "Id":
                reader.Read();
                Id = Convert.ToInt16(reader.Value);
                break;

            case "Name":
                reader.Read();
                Name = Convert.ToString(reader.Value);
                break;

        }
    }

    return this;
}
Run Code Online (Sandbox Code Playgroud)

代码取自CGbR JSON Target