Fix failure on REST requests with $filter and $orderby parameters#3664
Fix failure on REST requests with $filter and $orderby parameters#3664RubenCerna2079 wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request addresses a REST regression (issue #3662) where OData system query options like $filter / $orderby could fail to be extracted from the query string, by normalizing URL-encoded $ (%24) before downstream parsing.
Changes:
- Normalize
%24to$in the REST request query string prior to parsing. - Add an end-to-end REST test to validate requests using
$filterand$orderbysucceed.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/Core/Services/RestService.cs | Normalizes the raw query string so $-prefixed OData query options can be parsed reliably. |
| src/Service.Tests/Configuration/ConfigurationTests.cs | Adds an end-to-end REST test to prevent regressions for $filter / $orderby query options. |
souvikghosh04
left a comment
There was a problem hiding this comment.
needs some changes on parsing logic and additional tests assesrtion
| using (HttpClient client = server.CreateClient()) | ||
| { | ||
| // Act | ||
| using HttpRequestMessage restRequest = new(HttpMethod.Get, "/api/Book?$orderby=id desc&$filter=publisher_id eq 1234"); |
There was a problem hiding this comment.
I don't think this explicitly tests the %24. the httpclient would internally normalize this, so this can pass with or without the fix. you might need to explicitly pass the encoded values in URI "/api/Book?%24orderby=id%20desc&%24filter=publisher_id%20eq%201234") and then do proper assertions.
There was a problem hiding this comment.
No, the whole point of the test is to make an end-to-end scenario with values that a user would use. Adding the encoded values directly would defeat that purpose and would not help us catch any possible regressions in the future. DAB should be able to encode these values by itself and not throw any errors.
There was a problem hiding this comment.
the intent is fair but partially justifiable. this test doesn't hit the fix's code path. HttpClient won't percent-encode $ (it's a legal sub-delimiter per RFC 3986), so Request.QueryString never contains %24 here, the Replace calls never fire. you can verify by reverting the fix and confirming the test still passes.
DAB is the server. it doesn't encode. it decodes what arrives on the wire. The regression is specifically when a client sends %24filter. the test must send the encoded form.
Suggestion: keep both as [DataRow] inputs: the current URI as a smoke test, plus a %24-encoded variant as the actual regression guard.
| QueryString? query = GetHttpContext().Request.QueryString; | ||
| string queryString = query is null ? string.Empty : GetHttpContext().Request.QueryString.ToString(); | ||
| string queryString = query is null ? string.Empty : GetHttpContext().Request.QueryString.ToString() | ||
| .Replace("?%24", "?$").Replace("&%24", "&$"); //Add replacement in order to ensure '$' sign is present as expected only for the case where it is after a '?' or '&' signs. |
There was a problem hiding this comment.
shouldn't this be parsed using already available libraries instead of manually? we have something like this below context.RawQueryString = queryString; context.ParsedQueryString = HttpUtility.ParseQueryString(queryString); or using Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery()
There was a problem hiding this comment.
this should be solved/fixed at root level to ensure downstream usage of the querystring is already valid.
There was a problem hiding this comment.
the trailing comment on RestService.cs:75 says what the code does but not why $ arrives URL-encoded in the first place, nor what PR #3080 changed that broke it. future readers will look at the Replace chain and have no idea whether they can remove it.
| using HttpResponseMessage restResponse = await client.SendAsync(restRequest); | ||
|
|
||
| // Assert - Verify REST response | ||
| Assert.AreEqual(HttpStatusCode.OK, restResponse.StatusCode, "REST request to auto-generated entity should succeed"); |
There was a problem hiding this comment.
this only checks HttpStatusCode.OK. a regression where $filter is silently dropped would still return 200 with an unfiltered list. can we also assert that the response body contains the rows you expect (publisher_id == 1234 only) and in the order requested.
Why make this change?
This issue is caused by a regression in PR #3080
What is this change?
This change fixes a bug that caused using
$filteror$orderbyin REST. This is done by replacing the URL-encoded special character into its counterpart as a '$' sign, which is what is expected for this sign to be inside the URL.How was this tested?
Added end to end test to ensure that REST requests that use
$filterand$orderbysucceed.Sample Request(s)
http://localhost:5000/api/Book?$orderby=id desc
http://localhost:5000/api/Book?$filter=publisher_id 1234