我获得了一个json数据流,其中包含一个名为“type”的字段。此类型字段描述了需要在运行时创建的对象类型。看起来我无法使用JsonTextReader两次,我找不到将文本阅读器重置为开头。
using (var streamReader = new StreamReader(stream, Encoding))
using (var jsonTextReader = new JsonTextReader(streamReader))
{
JToken token = JObject.Load(jsonTextReader);
var type = (string) token.SelectToken("type");
var modelType = Type.GetType("Project." + type + ", Project");
// Fails here
var obj = serializer.Deserialize(jsonTextReader, modelType);
}
我收到此错误消息。
反序列化对象时出现意外的令牌:EndObject。
您可以从JToken创建JsonReader。
JsonReader reader = token.CreateReader();
您可以从JToken创建JsonReader。
JsonReader reader = token.CreateReader();
要将阅读器重置为开始,请将基础流的Position属性设置为0。
streamReader.BaseStream.Position = 0;
编辑:
虽然这将重置您的基础流,但jsonTextReader是 只进 根据定义,这意味着它的行号和位置是只读的。为此,您必须重置streamReader位置,然后将其输入到 新 JsonTextReader对象。
所以不幸的是Phil,没有办法两次读取JsonTextReader,因为它只是前向的。
参考:
http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonTextReader.htm
“代表一个读者,它提供对序列化Json数据的快速,非缓存,仅向前访问。”
我做了一些测试,发现以下工作。
- 组
JsonTextReader.CloseInput = false
- 摧毁
JsonTextReader
(通过关闭 using
声明)
- 组
StreamReader.BaseStream.Position = 0
- 创建一个新的
JsonTextReader
它看起来像这样:
using (var streamReader = new StreamReader(stream, encoding))
{
Type modelType = null;
using (var jsonTextReader = new JsonTextReader(streamReader))
{
jsonTextReader.CloseInput = false;
JToken token = JObject.Load(jsonTextReader);
string type = (string)token.SelectToken("type");
modelType = Type.GetType("Project." + type + ", Project");
}
streamReader.BaseStream.Position = 0;
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var obj = serializer.Deserialize(jsonTextReader, modelType);
}
}
我用封面来掩盖 JsonTextReader
以内存有效的格式,避免大对象堆等, 在我的博客中,根据James Newton King的建议。您可以利用此代码和提供的代码多次读取JSON,而无需担心底层实现 JsonTextReader
。
欢迎提出意见和反馈。