private IEnumerable <LinkDto> CreateLinksForPersons(PersonsResourceParameters personsResourceParameters,
                                                            bool hasNext, bool hasPrevious)
        {
            var links = new List <LinkDto>();

            links.Add(new LinkDto(CreatePersonsResourceUri(personsResourceParameters, ResourceUriType.Current),
                                  "self",
                                  "GET"));

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

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

            return(links);
        }
Esempio n. 2
0
        public PagedList <Person> GetPersons(PersonsResourceParameters personsResourceParameters)
        {
            if (personsResourceParameters == null)
            {
                throw new ArgumentNullException(nameof(personsResourceParameters));
            }

            //if (string.IsNullOrWhiteSpace(personsResourceParameters.Gender) && string.IsNullOrWhiteSpace(personsResourceParameters.SearchQuery))
            //{
            //    return GetPersons();
            //}

            var collection = _context.People as IQueryable <Person>;

            if (!string.IsNullOrWhiteSpace(personsResourceParameters.Gender))
            {
                var gender = personsResourceParameters.Gender.Trim();
                collection = collection.Where(a => a.Gender == gender);
            }

            if (!string.IsNullOrWhiteSpace(personsResourceParameters.SearchQuery))
            {
                var searchQuery = personsResourceParameters.SearchQuery.Trim();
                collection = collection.Where(a => a.Gender.Contains(searchQuery) ||
                                              a.Email.Contains(searchQuery) ||
                                              a.FirstName.Contains(searchQuery) ||
                                              a.LastName.Contains(searchQuery) ||
                                              a.Address.Contains(searchQuery));
            }

            if (!string.IsNullOrWhiteSpace(personsResourceParameters.OrderBy))
            {
                //collection = collection.OrderBy(a => a.FirstName).ThenBy(a => a.LastName);

                // Get property mapping dictionary
                var personPropertyMappingDictionary = _propertyMappingService.GetPropertyMapping <PersonDto, Person>();

                collection = collection.ApplySort(personsResourceParameters.OrderBy, personPropertyMappingDictionary);
            }

            // It is important to add pagination last because we want to apply the pagination
            // on the filtered and searched collection. And if we did it first we would be searching and
            // filtering to only a small set of data, which would not return all the results, which is incorrect
            // The -1 insures that if we want to get page 2, the amount of items on page 1 will be skipped

            // Due to the Deferred Execution the query is only executed here because the IQueryably only
            // stores the queries. Only when we do a for loop, ToList..., or singleton queries (average, first)
            return(PagedList <Person> .Create(collection,
                                              personsResourceParameters.PageNumber,
                                              personsResourceParameters.PageSize));

            //collection
            //.Skip(personsResourceParameters.PageSize * (personsResourceParameters.PageNumber - 1))
            //.Take(personsResourceParameters.PageSize)
            //.ToList();
        }
        private string CreatePersonsResourceUri(PersonsResourceParameters personsResourceParameters,
                                                ResourceUriType type)
        {
            switch (type)
            {
            case ResourceUriType.PreviousPage:
                return(Url.Link("GetPersons",
                                new
                {
                    fields = personsResourceParameters.Fields,
                    orderBy = personsResourceParameters.OrderBy,
                    pageNumber = personsResourceParameters.PageNumber - 1,
                    pageSize = personsResourceParameters.PageSize,
                    gender = personsResourceParameters.Gender,
                    searchQuery = personsResourceParameters.SearchQuery
                }));

            case ResourceUriType.NextPage:
                return(Url.Link("GetPersons",
                                new
                {
                    fields = personsResourceParameters.Fields,
                    orderBy = personsResourceParameters.OrderBy,
                    pageNumber = personsResourceParameters.PageNumber + 1,
                    pageSize = personsResourceParameters.PageSize,
                    gender = personsResourceParameters.Gender,
                    searchQuery = personsResourceParameters.SearchQuery
                }));

            case ResourceUriType.Current:
            default:
                return(Url.Link("GetPersons",
                                new
                {
                    fields = personsResourceParameters.Fields,
                    orderBy = personsResourceParameters.OrderBy,
                    pageNumber = personsResourceParameters.PageNumber,
                    pageSize = personsResourceParameters.PageSize,
                    gender = personsResourceParameters.Gender,
                    searchQuery = personsResourceParameters.SearchQuery
                }));
            }
        }
        public IActionResult GetPersons([FromQuery] PersonsResourceParameters personsResourceParameters)
        {
            if (!_propertyMappingService.ValidMappingExistsFor <PersonDto, Person>(personsResourceParameters.OrderBy))
            {
                return(BadRequest());
            }

            if (!_propertyCheckerService.TypeHasProperties <PersonDto>(personsResourceParameters.Fields))
            {
                return(BadRequest());
            }

            var peopleFromRepo = _personRepository.GetPersons(personsResourceParameters);

            //var previousPageLink = peopleFromRepo.HasPrevious ?
            //    CreatePersonsResourceUri(personsResourceParameters, ResourceUriType.PreviousPage) : null;

            //var nextPageLink = peopleFromRepo.HasNext ?
            //    CreatePersonsResourceUri(personsResourceParameters, ResourceUriType.NextPage) : null;

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

            // O mapper serve para não ter que andar a fazer isto para todos
            //var people = new List<PersonDto>();

            //foreach (var person in peopleFromRepo)
            //{
            //    people.Add(new PersonDto()
            //    {
            //        Id = person.Id,
            //        Name = $"{person.FirstName} {person.LastName}",
            //        Address = person.Address,
            //        Age = person.DateOfBirth.GetCurrentAge(),
            //        Contact = person.Contact,
            //        Email = person.Email,
            //        NIF = person.NIF,
            //        Sex = person.Sex
            //    });
            //}

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

            var links = CreateLinksForPersons(personsResourceParameters, peopleFromRepo.HasNext, peopleFromRepo.HasPrevious);

            var shapedPersons = _mapper.Map <IEnumerable <PersonDto> >(peopleFromRepo)
                                .ShapeData(personsResourceParameters.Fields);

            var shapedPersonsWithLinks = shapedPersons.Select(person =>
            {
                var personAsDictionary = person as IDictionary <string, object>;
                var personLinks        = CreateLinksForPerson((Guid)personAsDictionary["Id"], null);
                personAsDictionary.Add("links", personLinks);
                return(personAsDictionary);
            });

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

            return(Ok(linkedCollectionResource));
        }