我获得了一个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。
答案 0 :(得分:14)
您可以从JToken创建一个JsonReader。
JsonReader reader = token.CreateReader();
答案 1 :(得分:2)
要将阅读器重置为开始,请将基础流的Position属性设置为0。
streamReader.BaseStream.Position = 0;
编辑: 虽然这将重置您的基础流,但jsonTextReader根据定义是仅向前,这意味着它的行号和位置是只读的。为此,您必须重置streamReader位置,然后将其提供给 new JsonTextReader对象。
所以不幸的是Phil,因为它只是前向的,所以无法读取JsonTextReader两次。
参考: http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_JsonTextReader.htm “代表一个读者,它提供对序列化Json数据的快速,非缓存,仅向前访问。”
答案 2 :(得分:1)
根据James Newton King的建议,我以内存效率格式使用JsonTextReader
,避免使用大对象堆等in my blog。您可以利用此代码和提供的代码多次读取JSON,而无需担心JsonTextReader
的底层实现。
欢迎提出意见和反馈。
答案 3 :(得分:0)
我做了一些测试,发现以下工作。
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);
}
}