ODataController POST请求因属性不匹配致模型全为null的原因排查
OData请求含未知属性时模型解析为null的原因及解决办法
问题场景
在ODataController里用Post([FromBody] Request data)接收POST请求时,只要请求负载里有模型定义中不存在的属性(比如把Person写成Person_),整个Request模型就会被解析成null。
相关代码如下:
public class Person { public Guid Id { get; set; } public string? Firstname { get; set; } public string? Lastname { get; set; } } public class Request { public Guid Id { get; set; } public Guid? Personid { get; set; } public virtual Person? Person { get; set; } } public IActionResult Post([FromBody] Request data) { // 业务处理逻辑 }
测试用的curl请求示例:
curl --location --request POST 'https://localhost:7124/v2/request?$expand=Person($select=Id,Firstname,Lastname)/Request&@odata.context=%27https://localhost:7124/v2/$metadata' \ --header 'Content-Type: application/json' \ --data-raw '{ "Id": "a436677a-fa4b-465e-8e70-211a1a3de8e9", "Personid": "be9b53ad-4dfb-4db5-b269-32669f7c4e2d", "Person_" : { "Firstname": "JOHN", "Lastname": "SMITH", } }'
需求:哪怕请求里有不符合模型架构的属性,也要能正常解析拿到模型实例。
解析为null的原因
- JSON序列化组件的严格匹配:ASP.NET Core默认使用的System.Text.Json,默认开启了严格属性匹配模式——反序列化时碰到目标类未定义的属性,会直接触发绑定失败,最终整个模型被解析为
null。 - OData的模型校验逻辑:OData依赖EDM模型进行请求校验,如果请求负载包含EDM模型未定义的属性,会被判定为无效请求,进而导致模型绑定失败。
解决办法
1. 全局配置忽略未知属性
在Program.cs中修改JSON序列化配置,让System.Text.Json自动忽略未知字段:
builder.Services.AddControllers() .AddOData(options => options.Select().Expand().Filter().OrderBy().Count().SetMaxTop(100)) .AddJsonOptions(options => { options.JsonSerializerOptions.IgnoreUnknownFields = true; });
2. 给特定模型类添加特性
如果只想让单个模型忽略未知属性,直接在目标类上添加特性即可:
- 用System.Text.Json时:
using System.Text.Json.Serialization; [JsonIgnoreUnknownProperties] public class Request { public Guid Id { get; set; } public Guid? Personid { get; set; } public virtual Person? Person { get; set; } }
- 用Newtonsoft.Json(Json.NET)时:
using Newtonsoft.Json; [JsonIgnoreProperties(AllowUnknown = true)] public class Request { // 类成员 }
3. 调整OData的校验设置
如果OData的严格校验仍导致问题,可以关闭未知属性的校验规则:
builder.Services.AddControllers() .AddOData(options => { options.Select().Expand().Filter().OrderBy().Count().SetMaxTop(100); // 允许未知查询选项,关闭严格模型验证 options.AllowUnknownQueryOptions = true; options.ValidateModel = false; });
内容的提问来源于stack exchange,提问作者user2748122
相关产品推荐
相关产品推荐

