How to use StringAsEnumResolver to filter enums by string in ASP.NET Core 5 OData?

Viewed 567

Using latest Microsoft.AspNetCore.OData 8.0.0-rc3.

services.AddControllers()
    .AddOData(opt => opt.Count().Filter().Expand().Select().OrderBy().SetMaxTop(100)
        .AddModel(string.Empty, GetEdmModel(),
            builder =>
            {
                builder.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataUriResolver), sp => new StringAsEnumResolver() { EnableCaseInsensitive = true });
            })
        .Conventions.Add(new OdataConvention()))

With the above code to configure StringAsEnumResolver, I'm still not able to use strings to filter enums. I've scoured the internet to no avail.

What am I missing?

Error from $filter=contactType eq 'person':

{
  "error": {
    "code": "",
    "message": "The query specified in the URI is not valid. The string 'person' is not a valid enumeration type constant.",
    "details": [
      
    ],
    "innererror": {
      "message": "The string 'person' is not a valid enumeration type constant.",
      "type": "Microsoft.OData.ODataException",
      "stacktrace": "   at Microsoft.OData.UriParser.MetadataBindingUtils.ConvertToTypeIfNeeded(SingleValueNode source, IEdmTypeReference targetTypeReference)\n   at Microsoft.OData.UriParser.BinaryOperatorBinder.PromoteOperandTypes(BinaryOperatorKind binaryOperatorKind, SingleValueNode& left, SingleValueNode& right, TypeFacetsPromotionRules facetsPromotionRules)\n   at Microsoft.OData.UriParser.ODataUriResolver.PromoteBinaryOperandTypes(BinaryOperatorKind binaryOperatorKind, SingleValueNode& leftNode, SingleValueNode& rightNode, IEdmTypeReference& typeReference)\n   at Microsoft.OData.UriParser.StringAsEnumResolver.PromoteBinaryOperandTypes(BinaryOperatorKind binaryOperatorKind, SingleValueNode& leftNode, SingleValueNode& rightNode, IEdmTypeReference& typeReference)\n   at Microsoft.OData.UriParser.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)\n   at Microsoft.OData.UriParser.MetadataBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)\n   at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\n   at Microsoft.OData.UriParser.FilterBinder.BindFilter(QueryToken filter)\n   at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilterImplementation(String filter, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo)\n   at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilter()\n   at Microsoft.AspNetCore.OData.Query.FilterQueryOption.get_FilterClause()\n   at Microsoft.AspNetCore.OData.Query.Validator.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)\n   at Microsoft.AspNetCore.OData.Query.FilterQueryOption.Validate(ODataValidationSettings validationSettings)\n   at Microsoft.AspNetCore.OData.Query.Validator.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\n   at Microsoft.AspNetCore.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\n   at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)\n   at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuting(ActionExecutingContext actionExecutingContext)"
    }
  }
}

Error from $filter=contains(tolower(contactType),'person'):

{
  "error": {
    "code": "",
    "message": "The query specified in the URI is not valid. No function signature for the function with name 'tolower' matches the specified arguments. The function signatures considered are: tolower(Edm.String Nullable=true).",
    "details": [
      
    ],
    "innererror": {
      "message": "No function signature for the function with name 'tolower' matches the specified arguments. The function signatures considered are: tolower(Edm.String Nullable=true).",
      "type": "Microsoft.OData.ODataException",
      "stacktrace": "   at Microsoft.OData.UriParser.FunctionCallBinder.MatchSignatureToUriFunction(String functionCallToken, SingleValueNode[] argumentNodes, IList`1 nameSignatures)\n   at Microsoft.OData.UriParser.FunctionCallBinder.BindAsUriFunction(FunctionCallToken functionCallToken, List`1 argumentNodes)\n   at Microsoft.OData.UriParser.FunctionCallBinder.BindFunctionCall(FunctionCallToken functionCallToken)\n   at Microsoft.OData.UriParser.MetadataBinder.BindFunctionCall(FunctionCallToken functionCallToken)\n   at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\n   at Microsoft.OData.UriParser.MetadataBinder.BindFunctionParameter(FunctionParameterToken token)\n   at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\n   at Microsoft.OData.UriParser.FunctionCallBinder.<BindFunctionCall>b__7_0(FunctionParameterToken ar)\n   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()\n   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\n   at Microsoft.OData.UriParser.FunctionCallBinder.BindFunctionCall(FunctionCallToken functionCallToken)\n   at Microsoft.OData.UriParser.MetadataBinder.BindFunctionCall(FunctionCallToken functionCallToken)\n   at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\n   at Microsoft.OData.UriParser.FilterBinder.BindFilter(QueryToken filter)\n   at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilterImplementation(String filter, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo)\n   at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilter()\n   at Microsoft.AspNetCore.OData.Query.FilterQueryOption.get_FilterClause()\n   at Microsoft.AspNetCore.OData.Query.Validator.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)\n   at Microsoft.AspNetCore.OData.Query.FilterQueryOption.Validate(ODataValidationSettings validationSettings)\n   at Microsoft.AspNetCore.OData.Query.Validator.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\n   at Microsoft.AspNetCore.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\n   at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)\n   at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuting(ActionExecutingContext actionExecutingContext)"
    }
  }
}
0 Answers
Related