OData OpenType动态属性使用in筛选器抛ArgumentNullException问题咨询
结论
OData 协议本身支持开放类型(OpenType)的动态属性使用 in 筛选操作,你遇到的报错属于 ASP.NET Core OData 框架的已知 Bug,并非缺失必要配置。
问题原因
报错的核心原因是低版本 OData Uri 解析器的 InBinder 逻辑未兼容开放类型的动态属性场景:
- 对于显式定义的属性(比如示例中的
Address/City),EDM 模型中预先注册了明确的类型,InBinder解析in操作符时可以直接拿到属性类型作为集合的元素类型,不会出现空引用。 - 对于未显式注册的动态属性(比如示例中的
Address/Country),低版本InBinder没有做特殊处理,无法从动态属性上获取到预定义的元素类型,传入空值构造EdmCollectionType时就触发了ArgumentNullException: Value cannot be null. Parameter name: elementType异常。 - 而
eq操作符的绑定逻辑本身有兼容动态属性的处理,会自动根据右值的类型推导匹配,所以可以正常运行。
解决方案
你可以根据自己的业务场景选择以下任意一种方案解决:
- 显式注册动态属性类型(适合固定动态属性的场景)
在构建 EDM 模型时,提前声明对应动态属性的类型,让InBinder可以拿到正确的元素类型:
public static IEdmModel GetModel() { if (_edmModel == null) { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Account>("Accounts"); builder.EnumType<Gender>(); // 新增:显式声明Address复杂类型的Country动态属性为字符串类型 var addressType = builder.ComplexType<Address>(); addressType.HasDynamicProperty("Country", EdmPrimitiveTypeKind.String); builder.Namespace = typeof(Account).Namespace; _edmModel = builder.GetEdmModel(); } return _edmModel; }
- 拆解in操作为多个eq条件(适合临时兼容、动态属性不固定的场景)
把Address/Country in ('US','CN')这类筛选条件改为Address/Country eq 'US' or Address/Country eq 'CN'的写法,eq操作本身兼容动态属性,可以正常运行。 - 升级OData NuGet包版本(最推荐的方案)
这个Bug已经在后续版本修复,直接升级对应版本的包即可:
- 如果你用的是7.x版本的
Microsoft.AspNetCore.OData,升级到7.5.12及以上版本 - 如果你用的是8.x版本的
Microsoft.AspNetCore.OData,升级到8.0.8及以上版本
升级后无需修改业务代码即可正常支持动态属性的in筛选操作。
内容的提问来源于stack exchange,提问作者Cedar
相关产品推荐
相关产品推荐

