public async Task <IActionResult> ExecuteAsync(PageOptionsCursor pageOptions, CancellationToken cancellationToken) { DateTimeOffset?createdAfter = Cursor.FromCursor <DateTimeOffset?>(pageOptions.Before); DateTimeOffset?createdBefore = Cursor.FromCursor <DateTimeOffset?>(pageOptions.After); ICommandResult <PaginatedResult <Car> > result = await _mediator .Send(new GetCarPageCommand(pageOptions.First, pageOptions.Last, createdAfter, createdBefore), cancellationToken); switch (result.Status) { case CommandStatus.Unknown: default: throw new ArgumentOutOfRangeException(nameof(result.Status), result.Status, null); case CommandStatus.NotFound: return(new NotFoundResult()); case CommandStatus.Ok: PaginatedResult <Car> paginatedResult = result.Data; List <CarVm> carViewModels = _carMapper.MapList(paginatedResult.Items); (string startCursor, string endCursor) = Cursor.GetFirstAndLastCursor(paginatedResult.Items, x => x.Created); PaginatedResultVm <CarVm> paginatedResultVm = _paginatedResultFactory .GetCursorPaginatedResult(pageOptions, paginatedResult.HasNextPage, paginatedResult.HasPreviousPage, paginatedResult.TotalCount, startCursor, endCursor, RouteNames.GetCarPage, carViewModels); _actionCtx.ActionContext.HttpContext .Response.Headers.Add(CustomHeaderNames.Link, paginatedResultVm.PageInfo.ToLinkHttpHeaderValue()); return(new OkObjectResult(paginatedResultVm)); } }
public Task <IActionResult> GetPageAsync( [FromServices] IGetCarPageAh handler, [FromQuery] PageOptionsCursor pageOptions, CancellationToken cancellationToken) { return(handler.ExecuteAsync(pageOptions, cancellationToken)); }
private Tuple <ExpandoObject, ExpandoObject> GetCursorUniqueQueryParams(PageOptionsCursor pageOptions) { ExpandoObject uniqueParams = new ExpandoObject(); ExpandoObject apiVersionParam = new ExpandoObject(); foreach (KeyValuePair <string, StringValues> item in _actionCtx.ActionContext.HttpContext.Request.Query) { string key = item.Key.ToLowerInvariant(); if (key != nameof(pageOptions.First).ToLowerInvariant() && key != nameof(pageOptions.Last).ToLowerInvariant() && key != nameof(pageOptions.Before).ToLowerInvariant() && key != nameof(pageOptions.After).ToLowerInvariant()) { if (key == ApiVersionQueryKey) { apiVersionParam.TryAdd(key, item.Value); } else { uniqueParams.TryAdd(key, item.Value); } } } return(new Tuple <ExpandoObject, ExpandoObject>(uniqueParams, apiVersionParam)); }
public PaginatedResultVm <T> GetCursorPaginatedResult <T>(PageOptionsCursor pageOptions, bool hasNextPage, bool hasPreviousPage, int totalCount, string startCursor, string endCursor, string routeName, ICollection <T> items) where T : class { ArgumentNullException.ThrowIfNull(pageOptions); if (string.IsNullOrEmpty(routeName)) { throw new ArgumentNullException(nameof(routeName)); } ICollection <T> resultItems = items ?? new List <T>(); Tuple <ExpandoObject, ExpandoObject> baseQueryParams = GetCursorUniqueQueryParams(pageOptions); PageInfoVm pageInfo = new PageInfoVm() { Count = items.Count, HasNextPage = hasNextPage, HasPreviousPage = hasPreviousPage, NextPageUrl = hasNextPage ? GetCursorNextPageUri(routeName, baseQueryParams, pageOptions, endCursor) : null, PreviousPageUrl = hasPreviousPage ? GetCursorPreviousPageUri(routeName, baseQueryParams, pageOptions, startCursor) : null, FirstPageUrl = GetCursorFirstPageUri(routeName, baseQueryParams, pageOptions), LastPageUrl = GetCursorLastPageUri(routeName, baseQueryParams, pageOptions), }; PaginatedResultVm <T> result = new PaginatedResultVm <T>(totalCount, pageInfo, resultItems); return(result); }
private Uri GetCursorNextPageUri(string routeName, Tuple <ExpandoObject, ExpandoObject> baseUrlParams, PageOptionsCursor pageOptions, string endCursor) { ExpandoObject baseParams = CopyUniqueQueryParams(baseUrlParams.Item1); baseParams.TryAdd(nameof(pageOptions.First), pageOptions.First ?? pageOptions.Last); baseParams.TryAdd(nameof(pageOptions.After), endCursor); return(GenerateLink(routeName, baseParams, baseUrlParams.Item2)); }