反序列化参考周期不会将数据带入构造函数

问题描述

我有以下情况(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 settersdeserialize private constructor

json看起来一样:

{“ $ id”:“ 1”,“名称”:“ test”,“端口”:[{“名称”:“ first”,“父母”:{“ $ ref”:“ 1”}} ,{“名称”:“第二”,“父母”:{“ $ ref”:“ 1”}}]}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...