如何使用 StringAsEnumResolver 在 ASP.NET Core 5 OData 中按字符串过滤枚举?

NGU*_*YET 6 c# asp.net odata .net-core asp.net-core

使用最新的 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()))
Run Code Online (Sandbox Code Playgroud)

使用上面的代码来配置StringAsEnumResolver,我仍然无法使用字符串来过滤枚举。我在互联网上搜索过但无济于事。

我缺少什么?

错误来自$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)"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

错误来自$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)"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)