c# - 反序列化引用循环不将数据带入构造函数

标签 c# json serialization json-deserialization

我有以下场景(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)] 属性来管理循环引用,但似乎这不足以使反序列化工作。

最佳答案

您正在尝试序列化/反序列化包含对父级的引用的树状结构。

我认为问题在于,当为子级调用 [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","Name":"test","Ports":[{"Name":"first","Parent":{"$ref":"1"}},{"Name":"second","Parent":{"$ref":"1"}}]}

关于c# - 反序列化引用循环不将数据带入构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63523019/

相关文章:

javascript - 序列化 JavaScript 对象

c# - 设计一组使用依赖关系的规则

c# - 如何获取远程机器上的任务历史记录?

c# - 如何在 .net 2.0 中使用 HTTP POST 使用 RESTFul web 服务

ios - 如何在键是动态的 Swift 4 中为 JSON 编写 Decodable?

json - Clojure 名称绑定(bind)到 REST JSON 数据

c# - 通过 asm DLL 中的 ref 指针取消引用 C#

javascript - 动态显示json对象

javascript - 将表单序列化为不带空值的 json

c# - 找不到程序集