我得到了一个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();
若要将读取器重置为初始,请将基础流的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数据的快速、非缓存、仅前向访问的读取器。"
根据James Newton King的建议,我在博客中介绍了以节省内存的格式使用JsonTextReader
,避免使用大型对象堆等。您可以利用它和提供的代码多次读取JSON,而无需担心JsonTextReader
的底层实现。
欢迎评论和反馈。
我做了更多的测试,发现以下内容有效。
- 设置
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);
}
}