- 此问题在此处已有答案**:
Why my dull Newtonsoft.Json deserialization code does not work? [duplicate](1个答案)
13小时前关门了。
我试图序列化一棵树,但我只需要对象数据的一小部分(它是一棵UI树),所以我编写了一个自定义转换器。
转换器只是将读取器和写入器传递给对象
public override void WriteJson(JsonWriter writer, NavTree value, JsonSerializer serializer)
{
value.SaveAsJson(writer);
}
public override NavTree ReadJson(JsonReader reader, Type objectType, NavTree existingValue, bool hasExistingValue,
JsonSerializer serializer)
{
NavTree tree = hasExistingValue ? existingValue : new NavTree();
tree.LoadFromJson(reader);
return tree;
}
序列化如下所示
public void SaveAsJson(JsonWriter writer)
{
SerializableTreeItem root = new (this.GetRoot());
JObject.FromObject(root).WriteTo(writer);
}
该对象似乎序列化产生的json,类似于
"NavTree": {
"Id": "All",
"IsCategory": true,
"Children": [
{
"Id": "https://popularresistance.org/feed/",
"IsCategory": false,
"Children": []
},
{
"Id": "https://www.aljazeera.com/xml/rss/all.xml",
"IsCategory": false,
"Children": []
},
... more children
反序列化如下所示:
public void LoadFromJson(JsonReader reader)
{
SerializableTreeItem loaded =
JsonConvert.DeserializeObject<SerializableTreeItem>((string)reader.Value ?? string.Empty);
if (loaded == null) return;
if (this.GetRoot() != null)
{
this.GetRoot().Free();
TreeItem root = this.CreateItem();
root.SetMetadata(0, RootMetaDataId);
}
this.AddItem(loaded, this.GetRoot());
}
尝试访问reader。函数开头的值返回null。尝试访问开头的reader. ReadAsString()将导致:
Newtonsoft.Json.JsonReaderException: Unexpected state: ObjectStart. Path 'NavTree', line 669, position 14.
at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType)
at Newtonsoft.Json.JsonTextReader.ReadAsString()
at Porifera.NavTree.LoadFromJson(JsonReader reader)
第669行是上面发布的json的第一行。我以前从来没有做过一个定制的转换器,很明显我把它搞砸了。问题是我做错了什么?json在我看来还不错,我真正需要的是读者提供 * 一些东西 *,我可以重建对象。
1条答案
按热度按时间e5nqia271#
您正在将
SerializableTreeItem
用作NavTree
的data transfer object:在编程领域,数据传输对象**(DTO)**是在进程之间传送数据的对象。
您应该做的是重构代码,以分离从JSON转换到DTO以及从DTO转换到
NavTree
的职责。首先,修改
NavTree
以删除对JsonReader
或任何其他JSON类型的所有引用:现在,将
JsonConverter<NavTree>
重写如下:你应该可以走了。
注:
1.您的
JsonReaderException
是由以下行引起的:JsonReader.Value
是当前JSON标记的值,但您使用它时就好像它包含了与SerializableTreeItem
对应的整个JSON子树一样,而是使用JsonSerializer.Deserialize<T>(JsonReader)
来反序列化当前JSON标记锚定的JSON子树。1.写的时候,不需要先把你的
SerializableTreeItem
序列化为一个JObject
,然后再写JObject
,直接序列化SerializableTreeItem
,跳过中间的JObject
表示就行了。1.通过将JSON序列化与DTO转换分离,您将能够更容易地将序列化代码移植到System.Text.Json或任何其他序列化程序(如果您最终选择这样做的话)。