如何正确组合[JsonPropertyName]与[ObservableProperty]实现JSON反序列化?
问题原因与解决方案
问题根源
你遇到的问题是因为[ObservableProperty]特性会基于字段生成对应的公共属性(此处为Updated),但你将[JsonPropertyName("last_updated")]直接标注在了原字段上,而System.Text.Json默认只处理公共属性,生成的Updated属性并没有携带JSON映射特性,因此反序列化时无法匹配到JSON中的last_updated字段,导致Updated为null。
正确处理方式
使用[property: JsonPropertyName("last_updated")]的特性标注语法,将JSON映射特性直接应用到[ObservableProperty]生成的公共属性上,同时将原字段改为私有(符合MVVM工具包的最佳实践):
public partial class User : ObservableObject { // 其他属性示例 public int Id { get; set; } public string Username { get; set; } public string Created { get; set; } [ObservableProperty] [property: JsonPropertyName("last_updated")] private string updated; // 其他属性示例 public string Address { get; set; } public LastLogin LastLogin { get; set; } } public class LastLogin { public int Id { get; set; } public int UserId { get; set; } public string IpAddress { get; set; } public string ResultCode { get; set; } public string Result { get; set; } }
原理说明
[ObservableProperty]会自动将私有字段updated转换为公共属性Updated,并实现INotifyPropertyChanged逻辑。[property: ...]是C#的特性目标语法,用于指定特性要应用到生成的属性上,而非原字段。这样System.Text.Json就能识别到Updated属性对应JSON中的last_updated字段,完成正确映射。
验证反序列化代码
确保反序列化时使用正确的类型:
string jsonContent = "[{\"id\":1,\"username\":\"******\",\"password\":\"******\",\"email\":\"*****\",\"created\":\"2023-12-19 19:28:23\",\"last_updated\":\"2023-12-19 19:28:23\",\"address\":\"*******\",\"full_name\":\"*******\",\"last_login\":{\"id\":1,\"user_id\":1,\"ip_address\":\"******\",\"result_code\":\"0\",\"result\":\"Success\"},\"role\":\"Admin\"}]"; var userList = JsonSerializer.Deserialize<List<User>>(jsonContent);
此时userList[0].Updated会正确获取到JSON中的last_updated值。
内容的提问来源于stack exchange,提问作者TimoFran
相关产品推荐
相关产品推荐

