.NET Framework迁移.NET 8:Newtonsoft模型绑定行为差异疑问
问题:.NET Framework 迁移至 .NET 8 时 Newtonsoft JSON 反序列化行为不一致
我正在将.NET Framework项目迁移至.NET 8,遇到了模型绑定行为不一致的问题。两个项目均使用Newtonsoft进行JSON反序列化,定义了如下Person类:
public class Person { public string Name { get; set; } public int Age { get; set; } }
当发送包含null值的age字段的Post请求(JSON数据如下):
{ "name": "test", "age": null }
.NET Framework会将age转为0且Name属性赋值正常,对应的控制器代码:
public class PersonController : ApiController { public int Post([FromBody] Person person) { return person.Age; } }
而.NET 8(已添加Newtonsoft序列化配置):
builder .Services .AddControllers() .AddNewtonsoftJson();
控制器代码:
[ApiController] [Route("[controller]")] public class PersonController : ControllerBase { [HttpPost] public int Post([FromBody] Person person) { return person.Age; } }
会抛出如下异常:
{ "errors": { "age": [ "Error converting value {null} to type 'System.Int32'. Path 'age', line 3, position 15." ], "person": [ "The person field is required." ] }, "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-9df50c9ae2e267f2fe8a525c17162586-7661f82dc052edbd-00" }
我理解.NET 8的异常原因,但疑惑.NET Framework是否设置了额外的反序列化属性,具体是什么?
原因与解决方案
.NET Framework 的默认行为
.NET Framework 中的 Web API(基于System.Web.Http)默认有两个关键特性导致了这种差异:
- 宽松的模型验证策略:即使反序列化时出现类型转换错误(比如将
null赋值给值类型int),它不会将该错误判定为模型验证失败,而是会将值类型属性设置为其默认值(比如int的0),然后继续执行控制器方法。 - Newtonsoft.Json 的默认配置兼容:旧版本的 Newtonsoft.Json 在配合 .NET Framework Web API 使用时,默认会忽略值类型的
null赋值错误,自动回退到类型默认值,而不会抛出异常中断流程。
让 .NET 8 对齐 .NET Framework 行为的配置
要在 .NET 8 中实现和 .NET Framework 一致的效果,需要调整 Newtonsoft.Json 的序列化配置,同时可以根据需求调整模型验证的严格程度:
1. 全局配置 Newtonsoft.Json 忽略 null 值对值类型的赋值
修改AddNewtonsoftJson的配置,设置NullValueHandling.Ignore,这样反序列化时会跳过null值的赋值,值类型属性会保留默认值:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; });
2. 针对单个属性配置(可选)
如果只需要特定属性兼容这种行为,可以在Person类的属性上添加JsonProperty特性:
public class Person { public string Name { get; set; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public int Age { get; set; } }
3. 调整模型验证严格程度(可选)
如果需要完全关闭ApiController的自动模型验证(不推荐,除非有特殊需求),可以在配置中禁用:
builder.Services.Configure<ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; });
这样即使反序列化出现错误,也会进入控制器方法,此时值类型属性会被设置为默认值,但需要注意自行处理模型状态错误。
内容的提问来源于stack exchange,提问作者Wave
相关产品推荐
相关产品推荐

