From fef49ad0dacbbd9a4cc1ceaef410e16ba8dfb1be Mon Sep 17 00:00:00 2001 From: John Gathogo Date: Mon, 7 Nov 2022 21:49:22 +0300 Subject: [PATCH] Maintain case for parameter alias in generated nextlink --- .../Extensions/GetNextPageHelper.cs | 1 + .../ServerSidePagingControllers.cs | 20 ++++++++++++ .../ServerSidePagingDataModel.cs | 7 ++++ .../ServerSidePaging/ServerSidePagingTests.cs | 32 ++++++++++++++++++- 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.OData/Extensions/GetNextPageHelper.cs b/src/Microsoft.AspNetCore.OData/Extensions/GetNextPageHelper.cs index 5ae3adfd4..d3aaf1a75 100644 --- a/src/Microsoft.AspNetCore.OData/Extensions/GetNextPageHelper.cs +++ b/src/Microsoft.AspNetCore.OData/Extensions/GetNextPageHelper.cs @@ -74,6 +74,7 @@ internal static Uri GetNextPageLink(Uri requestUri, IEnumerable //------------------------------------------------------------------------------ +using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc; @@ -47,4 +48,23 @@ public IActionResult Get() return Ok(_serverSidePagingCustomers); } } + + public class ServerSidePagingEmployeesController : ODataController + { + private static List employees = new List( + Enumerable.Range(1, 13).Select(idx => new ServerSidePagingEmployee + { + Id = idx, + HireDate = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(2022, 11, 07).AddMonths(idx), TimeZoneInfo.Local) + })); + + [HttpGet] + [EnableQuery(PageSize = 3)] + public IActionResult GetEmployeesHiredInPeriod([FromRoute] DateTime fromDate, [FromRoute] DateTime toDate) + { + var hiredInPeriod = employees.Where(d => d.HireDate >= fromDate && d.HireDate <= toDate); + + return Ok(hiredInPeriod); + } + } } diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/ServerSidePaging/ServerSidePagingDataModel.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/ServerSidePaging/ServerSidePagingDataModel.cs index 24b64ea91..e08a31f99 100644 --- a/test/Microsoft.AspNetCore.OData.E2E.Tests/ServerSidePaging/ServerSidePagingDataModel.cs +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/ServerSidePaging/ServerSidePagingDataModel.cs @@ -5,6 +5,7 @@ // //------------------------------------------------------------------------------ +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -25,4 +26,10 @@ public class ServerSidePagingOrder public decimal Amount { get; set; } public ServerSidePagingCustomer ServerSidePagingCustomer { get; set; } } + + public class ServerSidePagingEmployee + { + public int Id { get; set; } + public DateTime HireDate { get; set; } + } } diff --git a/test/Microsoft.AspNetCore.OData.E2E.Tests/ServerSidePaging/ServerSidePagingTests.cs b/test/Microsoft.AspNetCore.OData.E2E.Tests/ServerSidePaging/ServerSidePagingTests.cs index 11ed517e4..ab0f5b38a 100644 --- a/test/Microsoft.AspNetCore.OData.E2E.Tests/ServerSidePaging/ServerSidePagingTests.cs +++ b/test/Microsoft.AspNetCore.OData.E2E.Tests/ServerSidePaging/ServerSidePagingTests.cs @@ -5,6 +5,7 @@ // //------------------------------------------------------------------------------ +using System; using System.Net.Http; using System.Text.Json; using System.Threading.Tasks; @@ -27,7 +28,7 @@ public ServerSidePagingTests(WebApiTestFixture fixture) protected static void UpdateConfigureServices(IServiceCollection services) { IEdmModel edmModel = GetEdmModel(); - services.ConfigureControllers(typeof(ServerSidePagingCustomersController)); + services.ConfigureControllers(typeof(ServerSidePagingCustomersController), typeof(ServerSidePagingEmployeesController)); services.AddControllers().AddOData(opt => opt.Expand().AddRouteComponents("{a}", edmModel)); } @@ -36,6 +37,13 @@ protected static IEdmModel GetEdmModel() ODataModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet("ServerSidePagingOrders").EntityType.HasRequired(d => d.ServerSidePagingCustomer); builder.EntitySet("ServerSidePagingCustomers").EntityType.HasMany(d => d.ServerSidePagingOrders); + + var getEmployeesHiredInPeriodFunction = builder.EntitySet( + "ServerSidePagingEmployees").EntityType.Collection.Function("GetEmployeesHiredInPeriod"); + getEmployeesHiredInPeriodFunction.Parameter(typeof(DateTime), "fromDate"); + getEmployeesHiredInPeriodFunction.Parameter(typeof(DateTime), "toDate"); + getEmployeesHiredInPeriodFunction.ReturnsCollectionFromEntitySet("ServerSidePagingEmployees"); + return builder.GetEdmModel(); } @@ -84,5 +92,27 @@ public async Task ValidNextLinksGenerated() Assert.Equal("http://localhost/prefix/ServerSidePagingCustomers?$expand=ServerSidePagingOrders&$skip=5", nextLink.GetString()); } } + + [Fact] + public async Task VerifyParametersInNextPageLinkInEdmFunctionResponseBodyAreInSameCaseAsInRequestUrl() + { + // Arrange + var requestUri = "/prefix/ServerSidePagingEmployees/" + + "GetEmployeesHiredInPeriod(fromDate=@fromDate,toDate=@toDate)" + + "?@fromDate=2023-01-07T00:00:00%2B00:00&@toDate=2023-05-07T00:00:00%2B00:00"; + var request = new HttpRequestMessage(HttpMethod.Get, requestUri); + var client = CreateClient(); + + // Act + var response = await client.SendAsync(request); + var content = await response.Content.ReadAsStringAsync(); + + // Assert + Assert.Contains("\"@odata.nextLink\":", content); + Assert.Contains( + "/prefix/ServerSidePagingEmployees/GetEmployeesHiredInPeriod(fromDate=@fromDate,toDate=@toDate)" + + "?%40fromDate=2023-01-07T00%3A00%3A00%2B00%3A00&%40toDate=2023-05-07T00%3A00%3A00%2B00%3A00&$skip=3", + content); + } } }