Cannot perform `any` filter operation on enum collection attribute
See original GitHub issueDESCRIPTION
Cannot filter on enum attribute. Syntax not quite clear, error misses information.
STEPS TO REPRODUCE
I have an entity Users with an attribute Role, which is an enum of [Admin, Doctor…].
In Postman, a simple GET /users
will return a collection of all users.
I want to filter on Role.
I use the GET with url /users?filter=any(roles,'Admin')
In C# the roles are
public enum Role
{
Admin,
Doctor,
Nurse,
Assistant
}
The user:
public class User : Identifiable<Guid>, IManagedEntity
{
[Key]
public override Guid Id { get; set; }
[Attr]
[Required]
public string Email { get; set; }
[Attr]
public bool EmailConfirmed { get; set; }
[Attr(Capabilities = AttrCapabilities.AllowChange), NotMapped]
public string Password { get; set; }
[JsonIgnore]
public string? PasswordHash { get; set; }
[Attr]
public Role[]? Roles { get; set; }
}
EXPECTED BEHAVIOR
When I do a GET with the correct syntax for a filter on enum Role, I want to get a collection of users that has the specific Role.
ACTUAL BEHAVIOR
Postman receives an error message:
{
"errors": [
{
"id": "ea9d21c3-d86f-4228-aaca-9afb124ee0da",
"status": "400",
"title": "The specified filter is invalid.",
"detail": ", expected.",
"source": {
"parameter": "filter"
}
}
]
}
The detail field appears to be missing information.
Logging in IDE (Rider) shows:
info: JsonApiDotNetCore.Middleware.ExceptionHandler[0]
Errors = [
{
"Id": "ea9d21c3-d86f-4228-aaca-9afb124ee0da",
"Status": "400",
"Title": "The specified filter is invalid.",
"Detail": ", expected.",
"Source": {
"Parameter": "filter"
}
}
]
JsonApiDotNetCore.Errors.InvalidQueryStringParameterException: Errors = [
{
"Id": "ea9d21c3-d86f-4228-aaca-9afb124ee0da",
"Status": "400",
"Title": "The specified filter is invalid.",
"Detail": ", expected.",
"Source": {
"Parameter": "filter"
}
}
]
---> JsonApiDotNetCore.Queries.Internal.Parsing.QueryParseException: , expected.
at void JsonApiDotNetCore.Queries.Internal.Parsing.QueryExpressionParser.EatSingleCharacterToken(TokenKind kind) in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryExpressionParser.cs:line 85
at EqualsAnyOfExpression JsonApiDotNetCore.Queries.Internal.Parsing.FilterParser.ParseAny() in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs:line 204
at FilterExpression JsonApiDotNetCore.Queries.Internal.Parsing.FilterParser.ParseFilter() in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs:line 80
at FilterExpression JsonApiDotNetCore.Queries.Internal.Parsing.FilterParser.Parse(string source, ResourceContext resourceContextInScope) in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/Queries/Internal/Parsing/FilterParser.cs:line 42
at FilterExpression JsonApiDotNetCore.QueryStrings.Internal.FilterQueryStringParameterReader.GetFilter(string parameterValue, ResourceFieldChainExpression scope) in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs:line 135
at void JsonApiDotNetCore.QueryStrings.Internal.FilterQueryStringParameterReader.ReadSingleValue(string parameterName, string parameterValue) in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs:line 110
--- End of inner exception stack trace ---
at void JsonApiDotNetCore.QueryStrings.Internal.FilterQueryStringParameterReader.ReadSingleValue(string parameterName, string parameterValue) in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs:line 116
at void JsonApiDotNetCore.QueryStrings.Internal.FilterQueryStringParameterReader.Read(string parameterName, StringValues parameterValue) in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/QueryStrings/Internal/FilterQueryStringParameterReader.cs:line 78
at void JsonApiDotNetCore.QueryStrings.Internal.QueryStringReader.ReadAll(DisableQueryStringAttribute disableQueryStringAttribute) in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/QueryStrings/Internal/QueryStringReader.cs:line 61
at async Task JsonApiDotNetCore.Middleware.AsyncQueryStringActionFilter.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) in C:/projects/jsonapidotnetcore/src/JsonApiDotNetCore/Middleware/AsyncQueryStringActionFilter.cs:line 30
at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()+Awaited(?)
at void Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextExceptionFilterAsync()+Awaited(?)
VERSIONS USED
- JsonApiDotNetCore version: 4.2.0
- ASP.NET Core version: net5.0
- Entity Framework Core version: EF Core 6.4.4
- Database provider:
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
Not able to filter elements using an enum - java 8
I pass a list of ComputerComponent class to the averagePrice() function which has two fields of price which is of type double and...
Read more >Filtering on an enum collection in UI for WPF
I show a collection of Dish objects in a RadGridView. As property Categories is a collection I concatenate the values into a single...
Read more >Enum property stored as string, filter queries do not work
Entity Credit included an enum property Status , stored as a string, at the time the filter returns an "exception" as follows: System.Data....
Read more >How to use drop down filter in list view on enum values
I want to filter out list view rows based on an enumeration value using drop down filter. I was unable to bind the...
Read more >RadzenDataGridColumn enum filter not working without ...
I'm using a custom data grid column filter template with dropdown that is an Enum type. The filter string for LoadDataArgs looks like ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
This is by design. All filter operators act on a single value, never on arrays. How would you store an array in a database column?
The ‘equals’ function means: the target attribute must match the following constant. In contrast, the ‘set’ function means: the target attribute must match one constant from the following set, which is why you get an error when your set contains only one element – that is not a set and you should use ‘equals’ instead.
To accomplish the filter you want, don’t use an array but model roles as a to-many relationship.
Then the next filters return all users. But for each user, it includes only the subset of roles that match the condition.
or:
If, on the other hand, you want to filter on users, so return only users in a specific role, use the following:
or:
Hoi Bart,
Thx for the clear explanation. I’ll take it back to the team. Roles User many-to-many makes sense.
Cheerz, Eric