反序列化引用循环不将数据带入构造函数
Deserialization reference cycle don't bring the data into constructor
我有以下情况 (Newtonsoft.Json):
public class SubElement
{
[JsonConstructor]
public SubElement(string name, Element parent)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException("message", nameof(name));
}
Name = name;
Parent = parent ?? throw new ArgumentNullException(nameof(parent));
}
public string Name { get;private set; }
public Element Parent { get; }
}
[JsonObject(IsReference =true)]
public class Element
{
[JsonConstructor]
public Element(string name, IList<SubElement> subelements)
{
Name = name;
Subelements = subelements;
}
public string Name { get; set; }
public IList<SubElement> Subelements { get; }
}
Element element = new Element("test", new List<SubElement>());
element.Subelements.Add(new SubElement("first", element));
element.Subelements.Add(new SubElement("second", element));
string serialized = JsonConvert.SerializeObject(element);
Console.WriteLine(serialized);
Element deserialized = JsonConvert.DeserializeObject<Element>(serialized);
在反序列化过程中,SubElement 构造函数被调用,父 Element 为空,尽管在序列化数据中它被正确存储.我使用 [JsonObject(IsReference =true)] 属性来管理循环引用,但它似乎不足以让反序列化工作。
您正在尝试 serialize/deserialize tree-like 结构,其中包含对 parent 的引用。
我认为问题在于当为 children 调用 [JsonConstructor]
时,尚未构建 parent。但是,如果您只是反序列化属性,这并不重要(在这种情况下我们将需要无参数构造函数):
[JsonObject(IsReference = true)]
public class Element
{
[JsonProperty] // required for private setter
public string Name { get; private set; }
[JsonProperty]
public IList<SubElement> Ports { get; private set; }
[JsonConstructor] // required for private constructor
Element() { }
... // your public constructors (not used for serialization)
}
public class SubElement
{
[JsonProperty]
public string Name { get; private set; }
[JsonProperty]
public Element Parent { get; private set; }
[JsonConstructor]
SubElement() { }
...
}
我试着保留你的架构。使用的参考文献:deserialize private setters, deserialize private constructor.
json看起来一样:
{"$id":"1","Name":"test","Ports":[{"Name":"first","Parent":{"$ref":"1"}},{"Name":"second","Parent":{"$ref":"1"}}]}
我有以下情况 (Newtonsoft.Json):
public class SubElement
{
[JsonConstructor]
public SubElement(string name, Element parent)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException("message", nameof(name));
}
Name = name;
Parent = parent ?? throw new ArgumentNullException(nameof(parent));
}
public string Name { get;private set; }
public Element Parent { get; }
}
[JsonObject(IsReference =true)]
public class Element
{
[JsonConstructor]
public Element(string name, IList<SubElement> subelements)
{
Name = name;
Subelements = subelements;
}
public string Name { get; set; }
public IList<SubElement> Subelements { get; }
}
Element element = new Element("test", new List<SubElement>());
element.Subelements.Add(new SubElement("first", element));
element.Subelements.Add(new SubElement("second", element));
string serialized = JsonConvert.SerializeObject(element);
Console.WriteLine(serialized);
Element deserialized = JsonConvert.DeserializeObject<Element>(serialized);
在反序列化过程中,SubElement 构造函数被调用,父 Element 为空,尽管在序列化数据中它被正确存储.我使用 [JsonObject(IsReference =true)] 属性来管理循环引用,但它似乎不足以让反序列化工作。
您正在尝试 serialize/deserialize tree-like 结构,其中包含对 parent 的引用。
我认为问题在于当为 children 调用 [JsonConstructor]
时,尚未构建 parent。但是,如果您只是反序列化属性,这并不重要(在这种情况下我们将需要无参数构造函数):
[JsonObject(IsReference = true)]
public class Element
{
[JsonProperty] // required for private setter
public string Name { get; private set; }
[JsonProperty]
public IList<SubElement> Ports { get; private set; }
[JsonConstructor] // required for private constructor
Element() { }
... // your public constructors (not used for serialization)
}
public class SubElement
{
[JsonProperty]
public string Name { get; private set; }
[JsonProperty]
public Element Parent { get; private set; }
[JsonConstructor]
SubElement() { }
...
}
我试着保留你的架构。使用的参考文献:deserialize private setters, deserialize private constructor.
json看起来一样:
{"$id":"1","Name":"test","Ports":[{"Name":"first","Parent":{"$ref":"1"}},{"Name":"second","Parent":{"$ref":"1"}}]}