private string CreateFilteredPositionsResourceUrl(
            ResourceUriType uriType,
            PositionFilterDto filterModel)
        {
            int targetPage;

            switch (uriType)
            {
            case ResourceUriType.PreviousPage:
                targetPage = filterModel.Page - 1;
                break;

            case ResourceUriType.NextPage:
                targetPage = filterModel.Page + 1;
                break;

            case ResourceUriType.CurrentPage:
            default:
                targetPage = filterModel.Page;
                break;
            }

            return(Url.Link(
                       nameof(GetFilteredAsync),
                       new
            {
                Page = targetPage,
                PageSize = filterModel.PageSize,
                PositionType = filterModel.PositionType,
                OrderByField = filterModel.OrderByField,
                OrderByDirection = filterModel.OrderByDirection
            }));
        }
        private IEnumerable <Link> CreateLinksForFilteredPositions(
            LinkedPaginatedResult <LinkedPositionDto> paginatedResult,
            PositionFilterDto filterModel)
        {
            var links = new List <Link>
            {
                new Link
                {
                    Href = CreateFilteredPositionsResourceUrl(
                        ResourceUriType.CurrentPage,
                        filterModel),
                    Rel    = "self",
                    Method = HttpMethod.Get.ToString()
                }
            };

            if (paginatedResult.HasPrevious)
            {
                links.Add(
                    new Link
                {
                    Href = CreateFilteredPositionsResourceUrl(
                        ResourceUriType.CurrentPage,
                        filterModel),
                    Rel    = "previousPage",
                    Method = HttpMethod.Get.ToString()
                });
            }

            if (paginatedResult.HasNext)
            {
                links.Add(
                    new Link
                {
                    Href = CreateFilteredPositionsResourceUrl(
                        ResourceUriType.CurrentPage,
                        filterModel),
                    Rel    = "nextPage",
                    Method = HttpMethod.Get.ToString()
                });
            }

            return(links);
        }
        public async Task <IActionResult> GetFilteredAsync([FromQuery] PositionFilterDto filterModel)
        {
            _logger.LogInformation($"{nameof(PositionsController)}: {nameof(GetFilteredAsync)} was called with filter model: {JsonSerializer.Serialize(filterModel)}.");

            var filterDomainModel = _mapper.Map <PositionFilterDomainModel>(filterModel);

            var modelState = _positionsService.ValidatePositionFilterModel(filterDomainModel);

            if (!modelState.IsValid)
            {
                return(UnprocessableEntity(modelState));
            }

            var pagedPositionsDomainModel = await _positionsService.GetFilteredPositions(
                filterDomainModel,
                _currentUserService.AccessKey);

            var pagedPositionsDto = _mapper.Map <PaginatedResult <PositionDto> >(pagedPositionsDomainModel);

            SetPaginationHeaders(pagedPositionsDomainModel.Metadata);

            if (_mediaTypeService.IsLinkedRepresentation(_mediaType))
            {
                var linkedPositionsDto = pagedPositionsDto.Results
                                         .Select(position => new LinkedPositionDto
                {
                    Position = position,
                    Links    = CreateLinksForPosition(position.Symbol)
                });

                var linkedPagedPositionsDto = new LinkedPaginatedResult <LinkedPositionDto>(linkedPositionsDto, pagedPositionsDto.Metadata);

                linkedPagedPositionsDto.Links =
                    CreateLinksForFilteredPositions(linkedPagedPositionsDto, filterModel);

                return(Ok(linkedPagedPositionsDto));
            }
            else
            {
                return(Ok(pagedPositionsDto));
            }
        }