【问题标题】:Deserialize multiple json objects from a stream using Newtonsoft Json使用 Newtonsoft Json 从流中反序列化多个 json 对象
【发布时间】:2018-07-30 15:52:18
【问题描述】:

我正在为json 字符串读取NetworkStream,然后使用Newtonsoft.Json 反序列化它。

有时,两个json 对象可以背靠背发送并在流上同时读取。但是Newtonsoft.Jsonserializer 只给了我一个对象。

例如,如果我在流中有以下字符串:

{"name":"John Doe","age":10}{"name":"Jane Doe","age":10}

如果我反序列化流,serializer 会读取整个流,但只给出第一个对象。

有没有办法让serializer 只读取流中的第一个对象,然后在循环的下一次迭代中读取下一个对象?

代码:

public static Person Deserialize(Stream stream)
{
    var Serializer = new JsonSerializer();
    var streamReader = new StreamReader(stream, new UTF8Encoding());
    return Serializer.Deserialize<Person>(new JsonTextReader(streamReader));
}

我无法反序列化为列表,因为我没有收到 json 数组。

【问题讨论】:

  • 能否包含您现在用于反序列化的代码?
  • 我找到了关于这个主题的一个相当不错的维基百科页面:en.wikipedia.org/wiki/JSON_streaming,很笼统但仍然如此。
  • @Evk 我已经更新了我的问题。
  • @PeterB 好文章,谢谢!从文章来看,我正在处理的jsonconcatenated json。这是一个好的开始。现在我需要在Json.net 中做到这一点
  • 这里有一个可能的答案:stackoverflow.com/questions/43747477/…。它通过跳到下一个{ 并从那里解析一个对象来工作,

标签: c# .net json json.net json-deserialization


【解决方案1】:

我认为你可以这样做:

public static IList<Person> Deserialize(Stream stream) {
    var serializer = new JsonSerializer();
    var streamReader = new StreamReader(stream, new UTF8Encoding());
    var result = new List<Person>();
    using (var reader = new JsonTextReader(streamReader)) {
        reader.CloseInput = false;
        // important part
        reader.SupportMultipleContent = true;
        while (reader.Read()) {
            result.Add(serializer.Deserialize<Person>(reader));
        }
    }
    return result;
}

重要的部分是SupportMultipleContent属性,它通知读者可能有多个json对象并排。

【讨论】:

    【解决方案2】:

    你可以这样试试

            var httpRequest = HttpContext.Current.Request;
            // This list will have all the stream objects
            var persons = new List<Person>();
            if (httpRequest.Files.Count > 0)
            {
                for (var obj = 0; doc < httpRequest.Files.Count; obj++)
                {
                    var postedFile = httpRequest.Files[obj];
                    var bytes = new byte[postedFile.ContentLength];
                    postedFile.InputStream.Read(bytes, 0, postedFile.ContentLength);
                    persons.Add(Serializer.Deserialize<Person>(new JsonTextReader(new StreamReader(new MemoryStream(bytes)))));
                }
            }
    

    【讨论】:

    • 您的解决方案肯定会奏效,但在许多用例中效率低下。它要求在处理开始之前完全检索内容。如果您的实体很大,它还可能需要大量的 RAM。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    相关资源
    最近更新 更多