代码之家  ›  专栏  ›  技术社区  ›  PaperBirdMaster

我可以反序列化一个json文本直到出现错误或者以newtonsoft解析器结束吗?[副本]

  •  6
  • PaperBirdMaster  · 技术社区  · 6 年前

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

    [ { "key" : "value1" }, { "key " : "value2"}, { "key 
    

    请告诉我是否有方法使用newtonsoft.json库,或者我需要一些预处理。

    谢谢您!

    0 回复  |  直到 8 年前
        1
  •  2
  •   Toxantron    8 年前

    您可以使用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;
    }
    

    代码取自 CGbR JSON Target 是的。

        2
  •  6
  •   dbc    8 年前

    在json.net 8.0.3上,您可以从 JsonTextReader 给一个 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);
    }
    

    这将导致:

    [
      {
        "key": "value1"
      },
      {
        "key ": "value2"
      },
      {}
    ]
    

    然后可以使用 JToken.ToObject 是的。您还可以使用 badToken.Remove() 是的。

    不过,最好不要首先生成无效的json。我也不完全确定这是json.net的文档功能,因此它可能不适用于json.net的未来版本。(例如,可以想象,newtonsoft可以改变他们的算法 JTokenWriter.Token 仅在写入成功时设置。)