private IEnumerable <LinkDto> CreateLinksForCompany(
            CompanyResourceParameters companyResourceParameters,
            bool hasNext, bool hasPrevious)
        {
            var links = new List <LinkDto>();

            // self
            links.Add(
                new LinkDto(CreateCompaniesResourceUri(
                                companyResourceParameters, ResourceUriType.Current)
                            , "self", "GET"));

            if (hasNext)
            {
                links.Add(
                    new LinkDto(CreateCompaniesResourceUri(
                                    companyResourceParameters, ResourceUriType.NextPage),
                                "nextPage", "GET"));
            }

            if (hasPrevious)
            {
                links.Add(
                    new LinkDto(CreateCompaniesResourceUri(
                                    companyResourceParameters, ResourceUriType.PreviousPage),
                                "previousPage", "GET"));
            }

            return(links);
        }
        public PagedList <Company> GetCompanies(CompanyResourceParameters companiesResourceParameters)
        {
            if (companiesResourceParameters == null)
            {
                throw new ArgumentNullException(nameof(companiesResourceParameters));
            }

            var collection = _context.Company as IQueryable <Company>;

            if (!string.IsNullOrWhiteSpace(companiesResourceParameters.Type))
            {
                var type = companiesResourceParameters.Type.Trim();
                collection = collection.Where(a => a.Type == type);
            }

            if (!string.IsNullOrWhiteSpace(companiesResourceParameters.SearchQuery))
            {
                var searchQuery = companiesResourceParameters.SearchQuery.Trim();
                collection = collection.Where(a => a.Type.Contains(searchQuery) ||
                                              a.Name.Contains(searchQuery));
            }

            if (!string.IsNullOrWhiteSpace(companiesResourceParameters.OrderBy))
            {
                var companyPropertyMappingDictionary = _propertyMappingService.GetCompanyPropertyMapping <CompanyDto, Company>();

                collection = collection.ApplySort(companiesResourceParameters.OrderBy, companyPropertyMappingDictionary);
            }

            //Paging.... happens LAST
            return(PagedList <Company> .Create(collection,
                                               companiesResourceParameters.PageNumber,
                                               companiesResourceParameters.PageSize));
        }
        public IActionResult GetCompanies(
            [FromQuery] CompanyResourceParameters companyResourceParameters)
        {
            if (!_propertyMappingService.ValidCompanyMappingExistsFor <CompanyDto, Entities.Company>
                    (companyResourceParameters.OrderBy))
            {
                return(BadRequest());
            }

            var companiesFromRepo = _companyRepository.GetCompanies(companyResourceParameters);

            var paginationMetadata = new
            {
                totalCount  = companiesFromRepo.TotalCount,
                pageSize    = companiesFromRepo.PageSize,
                currentPage = companiesFromRepo.CurrentPage,
                totalPages  = companiesFromRepo.TotalPages
            };

            Response.Headers.Add("X-Pagination",
                                 JsonSerializer.Serialize(paginationMetadata));

            var links = CreateLinksForCompany(companyResourceParameters,
                                              companiesFromRepo.HasNext,
                                              companiesFromRepo.HasPrevious);

            var shapedCompanies = _mapper.Map <IEnumerable <CompanyDto> >(companiesFromRepo)
                                  .ShapeData(companyResourceParameters.Fields);

            var shapedCompaniesWithLinks = shapedCompanies.Select(company =>
            {
                var companyAsDictionary = company as IDictionary <string, object>;
                var companyLinks        = CreateLinksForCompany((string)companyAsDictionary["Id"], null);
                companyAsDictionary.Add("links", companyLinks);
                return(companyAsDictionary);
            });

            var linkedCollectionResource = new
            {
                value = shapedCompaniesWithLinks,
                links
            };

            return(Ok(linkedCollectionResource));
        }
        private string CreateCompaniesResourceUri(
            CompanyResourceParameters companyResourceParameters,
            ResourceUriType type)
        {
            switch (type)
            {
            case ResourceUriType.PreviousPage:
                return(Url.Link("GetCompanies",
                                new
                {
                    fields = companyResourceParameters.Fields,
                    orderBy = companyResourceParameters.OrderBy,
                    pageNumber = companyResourceParameters.PageNumber - 1,
                    pageSize = companyResourceParameters.PageSize,
                    mainCategory = companyResourceParameters.Type,
                    searchQuery = companyResourceParameters.SearchQuery
                }));

            case ResourceUriType.NextPage:
                return(Url.Link("GetCompanies",
                                new
                {
                    fields = companyResourceParameters.Fields,
                    orderBy = companyResourceParameters.OrderBy,
                    pageNumber = companyResourceParameters.PageNumber + 1,
                    pageSize = companyResourceParameters.PageSize,
                    mainCategory = companyResourceParameters.Type,
                    searchQuery = companyResourceParameters.SearchQuery
                }));

            case ResourceUriType.Current:
            default:
                return(Url.Link("GetCompanies",
                                new
                {
                    fields = companyResourceParameters.Fields,
                    orderBy = companyResourceParameters.OrderBy,
                    pageNumber = companyResourceParameters.PageNumber,
                    pageSize = companyResourceParameters.PageSize,
                    mainCategory = companyResourceParameters.Type,
                    searchQuery = companyResourceParameters.SearchQuery
                }));
            }
        }