問(wèn)題描述
我有一個(gè) JSON 對(duì)象流,看起來(lái)有點(diǎn)像這樣:
{...}{...}{...}{...}...
所以基本上是一個(gè)沒(méi)有任何分隔符的 JSON 對(duì)象的串聯(lián)列表.使用 JSON.NET 將它們反序列化為 IEnumerable<T>
的正確方法是什么?目前我嘗試了類(lèi)似
var serializer = new JsonSerializer();序列化程序.CheckAdditionalContent = false;使用 (var reader = new StreamReader(stream))使用 (var jsonReader = new JsonTextReader(reader)) {reader.SupportMultipleContent = true;閱讀器.Read();而(reader.TokenType!= JsonToken.None){yield return serializer.Deserialize(reader);}}
但這失敗了
Newtonsoft.Json.JsonSerializationException:反序列化對(duì)象時(shí)出現(xiàn)意外令牌:EndObject.路徑 '',第 1 行,位置 55.在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader 閱讀器,類(lèi)型 objectType,JsonContract 合同,JsonProperty 成員,JsonContainerContract containerContract,JsonProperty containerMember,對(duì)象現(xiàn)有值)在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader 閱讀器,類(lèi)型 objectType,布爾 checkAdditionalContent)在 Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader 閱讀器,類(lèi)型 objectType)在 Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader 閱讀器)
顯然我需要在 Deserialize
調(diào)用之后移動(dòng)閱讀器,但我該怎么做呢?
我認(rèn)為如果你稍微改變你的循環(huán),一切都應(yīng)該工作:
public IEnumerableReadJson(流流){var serializer = new JsonSerializer();使用 (var reader = new StreamReader(stream))使用 (var jsonReader = new JsonTextReader(reader)){jsonReader.SupportMultipleContent = true;而(jsonReader.Read()){yield return serializer.Deserialize<TResult>(jsonReader);}}}
請(qǐng)注意,當(dāng)傳遞給此方法的 Stream
處于打開(kāi)狀態(tài)時(shí),您必須遍歷 IEnumerable
:
using (var stream =/* some stream */){IEnumerable<MyClass>結(jié)果 = ReadJson<MyClass>(流);foreach(結(jié)果中的變量項(xiàng)){Console.WriteLine(item.MyProperty);}}
示例: https://dotnetfiddle.net/Y2FLuK
JsonNet 站點(diǎn)上的示例:使用 JsonReader 讀取多個(gè)片段p>
I have a stream of JSON objects that looks somewhat like this:
{...}{...}{...}{...}...
So basically a concatenated list of JSON objects without any separator.
What's the proper way to deserialize those into an IEnumerable<T>
using JSON.NET? At the moment I tried something like
var serializer = new JsonSerializer();
serializer.CheckAdditionalContent = false;
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader)) {
reader.SupportMultipleContent = true;
reader.Read();
while (reader.TokenType != JsonToken.None) {
yield return serializer.Deserialize<TResult>(reader);
}
}
But this fails with
Newtonsoft.Json.JsonSerializationException: Unexpected token while deserializing object: EndObject. Path '', line 1, position 55.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
Obviously I need to move the reader after the Deserialize
call, but how do I do this?
I think if you change your loop around slightly everything should work:
public IEnumerable<TResult> ReadJson<TResult>(Stream stream)
{
var serializer = new JsonSerializer();
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
jsonReader.SupportMultipleContent = true;
while (jsonReader.Read())
{
yield return serializer.Deserialize<TResult>(jsonReader);
}
}
}
Note that you must iterate over the IEnumerable<TResult>
while the Stream
passed to this method is open:
using (var stream = /* some stream */)
{
IEnumerable<MyClass> result = ReadJson<MyClass>(stream);
foreach (var item in result)
{
Console.WriteLine(item.MyProperty);
}
}
Example: https://dotnetfiddle.net/Y2FLuK
Sample on JsonNet site: Read Multiple Fragments With JsonReader
這篇關(guān)于使用 JSON.NET 解析 JSON 對(duì)象流的正確方法是什么?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!