-
Notifications
You must be signed in to change notification settings - Fork 357
Description
Describe the bug
When querying an OData endpoint that uses a Flags
enum, the query fails to parse correctly when using either string representations of combined enum values or their numeric equivalents. This issue arises when attempting to filter data using queries such as /customers?filter=Type eq 'Premium,Loyal'
or /customers?filter=Type eq 66
. The error indicates that the provided string or numeric value is not recognized as a valid enumeration type constant.
Affected Assemblies
ODL 7.x, 8.x
Steps to Reproduce
- Clone the repo:
git clone https://github.com/WanjohiSammy/FlagsEnumIssue.git
-
Flags
enum in the application:[Flags] public enum CustomerType { None = 1, Premium = 2, VIP = 4, Regular = 8, New = 16, Returning = 32, Loyal = 64, }
-
A model that uses the
Flags
enum:public class Customer { public int Id { get; set; } public string? Name { get; set; } public CustomerType? Type { get; set; } }
-
Query the OData endpoint with the following filters:
/customers?filter=Type eq 'Premium,Loyal'
/customers?filter=Type eq 66
(where 66 is the result ofCustomerType.Premium | CustomerType.Loyal
)/customers?filter=Type in ('Premium', 'VIP, Regular, Returning')
/customers?filter=Type in (12, 44)
(where 12 isCustomerType.Premium | CustomerType.Loyal
and 44 isCustomerType.VIP | CustomerType.Regular | CustomerType.Returning
)/customers?filter=Type in ('12', '44')
/customers?filter=Type has any 'Premium,Loyal'
/customers?filter=Type has any '66'
Expected Behavior
The OData query should correctly parse and filter results based on the provided Flags
enum values, regardless of whether they are specified as strings or numeric equivalents. For example:
/customers?filter=Type eq 'Premium,Loyal'
should return customers with theType
field set toCustomerType.Premium | CustomerType.Loyal
./customers?filter=Type eq 66
should return the same results as the above query.
Actual Behavior
The query fails with an error similar to the following:
{
"error": {
"code": "",
"message": "The query specified in the URI is not valid. The string '66' is not a valid enumeration type constant.",
"details": [],
"innererror": {
"message": "The string '66' is not a valid enumeration type constant.",
"type": "Microsoft.OData.ODataException",
"stacktrace": " at Microsoft.OData.UriParser.MetadataBindingUtils.ConvertToTypeIfNeeded(SingleValueNode source, IEdmTypeReference targetTypeReference)\r\n at Microsoft.OData.UriParser.BinaryOperatorBinder.PromoteOperandTypes(BinaryOperatorKind binaryOperatorKind, SingleValueNode& left, SingleValueNode& right, TypeFacetsPromotionRules facetsPromotionRules)\r\n at Microsoft.OData.UriParser.ODataUriResolver.PromoteBinaryOperandTypes(BinaryOperatorKind binaryOperatorKind, SingleValueNode& leftNode, SingleValueNode& rightNode, IEdmTypeReference& typeReference)\r\n at Microsoft.OData.UriParser.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)\r\n at Microsoft.OData.UriParser.MetadataBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)\r\n at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\r\n at Microsoft.OData.UriParser.FilterBinder.BindFilter(QueryToken filter)\r\n at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilterImplementation(String filter, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo)\r\n at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilter()\r\n at Microsoft.AspNetCore.OData.Query.FilterQueryOption.get_FilterClause()\r\n at Microsoft.AspNetCore.OData.Query.Validator.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)\r\n at Microsoft.AspNetCore.OData.Query.FilterQueryOption.Validate(ODataValidationSettings validationSettings)\r\n at Microsoft.AspNetCore.OData.Query.Validator.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n at Microsoft.AspNetCore.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\r\n at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)\r\n at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuting(ActionExecutingContext actionExecutingContext)"
}
}
}
Additional Details
The issue appears to stem from the following sections of the Microsoft.OData.Core
library:
These sections of code may need to be updated to handle Flags
enums more effectively, ensuring that both string and numeric representations of combined enum values are correctly parsed and validated.