smi*_*rth 17 c# .net-core system.text.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;
}
}
Run Code Online (Sandbox Code Playgroud)
简单的往返。
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);
Run Code Online (Sandbox Code Playgroud)
Tan*_*jel 21
只需添加JsonConstructorAttribute到私有构造函数中,如下所示:
public class Employee
{
[JsonConstructor] // This will work from .NET 8.0
private Employee()
{
}
private Employee(int id, string name)
{
Id = id;
Name = name;
}
[JsonInclude]
public int Id { get; private set; }
[JsonInclude]
public string Name { get; private set; }
public static Employee Create(int id, string name)
{
Employee employee = new Employee(id, name);
return employee;
}
}
Run Code Online (Sandbox Code Playgroud)
从 .NET 7.0 开始,可以通过编写自己的 ContractResolver 使用私有无参数构造函数来完成反序列化,如下所示:
public class PrivateConstructorContractResolver : DefaultJsonTypeInfoResolver
{
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);
if (jsonTypeInfo.Kind == JsonTypeInfoKind.Object && jsonTypeInfo.CreateObject is null)
{
if (jsonTypeInfo.Type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).Length == 0)
{
// The type doesn't have public constructors
jsonTypeInfo.CreateObject = () =>
Activator.CreateInstance(jsonTypeInfo.Type, true);
}
}
return jsonTypeInfo;
}
}
Run Code Online (Sandbox Code Playgroud)
使用方法如下:
private static void Main(string[] args)
{
JsonSerializerOptions options = new JsonSerializerOptions
{
TypeInfoResolver = new PrivateConstructorContractResolver()
};
Employee employee = Employee.Create(1, "Tanvir");
string jsonString = JsonSerializer.Serialize(employee);
Employee employee1 = JsonSerializer.Deserialize<Employee>(jsonString , options);
}
public class Employee
{
private Employee()
{
}
private Employee(int id, string name)
{
Id = id;
Name = name;
}
[JsonInclude]
public int Id { get; private set; }
[JsonInclude]
public string Name { get; private set; }
public static Employee Create(int id, string name)
{
Employee employee = new Employee(id, name);
return employee;
}
}
Run Code Online (Sandbox Code Playgroud)
答案似乎是“否”,或者至少是“还没有”。
这是[System.Text.Json] v1的 System.Text.Json 序列化程序的已知限制。我们计划将来支持这一点。 -阿松汗
您可以为此编写一个自定义转换器...对于[ASP.NET Core] 3.0 版本,没有计划在反序列化期间调用非默认构造函数的额外支持。这必须由定制转换器来完成。——史蒂夫哈特
链接的自定义转换器选项将允许您使用您所拥有的任何 API 来构建对象,但与 Newtonsoft.Json 或实体框架通过摆弄反射和私有构造函数可以完成的操作不同,所以可能不是你在寻找什么。
| 归档时间: |
|
| 查看次数: |
11647 次 |
| 最近记录: |