简体   繁体   English

JSON反序列化字符串值到列表 <T> 使用Newtonsoft-构造函数arg在C#中为null

[英]JSON Deserializing string value to List<T> using Newtonsoft - constructor arg is null in C#

I am using Newtonsoft libraries for serialization and deserialization json object. 我正在使用Newtonsoft库进行序列化和反序列化json对象。 The reference code is below: 参考代码如下:

 public abstract class BaseNode
{
    [JsonConstructor]
    protected BaseNode(string [] specifications)
    {
        if (specifications == null)
        {
            throw new ArgumentNullException();
        }
        if (specifications.Length == 0)
        {
            throw new ArgumentException();
        }

        Name = specifications[0];
        Identifier = specifications[1];
        //Owner = specifications[2];
    }

    public string Name{ get; protected set; }
    public string Identifier { get; protected set; }
    public string Owner { get; protected set; }
}


public class ComputerNode: BaseNode
{
    [JsonConstructor]
    public ComputerNode(string[] specifications):base(specifications)
    {
        Owner = specifications[2];
    }
}

Serialization works fine and I can save the json formatted data in a file. 序列化工作正常,我可以将json格式的数据保存在文件中。 I am storing a list of ComputerNode objects in a file. 我将一个ComputerNode对象列表存储在一个文件中。 Following code for file read/write operation: 以下代码用于文件读/写操作:

public class Operation<T>
{
    public string path;

    public Operation()
    {
        var path = Path.Combine(Directory.GetCurrentDirectory(), "nodes.txt");

        if (File.Exists(path) == false)
        {
            using (File.Create(path))
            {
            }
        }
        this.path = path;
    }

    public void Write(string path, List<T> nodes)
    {
        var ser = JsonConvert.SerializeObject(nodes);

        File.WriteAllText(path, ser);
    }

    public List<T> Read(string path)
    {
        var text = File.ReadAllText(path);

        var res =  JsonConvert.DeserializeObject<List<T>>(text);
        return res;
    }

}

The expected file Read result should be a list of ComputerNode objects stored in a file. 预期的文件读取结果应该是文件中存储的ComputerNode对象的列表。 However, while deserialization - creating an object of ComputerNode, correct constructor is called but the argument (string[] specifications) is null. 但是,在反序列化-创建ComputerNode对象时,将调用正确的构造函数,但参数(string []规范)为null。

Is there any better way to work with it. 有没有更好的方法来使用它。

Please do not suggest to change BaseNode.cs or ComputerNode.cs 请不要建议更改BaseNode.cs或ComputerNode.cs

Thanks for suggestion... 感谢您的建议...

Correct Answer 正确答案

Overridden with new Json constructor. 被新的Json构造函数覆盖。 In BaseNode.cs 在BaseNode.cs中

    [JsonConstructor]
    public BaseNode(string Owner, string Name, string Identifier)
    {
        this.Name = Name;
        this.Identifier = Identifier;
    }

and Overridden a Json constructor - ComputerNode.cs 和重写Json构造函数-ComputerNode.cs

    [JsonConstructor]
    public ComputerNode(string Owner, string Name, string Identifier):base(Owner, Name, Identifier)
    {
        this.Owner = Owner;
    }

https://stackoverflow.com/a/23017892/34092 states: https://stackoverflow.com/a/23017892/34092指出:

It is important that the constructor parameter names match the corresponding property names of the JSON object for this to work correctly. 重要的是,构造函数参数名称必须与JSON对象的相应属性名称匹配才能正常工作。

Your constructor parameter is called specifications . 您的构造函数参数称为specifications There is no property in the JSON with the name of specifications . JSON中没有带有specifications名称的属性。 This is why the value is passed as null. 这就是为什么将值传递为null的原因。

See also http://www.newtonsoft.com/json/help/html/JsonConstructorAttribute.htm . 另请参见http://www.newtonsoft.com/json/help/html/JsonConstructorAttribute.htm

in practice if you run 在实践中,如果您跑步

var ser = JsonConvert.SerializeObject(nodes);
File.WriteAllText(path, ser);

where nodes is a List<T> 其中节点是List <T>

then 然后

var text = File.ReadAllText(path);
var res =  JsonConvert.DeserializeObject<List<T>>(text);

where res is a List<T> 其中res是List <T>

According to the JsonConstructor documentation: http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonConstructorAttribute.htm 根据JsonConstructor文档: http : //www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonConstructorAttribute.htm

Instructs the JsonSerializer to use the specified constructor when deserializing that object. 指示JsonSerializer在反序列化该对象时使用指定的构造函数。

No where it is said that there will be a constructor parameter related with the string to be deserialized. 没有地方会说有一个与要反序列化的字符串相关的构造函数参数。

in fact the constructor you designate ( [JsonConstructor] ) try to override the result of the deserialization with an always null parameter 实际上,您指定的构造函数( [JsonConstructor] )尝试使用始终为null的参数覆盖反序列化的结果

In your case you should have 在你的情况下,你应该

[JsonConstructor]
protected BaseNode()
{

}

to avoid the constructor over interacting with the deserialization. 避免构造函数与反序列化交互。

IMHO, the deserializer will never (according to documentation) give a parameter to a constructor. 恕我直言,反序列化器永远不会(根据文档)将参数提供给构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM