Search code examples
c#odataasp.net-core-webapi

How to use ODataQueryOpions with lower Camel case?


I am using the latest Microsoft.AspNetCore.OData (7.0.0-beta2). I am trying to use ODataQueryOptions<> to get OData parameters from the OData query with Camel case properties names.

I have used builder.EnableLowerCamelCase(); Everything is working fine when calling my controller endpoints with Pascal case properties names. For example:

URL: /myentities?$orderby=**Id** Controller action: public async Task<IEnumerable<MyEntity>> Get(ODataQueryOptions<MyEntity> options)

But as soon as I use camel case names (/myentities?$orderby=**id**), the OData throw a validation exception:

ODataException: Could not find a property named 'id' on type 'MyNamespace.MyEntity'. Microsoft.OData.UriParser.EndPathBinder.GeneratePropertyAccessQueryForOpenType(EndPathToken endPathToken, SingleValueNode parentNode) Microsoft.OData.UriParser.EndPathBinder.BindEndPath(EndPathToken endPathToken) Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token) Microsoft.OData.UriParser.OrderByBinder.ProcessSingleOrderBy(BindingState state, OrderByClause thenBy, OrderByToken orderByToken) Microsoft.OData.UriParser.OrderByBinder.BindOrderBy(BindingState state, IEnumerable orderByTokens) Microsoft.OData.UriParser.ODataQueryOptionParser.ParseOrderByImplementation(string orderBy, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo) Microsoft.OData.UriParser.ODataQueryOptionParser.ParseOrderBy() Microsoft.AspNet.OData.Query.OrderByQueryOption.get_OrderByClause() Microsoft.AspNet.OData.Query.OrderByQueryOption.get_OrderByNodes() Microsoft.Extensions.Internal.PropertyHelper.CallNullSafePropertyGetter(Func getter, object target) Microsoft.AspNetCore.Mvc.Internal.DefaultComplexObjectValidationStrategy+Enumerator.GetModel(object container, ModelMetadata property) Microsoft.AspNetCore.Mvc.Internal.DefaultComplexObjectValidationStrategy+Enumerator+<>c__DisplayClass10_0.b__1() Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationEntry.get_Model() Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy strategy) Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy) Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, string key, object model) Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy strategy) Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy) Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, string key, object model) Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Validate(ModelMetadata metadata, string key, object model) Microsoft.AspNetCore.Mvc.Internal.DefaultObjectValidator.Validate(ActionContext actionContext, ValidationStateDictionary validationState, string prefix, object model) Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder+d__6.MoveNext()

I understand that builder.EnableLowerCamelCase(); is just about using Camel case when serializing OData entities "responses" but how to properly create an OData API with asp.net core using Camel case names and ODataQueryOptions<> ? Do I have to implement a custom binder or is there a native way to do it ?

I found an issue that may be related to my problem here: https://github.com/OData/WebApi/issues/889

Has anyone managed to implement this without any hack?


Solution

  • Everything is working fine with latest OData packages (7 beta4 or final) and without any additional setting. I think I should have had an old OData package or a wrong setting on my EDM OData model when I posted this question...