-
Notifications
You must be signed in to change notification settings - Fork 344
Fix failure on REST requests with $filter and $orderby parameters #3664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4224,6 +4224,41 @@ public async Task OpenApi_InteractiveSwaggerUI( | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// End to end test that validates that REST requests with OData query | ||
| /// options $filter and $orderby succeed to ensure no regression can occur. | ||
| /// </summary> | ||
| [TestMethod] | ||
| [TestCategory(TestCategory.MSSQL)] | ||
| public async Task TestForRestRequestsWithFilterAndOrderbyParameters() | ||
| { | ||
| // The configuration file is constructed by merging hard-coded JSON strings to simulate the scenario where users manually edit the | ||
| // configuration file (instead of using CLI). | ||
| string configJson = TestHelper.AddPropertiesToJson(TestHelper.BASE_CONFIG, BOOK_ENTITY_JSON); | ||
| Assert.IsTrue(RuntimeConfigLoader.TryParseConfig( | ||
| configJson, | ||
| out RuntimeConfig deserializedConfig, | ||
| replacementSettings: new(), | ||
| connectionString: GetConnectionStringFromEnvironmentConfig(environment: TestCategory.MSSQL))); | ||
| string configFileName = "custom-config.json"; | ||
| File.WriteAllText(configFileName, deserializedConfig.ToJson()); | ||
| string[] args = new[] | ||
| { | ||
| $"--ConfigFileName={configFileName}" | ||
| }; | ||
|
|
||
| using (TestServer server = new(Program.CreateWebHostBuilder(args))) | ||
| using (HttpClient client = server.CreateClient()) | ||
| { | ||
| // Act | ||
| using HttpRequestMessage restRequest = new(HttpMethod.Get, "/api/Book?$orderby=id desc&$filter=publisher_id eq 1234"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this explicitly tests the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
| 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"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Test different loglevel values that are avaliable by deserializing RuntimeConfig with specified LogLevel | ||
| /// and checks if value exists properly inside the deserialized RuntimeConfig. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 usingMicrosoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery()There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.