将json反序列化为具有默认私有构造函数的类的C#对象

将json反序列化为具有默认私有构造函数的类的C#对象,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我需要为下面的类反序列化json public class Test { public string Property { get; set; } private Test() { //NOTHING TO INITIALIZE } public Test(string prop) { Property = prop; } } 我可以创建一个测试实例,如 var instance = new Test(

我需要为下面的类反序列化json

public class Test
{
    public string Property { get; set; }

    private Test()
    {
        //NOTHING TO INITIALIZE
    }

    public Test(string prop)
    {
        Property = prop;
    }
}
我可以创建一个测试实例,如

var instance = new Test("Instance");
考虑到我的json

"{  "Property":"Instance" }"
我应该如何创建测试类的对象,因为我的默认构造函数是私有的,并且我得到的对象属性为NULL


我正在使用Newtonsoft Json解析器。

您可以通过使用
[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);
JsonSerializerSettings设置=新的JsonSerializerSettings
{
ConstructorHandling=ConstructorHandling.AllowNonPublicDefaultConstructor
};
Test t=JsonConvert.DeserializeObject(json,设置);

您似乎不需要采取任何额外的步骤

使用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;
    }
}
void Main()
{   
var o=JsonConvert.DeserializeObject(“{\”属性\“:\”实例\“}”);
Assert(o.Property==“实例”,
“反序列化时未设置属性值。”);
}
公开课考试
{
公共字符串属性{get;set;}
私人测试()
{
}
公共测试(字符串属性值)
{
属性=属性值;
}
}

无需创建序列化程序设置并在此处指定assign Constructor Handling。请记住为私有构造函数定义
[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;
    }

}
公共类操作
{
公共字符串路径;
公共业务()
{
var path=path.Combine(Directory.GetCurrentDirectory(),“nodes.txt”);
if(File.Exists(path)==false)
{
使用(File.Create(path))
{
}
}
this.path=path;
}
公共无效写入(字符串路径、列表节点)
{
var ser=JsonConvert.serialized对象(节点、格式、缩进);
writealText(路径,ser);
}
公共列表读取(字符串路径)
{
var text=File.ReadAllText(路径);
var res=JsonConvert.DeserializeObject(文本);
返回res;
}
}

祝你一切顺利

今天的简短回答是:将构造函数参数
prop
重命名为
property
,您的代码将正常工作

公共类测试
{
公共字符串属性{get;}
公共测试(字符串属性)
{
财产=财产;
}
}
控制台写入线(
反序列化对象(新测试(“实例”);

Json支持使用现成的构造函数参数初始化属性,而无需设置任何附加属性或更改任何设置。唯一的限制是参数名必须与属性名不区分大小写匹配。

您使用的是什么库?如何获得
Test
的实例?如果没有任何工厂生成
Test
对象,您希望如何将JSON反序列化到它的实例中?如果要序列化的对象位于不希望引入第三方依赖项的库/程序集中,则第二个选项是最佳选择(包括对Json.Net的依赖项…)在线修改示例示例:请注意,在此示例中,未使用带有
propertyValue
参数的公共构造函数。相反,私有构造函数与
属性
ter一起使用。如果要使其与
get
一起使用,请参阅我对该问题的回答>只有属性。