[英]JSON Deserializing string value to List<T> using Newtonsoft - constructor arg is null in C#
我正在使用Newtonsoft库进行序列化和反序列化json对象。 参考代码如下:
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];
}
}
序列化工作正常,我可以将json格式的数据保存在文件中。 我将一个ComputerNode对象列表存储在一个文件中。 以下代码用于文件读/写操作:
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;
}
}
预期的文件读取结果应该是文件中存储的ComputerNode对象的列表。 但是,在反序列化-创建ComputerNode对象时,将调用正确的构造函数,但参数(string []规范)为null。
有没有更好的方法来使用它。
请不要建议更改BaseNode.cs或ComputerNode.cs
感谢您的建议...
正确答案
被新的Json构造函数覆盖。 在BaseNode.cs中
[JsonConstructor]
public BaseNode(string Owner, string Name, string Identifier)
{
this.Name = Name;
this.Identifier = Identifier;
}
和重写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指出:
重要的是,构造函数参数名称必须与JSON对象的相应属性名称匹配才能正常工作。
您的构造函数参数称为specifications
。 JSON中没有带有specifications
名称的属性。 这就是为什么将值传递为null的原因。
另请参见http://www.newtonsoft.com/json/help/html/JsonConstructorAttribute.htm 。
在实践中,如果您跑步
var ser = JsonConvert.SerializeObject(nodes);
File.WriteAllText(path, ser);
其中节点是List <T>
然后
var text = File.ReadAllText(path);
var res = JsonConvert.DeserializeObject<List<T>>(text);
其中res是List <T>
根据JsonConstructor
文档: http : //www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonConstructorAttribute.htm
指示JsonSerializer在反序列化该对象时使用指定的构造函数。
没有地方会说有一个与要反序列化的字符串相关的构造函数参数。
实际上,您指定的构造函数( [JsonConstructor]
)尝试使用始终为null的参数覆盖反序列化的结果
在你的情况下,你应该
[JsonConstructor]
protected BaseNode()
{
}
避免构造函数与反序列化交互。
恕我直言,反序列化器永远不会(根据文档)将参数提供给构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.