通过阅读关于.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将列表返回为只读。
有没有一种方法可以告诉序列化使用私有字段?
1条答案
按热度按时间qpgpyjmq1#
问题不在于属性/字段,而在于构造函数参数名,它们应该匹配相应的属性/字段名。将ctor改为:
字符串
使用不可变的类型和属性:参数化构造函数文档:
参数化构造函数的参数名称必须与属性名称和类型匹配。匹配不区分大小写,并且构造函数参数必须与实际属性名称匹配,即使您使用
[JsonPropertyName]
重命名属性。注意,添加
JsonIncludeAttribute
就足够了。如果你可以让你的Age
属性init
-only,那么你可以完全跳过构造函数:的数据