我可以使用 System.Text.Json 通过私有构造函数反序列化 Json 吗?

想知道是否可以拥有私有构造函数并使用新的 System.Text.Json 序列化器。


public class MyModel

{

    public string Name { get; set; }

    public string Data { get; set; }


    private MyModel() 

    {

        // use me for when deserializing

    }


    public MyModel(string name, string data)

    {

        Name = name;

        Data = data;

    }

}

简单的往返。


var model = new MyModel("doo", "doo");

var json = JsonSerializer.Serialize(model, new JsonSerializerOptions

{

    WriteIndented = true

});


// no to go because of there is no parameterless constructor defined for this object.

var rehydrated = JsonSerializer.Deserialize<MyModel>(json);


扬帆大鱼
浏览 41回答 3
3回答

互换的青春

.NET 8.0 中的更新只需添加JsonConstructorAttribute到私有构造函数中,如下所示:public class Employee{&nbsp; &nbsp;[JsonConstructor] // This will work from .NET 8.0&nbsp; &nbsp;private Employee()&nbsp; &nbsp;{&nbsp; &nbsp;}&nbsp; &nbsp;private Employee(int id, string name)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp;Id = id;&nbsp; &nbsp; &nbsp;Name = name;&nbsp; &nbsp;}&nbsp; &nbsp;[JsonInclude]&nbsp; &nbsp;public int Id { get; private set; }&nbsp; &nbsp;[JsonInclude]&nbsp; &nbsp;public string Name { get; private set; }&nbsp; &nbsp;public static Employee Create(int id, string name)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp;Employee employee = new Employee(id, name);&nbsp; &nbsp; &nbsp;return employee;&nbsp; &nbsp;}}.NET 7.0 中的更新从 .NET 7.0 开始,可以通过编写自己的 ContractResolver 使用私有无参数构造函数来完成反序列化,如下所示:public class PrivateConstructorContractResolver : DefaultJsonTypeInfoResolver{&nbsp; &nbsp;public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp;JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);&nbsp; &nbsp; &nbsp; &nbsp;if (jsonTypeInfo.Kind == JsonTypeInfoKind.Object && jsonTypeInfo.CreateObject is null)&nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (jsonTypeInfo.Type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).Length == 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // The type doesn't have public constructors&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jsonTypeInfo.CreateObject = () =>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Activator.CreateInstance(jsonTypeInfo.Type, true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; return jsonTypeInfo;&nbsp; &nbsp;}}使用方法如下:private static void Main(string[] args){&nbsp; &nbsp; JsonSerializerOptions options = new JsonSerializerOptions&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;TypeInfoResolver = new PrivateConstructorContractResolver()&nbsp; &nbsp; };&nbsp; &nbsp; Employee employee = Employee.Create(1, "Tanvir");&nbsp; &nbsp; string jsonString = JsonSerializer.Serialize(employee);&nbsp; &nbsp; Employee employee1 = JsonSerializer.Deserialize<Employee>(jsonString , options);}public class Employee{&nbsp; &nbsp;private Employee()&nbsp; &nbsp;{&nbsp; &nbsp;}&nbsp; &nbsp;private Employee(int id, string name)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp;Id = id;&nbsp; &nbsp; &nbsp;Name = name;&nbsp; &nbsp;}&nbsp; &nbsp;[JsonInclude]&nbsp; &nbsp;public int Id { get; private set; }&nbsp; &nbsp;[JsonInclude]&nbsp; &nbsp;public string Name { get; private set; }&nbsp; &nbsp;public static Employee Create(int id, string name)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp;Employee employee = new Employee(id, name);&nbsp; &nbsp; &nbsp;return employee;&nbsp; &nbsp;}}

慕容3067478

答案似乎是“否”,或者至少是“还没有”。这是[System.Text.Json] v1的 System.Text.Json 序列化程序的已知限制。我们计划将来支持这一点。 -阿松汗您可以为此编写一个自定义转换器...对于[ASP.NET Core] 3.0 版本,没有计划在反序列化期间调用非默认构造函数的额外支持。这必须由定制转换器来完成。——史蒂夫哈特链接的自定义转换器选项将允许您使用您所拥有的任何 API 来构建对象,但与 Newtonsoft.Json 或实体框架通过摆弄反射和私有构造函数可以完成的操作不同,所以可能不是你在寻找什么。

海绵宝宝撒

您需要使用 JsonConstructor 属性。
打开App,查看更多内容
随时随地看视频慕课网APP