Newtonsoft反序列化.NET5 API内部类时double属性值全为0问题
问题成因
该问题是Newtonsoft.Json的默认反序列化逻辑和Company类Coordinates属性的Getter实现冲突导致:
- Newtonsoft.Json反序列化引用类型属性时,默认优先调用属性的Getter获取现有实例,直接对该实例的属性赋值,不会触发属性的Setter。
- 你当前的
Coordinates属性Getter实现为return coordinates ?? new Coordinates(),当私有字段coordinates为null时,只会返回一个临时的Coordinates实例,不会把这个实例赋值给私有字段coordinates。 - 反序列化时Json.NET将请求中的坐标值写入这个临时实例后,没有任何地方持有该实例,私有字段
coordinates仍然为null。后续你再次访问Coordinates属性时,Getter会返回一个全新的、所有属性默认为0的Coordinates实例,因此你看到的所有坐标值都是0。 - 你用
object类型接收参数时,Json.NET会直接反序列化为JObject对象,不会触发Company类的属性逻辑,所以能看到正确的坐标值。
解决方案
有三种可行方案,推荐前两种按需选择:
- 修改Coordinates属性的Getter逻辑
把Getter创建的默认实例赋值给私有字段,保证Json.NET填充的实例能被持久化保存,代码修改如下:[NotMapped] public Coordinates Coordinates { get { coordinates ??= new Coordinates(); return coordinates; } set { coordinates = value; Bounds = new NpgsqlTypes.NpgsqlBox(coordinates.Top, coordinates.Right, coordinates.Bottom, coordinates.Left); } } - 给Coordinates属性添加JsonProperty特性强制替换实例
不需要修改原有Getter逻辑,指定反序列化时直接创建新的Coordinates实例触发Setter:[NotMapped] [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] public Coordinates Coordinates { get { return coordinates ?? new Coordinates(); } set { coordinates = value; Bounds = new NpgsqlTypes.NpgsqlBox(coordinates.Top, coordinates.Right, coordinates.Bottom, coordinates.Left); } } - 全局配置Newtonsoft.Json反序列化规则(不推荐)
修改Startup的全局配置,所有反序列化场景都强制替换实例,可能影响其他业务逻辑:services.AddControllers().AddNewtonsoftJson(x => { x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; x.SerializerSettings.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace; });
内容的提问来源于stack exchange,提问作者polonskyg
相关产品推荐
相关产品推荐

