我需要将json反序列化为以下类。
public class Test
{
public string Property { get; set; }
private Test()
{
//NOTHING TO INITIALIZE
}
public Test(string prop)
{
Property = prop;
}
}
我可以像
那样创建一个Test实例var instance = new Test("Instance");
考虑我的json类似
"{ "Property":"Instance" }"
我如何创建Test类的对象,因为我的默认构造函数是私有的,我得到的对象属性为NULL
我正在使用Newtonsoft Json解析器。
答案 0 :(得分:32)
您可以通过使用[JsonConstructor]
属性标记Json.Net来调用私有构造函数:
[JsonConstructor]
private Test()
{
//NOTHING TO INITIALIZE
}
请注意,在调用构造函数后,序列化程序仍将使用公共setter来填充对象。
修改强>
另一种可能的选择是使用ConstructorHandling
设置:
JsonSerializerSettings settings = new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
Test t = JsonConvert.DeserializeObject<Test>(json, settings);
答案 1 :(得分:2)
您似乎不需要采取任何额外步骤。
使用Json.NET v6.0.8,以下C#程序在LINQPad中运行:
void Main()
{
var o = JsonConvert.DeserializeObject<Test>("{\"Property\":\"Instance\"}");
Debug.Assert(o.Property == "Instance",
"Property value not set when deserializing.");
}
public class Test
{
public string Property { get; set; }
private Test()
{
}
public Test(string propertyValue)
{
Property = propertyValue;
}
}
答案 2 :(得分:1)
无需创建Serializer设置并在此处指定ConstructorHandling。请记住为私有构造函数定义[JsonConstructor]
属性。
我有类似的抽象BaseNode.cs案例及其具体的ComputerNode.cs实现。您可以创建类,复制/粘贴下面的代码并进行一些实验。
public abstract class BaseNode
{
[JsonConstructor] // ctor used when Json Deserializing
protected BaseNode(string Owner, string Name, string Identifier)
{
this.Name = Name;
this.Identifier = Identifier;
}
// ctor called by concrete class.
protected BaseNode(string [] specifications)
{
if (specifications == null)
{
throw new ArgumentNullException();
}
if (specifications.Length == 0)
{
throw new ArgumentException();
}
Name = specifications[0];
Identifier = specifications[1];
}
public string Name{ get; protected set; }
public string Identifier { get; protected set; }
}
public class ComputerNode: BaseNode
{
public string Owner { get; private set; }
[JsonConstructor] // not visible while creating object from outside and only used during Json Deserialization.
private ComputerNode(string Owner, string Name, string Identifier):base(Owner, Name, Identifier)
{
this.Owner = Owner;
}
public ComputerNode(string[] specifications):base(specifications)
{
Owner = specifications[2];
}
}
对于JSon读写以下代码有帮助 -
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, Formatting.Indented);
File.WriteAllText(path, ser);
}
public List<T> Read(string path)
{
var text = File.ReadAllText(path);
var res = JsonConvert.DeserializeObject<List<T>>(text);
return res;
}
}
一切顺利!
答案 3 :(得分:0)
不幸的是,根据this和this,这不是新的System.Text.Json.JsonSerializer(Newtonsoft.Json的核心版本)的选项。
System.Text.Json仅支持无参数构造函数
答案 4 :(得分:0)
今天的简短回答是:将构造函数参数 prop
重命名为 property
,您的代码将可以正常工作。
public class Test
{
public string Property { get; }
public Test(string property)
{
Property = property;
}
}
Console.WriteLine(
JsonConvert.DeserializeObject(new Test("Instance")));
Newtonsoft.Json 支持使用开箱即用的构造函数参数初始化属性,无需设置任何其他属性或更改任何设置。唯一的限制是参数名称必须与属性名称不区分大小写。