.NET Core 3.1 Web API启用OData过滤后返回大写属性问题求解
解决OData接口返回属性大小写不一致的配置方案
出现大小写差异的核心原因:.NET Core 3.1 中OData中间件持有独立的JSON序列化逻辑,默认遵循.NET类属性的PascalCase命名规则,没有复用全局ASP.NET Core配置的驼峰序列化规则;尤其是接口携带$select、$expand这类投影参数时,OData会直接基于Edm模型的属性名构造返回结构,跳过全局序列化规则的拦截,最终和普通无参数接口的返回格式出现差异。
具体配置步骤
- 打通全局JSON序列化规则与OData序列化逻辑的共用通道
在Startup.cs的ConfigureServices方法中,注册服务时同步配置全局接口和OData接口的序列化命名规则,确保两者策略一致:services.AddControllers() .AddJsonOptions(jsonOpt => { // 普通接口的驼峰序列化配置 jsonOpt.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; jsonOpt.JsonSerializerOptions.PropertyNameCaseInsensitive = true; }) .AddOData(odataOpt => { // 原有OData功能开关配置 odataOpt.Select().Filter().OrderBy().Expand().Count().SetMaxTop(null); *关键*:让OData序列化流程复用全局的序列化配置,避免独立使用默认的PascalCase序列化规则 odataOpt.EnableQueryFeatures(); }); - 修正Edm模型的默认命名规则,适配投影操作的属性输出
当OData执行$select、$expand投影逻辑时,会直接读取Edm模型定义的属性名构造返回键,需要在构建Edm模型时将默认的PascalCase属性名转换为和普通接口一致的camelCase格式:// 自定义Edm模型构建逻辑 private static IEdmModel BuildEdmModel() { var modelBuilder = new ODataConventionModelBuilder(); // 原有实体注册逻辑 modelBuilder.EntitySet<Question>("questions"); // 配置模型命名校验规则,将首字母大写的属性名转为小写驼峰 modelBuilder.ModelBuilder.ValidateName = originalName => { if (char.IsUpper(originalName[0])) { return char.ToLowerInvariant(originalName[0]) + originalName.Substring(1); } return originalName; }; return modelBuilder.GetEdmModel(); } - Newtonsoft.Json兼容配置(项目引用对应包时需添加)
如果项目通过Microsoft.AspNetCore.OData.NewtonsoftJson包引入了Newtonsoft.Json作为OData的序列化后端,需要显式为其配置驼峰命名规则,否则OData会优先使用Newtonsoft默认的PascalCase逻辑,覆盖全局配置:.AddOData(odataOpt => { // 原有OData功能配置 odataOpt.AddNewtonsoftJson(newtonsoftOpt => { newtonsoftOpt.ContractResolver = new CamelCasePropertyNamesContractResolver(); // 确保嵌套对象、字典类型的属性也同步应用驼峰规则 newtonsoftOpt.ContractResolver.NamingStrategy.ProcessDictionaryKeys = true; }); })
配置验证方式:修改完成后重启服务,分别调用无参数的普通接口和带
$select、$expand参数的OData接口,确认两者返回的JSON属性名均为小写驼峰格式,不存在首字母大写的属性键。
内容的提问来源于stack exchange,提问作者Mauro Bilotti
相关产品推荐
相关产品推荐

