json 如何在.NET 8中转换为私有字段?

11dmarpk  于 5个月前  发布在  .NET
关注(0)|答案(1)|浏览(53)

通过阅读关于.NET 8序列化的公告和文档,我的印象是我们可以序列化到私有字段中。
我试着做以下事情:

public class User
{
    [JsonInclude]
    [JsonPropertyName("name")]
    private string _name = null!;
    
    public int Age { get; }
            
    [JsonConstructor]
    private User(string name, int age)
    {
        _name = name;
        Age = age;
    }
    
    private User(){}

}

...
var userStr = @"{""name"": ""juan"", ""age"": 31}";
var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true,
    IncludeFields = true,
    IgnoreReadOnlyFields = false
};
var user = JsonSerializer.Deserialize<User>(userStr, options)!;

字符串
这就把

Unhandled exception. System.InvalidOperationException: Each parameter in the deserialization constructor on type 'User' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object. Fields are only considered when 'JsonSerializerOptions.IncludeFields' is enabled. The match can be case-insensitive.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ConstructorParameterIncompleteBinding(Type parentType)...


将private字段更改为一个属性,该属性将暴露一个getter(如public string Name { get; }),但问题是我希望它是一个private字段。在我的真实的场景中,我有一个private List<T>,但我只是暴露了一个public IReadOnlyCollection<T>,其getter将列表返回为只读。
有没有一种方法可以告诉序列化使用私有字段?

qpgpyjmq

qpgpyjmq1#

问题不在于属性/字段,而在于构造函数参数名,它们应该匹配相应的属性/字段名。将ctor改为:

[JsonConstructor]
private User(string _name, int age)
{
    this._name = _name;
    Age = age;
}

字符串
使用不可变的类型和属性:参数化构造函数文档:
参数化构造函数的参数名称必须与属性名称和类型匹配。匹配不区分大小写,并且构造函数参数必须与实际属性名称匹配,即使您使用[JsonPropertyName]重命名属性
注意,添加JsonIncludeAttribute就足够了。如果你可以让你的Age属性init -only,那么你可以完全跳过构造函数:

public class User1
{
    [JsonInclude]
    [JsonPropertyName("name")]
    private string _name = null!;
    
    public int Age { get; init; }

    public override string ToString() => $"{_name}: {Age}";
}
var userStr = @"{""name"": ""juan"", ""age"": 31}";
var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true,
};
var user = JsonSerializer.Deserialize<User1>(userStr, options)!;

Console.WriteLine(user); // prints "juan: 31"

的数据

相关问题