Skip to content

Commit 736c710

Browse files
author
Bart Koelman
authored
Fixed: fail on filtering to-many relationships (crashes later otherwise) (#752)
Fixed: filters are not applied in GetById reauests
1 parent 87f05f2 commit 736c710

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

src/JsonApiDotNetCore/QueryParameterServices/FilterService.cs

+7
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ private FilterQueryContext GetQueryContexts(FilterQuery query, string parameterN
6363
queryContext.Relationship = GetRelationship(parameterName, query.Relationship);
6464
var attribute = GetAttribute(parameterName, query.Attribute, queryContext.Relationship);
6565

66+
if (queryContext.Relationship is HasManyAttribute)
67+
{
68+
throw new InvalidQueryStringParameterException(parameterName,
69+
"Filtering on one-to-many and many-to-many relationships is currently not supported.",
70+
$"Filtering on the relationship '{queryContext.Relationship.PublicRelationshipName}.{attribute.PublicAttributeName}' is currently not supported.");
71+
}
72+
6673
if (!attribute.Capabilities.HasFlag(AttrCapabilities.AllowFilter))
6774
{
6875
throw new InvalidQueryStringParameterException(parameterName, "Filtering on the requested attribute is not allowed.",

src/JsonApiDotNetCore/Services/DefaultResourceService.cs

+2
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,10 @@ public virtual async Task<TResource> GetAsync(TId id)
143143
_hookExecutor?.BeforeRead<TResource>(pipeline, id.ToString());
144144

145145
var entityQuery = _repository.Get(id);
146+
entityQuery = ApplyFilter(entityQuery);
146147
entityQuery = ApplyInclude(entityQuery);
147148
entityQuery = ApplySelect(entityQuery);
149+
148150
var entity = await _repository.FirstOrDefaultAsync(entityQuery);
149151

150152
if (entity == null)

test/JsonApiDotNetCoreExampleTests/Acceptance/Spec/AttributeFilterTests.cs

+46
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,52 @@ public async Task Can_Filter_On_Related_Attrs()
8989
list.Owner.FirstName = person.FirstName;
9090
}
9191

92+
[Fact]
93+
public async Task Can_Filter_On_Related_Attrs_From_GetById()
94+
{
95+
// Arrange
96+
var context = _fixture.GetService<AppDbContext>();
97+
var person = _personFaker.Generate();
98+
var todoItem = _todoItemFaker.Generate();
99+
todoItem.Owner = person;
100+
context.TodoItems.Add(todoItem);
101+
await context.SaveChangesAsync();
102+
103+
var httpMethod = new HttpMethod("GET");
104+
var route = $"/api/v1/todoItems/{todoItem.Id}?include=owner&filter[owner.firstName]=SOMETHING-ELSE";
105+
var request = new HttpRequestMessage(httpMethod, route);
106+
107+
// Act
108+
var response = await _fixture.Client.SendAsync(request);
109+
var body = await response.Content.ReadAsStringAsync();
110+
111+
// Assert
112+
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
113+
}
114+
115+
[Fact]
116+
public async Task Cannot_Filter_On_Related_ToMany_Attrs()
117+
{
118+
// Arrange
119+
var httpMethod = new HttpMethod("GET");
120+
var route = "/api/v1/todoItems?include=childrenTodos&filter[childrenTodos.ordinal]=1";
121+
var request = new HttpRequestMessage(httpMethod, route);
122+
123+
// Act
124+
var response = await _fixture.Client.SendAsync(request);
125+
126+
// Assert
127+
var body = await response.Content.ReadAsStringAsync();
128+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
129+
130+
var errorDocument = JsonConvert.DeserializeObject<ErrorDocument>(body);
131+
Assert.Single(errorDocument.Errors);
132+
Assert.Equal(HttpStatusCode.BadRequest, errorDocument.Errors[0].StatusCode);
133+
Assert.Equal("Filtering on one-to-many and many-to-many relationships is currently not supported.", errorDocument.Errors[0].Title);
134+
Assert.Equal("Filtering on the relationship 'childrenTodos.ordinal' is currently not supported.", errorDocument.Errors[0].Detail);
135+
Assert.Equal("filter[childrenTodos.ordinal]", errorDocument.Errors[0].Source.Parameter);
136+
}
137+
92138
[Fact]
93139
public async Task Cannot_Filter_If_Explicitly_Forbidden()
94140
{

0 commit comments

Comments
 (0)