迁移到.NET Core后[FromBody]入参未覆盖类默认属性值问题咨询
问题根因
.NET Core 3.1 开始默认使用内置的 System.Text.Json 库处理HTTP请求的JSON反序列化,它对集合类型属性的默认处理逻辑与.NET 472使用的Newtonsoft.Json存在差异:
- 反序列化时会先调用类的无参构造函数完成实例初始化,此时你的
TestTypes属性已经被赋值为包含默认元素的列表 - 若检测到请求中携带了
TestTypes数组,默认不会直接替换属性的现有集合实例,而是将传入的元素追加到已有集合中,最终表现为默认值和传入值同时存在。
解决方案
方案1:全局切换为Newtonsoft.Json(适配老项目逻辑首选)
该方案无需修改业务实体代码,即可完全复用.NET 472版本的序列化行为:
- 安装对应版本的NuGet包:
Microsoft.AspNetCore.Mvc.NewtonsoftJson(版本号需匹配你的.NET Core 3.1主版本) - 在
Startup.cs的ConfigureServices方法中修改服务注册逻辑:
services.AddControllers() .AddNewtonsoftJson();
配置完成后反序列化逻辑会自动对齐.NET 472的表现,传入的集合属性会直接覆盖构造函数中设置的默认值。
方案2:适配System.Text.Json默认逻辑
如果不想引入Newtonsoft.Json依赖,可通过修改实体类代码解决:
不在构造函数中给集合属性赋值,改为属性声明时直接设置默认值,反序列化时传入的值会直接覆盖属性的默认实例:
public class TestFilter { // 改为属性声明时赋值默认值,反序列化会直接替换整个属性实例 public IReadOnlyCollection<TestType> TestTypes { get; set; } = new List<TestType> { new TestType("AdvancedTest", 10) }; public string Description; TestFilter() { } }
如果是.NET 5及以上版本,也可以直接全局配置System.Text.Json的行为,无需修改实体类:
services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.PreferredObjectCreationHandling = JsonObjectCreationHandling.Replace; });
内容的提问来源于stack exchange,提问作者doorman
相关产品推荐
相关产品推荐

