问题描述
我有以下情况(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 为null无关,尽管在序列化数据中它已正确存储。我使用[JsonObject(IsReference = true)]属性来管理循环引用,但似乎反序列化还不够。
解决方法
您正在尝试序列化/反序列化树状结构,其中包含对父级的引用。
我认为问题在于,当为孩子调用[JsonConstructor]
时,尚未构造父对象。但是,只要您反序列化属性就没关系(在这种情况下,我们将需要无参数的构造函数):
[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”,“名称”:“ test”,“端口”:[{“名称”:“ first”,“父母”:{“ $ ref”:“ 1”}} ,{“名称”:“第二”,“父母”:{“ $ ref”:“ 1”}}]}