Exemple #1
0
        /*IActionResult defines a contract that represents the result of an action method.
         */
        /*ActionResult<T> explicity define the return type of the method, the other pieces
         * of code can infer the actions expected return type. That allows them to integrate
         * better of our actions. This isn't the benefit that is immediately obvious. It only
         * becomes obvious when implementing something like Swashbuckle for documenting the API,
         * which relies on getting information on how our API behaves. Next to that, both <T>
         * and ActionResult can be implicitly cast to an ActionResult of T, and that too simplifies
         * syntax. In other words, when you can use ActionResult of T, use it.*/

        /* We are now implementing a filter on mainCategory when getting authors.
         * The first thing to do is to allow the consumer of the API to pass in the value for the
         * mainCategory to the query string. This does not match any parameter name from the
         * route template so, thanks to the ApiController attribute, this will be bound by the
         * query string. [FromQuery] attribute is optional but this will make the code more
         * readable. In case the action parameter name is different from the key in the query string,
         * you can use the Name property FromQuery attribute [FromQuery(Name = "differentMainCategory")].
         * We will leave the default value as null. "string" is a reference type so null is the default.
         * By default, we don't want to apply "mainCategory" filters to our authors collection.
         */
        /* We will now add searching functionality for our Authors collection. We will accept a search query
         * and will return all authors for which one of the string fields contains the search query. First
         * we need to ensure that the search query can be passed in. That means adding a search query
         * string to our action parameter list for the GetAuthors action. We do need to combine it
         * with the filtering. The consumer might do a filter or search or combine both.
         */
        public ActionResult <IEnumerable <AuthorDto> > GetAuthors(AuthorsResourceParameter authorsResourceParameter)
        {
            var authorsFromRepo = _courseLibraryRepository.GetAuthors(authorsResourceParameter);

            // We are now commenting this codes since we will now use AutoMapper
            //var authors = new List<AuthorDto>();

            //foreach (var author in authorsFromRepo)
            //{
            //    authors.Add(new AuthorDto()
            //    {
            //        Id = author.Id,
            //        Name = $"{author.FirstName} {author.LastName}",
            //        MainCategory = author.MainCategory,
            //        Age = author.DateOfBirth.GetCurrentAge()
            //    }); ;
            //}

            //return Ok(authors);

            /* We want to map the authorsFromRepo variable. We pass to the type we want
             * to get back.
             */
            return(Ok(_mapper.Map <IEnumerable <AuthorDto> >(authorsFromRepo)));
        }
Exemple #2
0
        private IEnumerable <LinkDto> CreateLinksForAuthors(
            AuthorsResourceParameter authorsResourceParameter,
            bool hasNext, bool hasPrevious)
        {
            var links = new List <LinkDto>();

            links.Add(
                new LinkDto(CreateAuthorsResourceUri(authorsResourceParameter, ResourceUriType.Current),
                            "self",
                            "GET"
                            ));

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

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

            return(links);
        }
Exemple #3
0
        public async Task <PagedList <Author> > GetAuthors(AuthorsResourceParameter authorsResourceParameter)
        {
            var collectionBeforePaging = _context.Authors.ApplySort(authorsResourceParameter.OrderBy,
                                                                    _propertyMappingService.GetPropertyMapping <AuthorDto, Author>());

            if (!string.IsNullOrEmpty(authorsResourceParameter.Genre))
            {
                // trim and to lower case
                var genreForwhereClause = authorsResourceParameter.Genre.Trim().ToLower();
                collectionBeforePaging = collectionBeforePaging
                                         .Where(a => a.Genre.ToLower() == genreForwhereClause);
            }

            if (!string.IsNullOrEmpty(authorsResourceParameter.SearchQuery))
            {
                // trim and to lower case
                var searhForwhereClause = authorsResourceParameter.SearchQuery.Trim().ToLower();
                collectionBeforePaging = collectionBeforePaging
                                         .Where(a => a.Genre.ToLower().Contains(searhForwhereClause) ||
                                                a.FirstName.ToLower().Contains(searhForwhereClause) ||
                                                a.LastName.ToLower().Contains(searhForwhereClause));
            }

            return(await PagedList <Author> .Create(collectionBeforePaging,
                                                    authorsResourceParameter.PageNumber,
                                                    authorsResourceParameter.PageSize));
        }
        public IEnumerable <Author> GetAuthors(AuthorsResourceParameter authorsResourceParameter)
        {
            if (authorsResourceParameter == null)
            {
                throw new ArgumentNullException(nameof(authorsResourceParameter));
            }

            if (string.IsNullOrWhiteSpace(authorsResourceParameter.MainCategory) && string.IsNullOrWhiteSpace(authorsResourceParameter.SearchQuery))
            {
                return(GetAuthors());
            }

            var collection = _context.Authors as IQueryable <Author>;

            if (!string.IsNullOrWhiteSpace(authorsResourceParameter.MainCategory))
            {
                var mainCategory = authorsResourceParameter.MainCategory.Trim();
                collection = collection.Where(a => a.MainCategory == mainCategory);
            }

            if (!string.IsNullOrWhiteSpace(authorsResourceParameter.SearchQuery))
            {
                var searchQuery = authorsResourceParameter.SearchQuery.Trim();
                collection = collection.Where(a => a.MainCategory.Contains(searchQuery) ||
                                              a.FirstName.Contains(searchQuery) ||
                                              a.LastName.Contains(searchQuery));
            }

            return(collection.ToList());
        }
Exemple #5
0
        public ActionResult <IEnumerable <AuthorDto> > GetAuthors([FromQuery] AuthorsResourceParameter authorsResourceParameter)
        {
            var authors = _courseLibraryRepository.GetAuthors(authorsResourceParameter);

            var result = _mapper.Map <IEnumerable <AuthorDto> >(authors);

            return(Ok(result));
        }
        public IEnumerable <Author> GetAuthors(AuthorsResourceParameter authorsResourceParameter)
        {
            if (string.IsNullOrWhiteSpace(authorsResourceParameter.MainCategory) &&
                string.IsNullOrWhiteSpace(authorsResourceParameter.SearchQuery))
            {
                return(GetAuthors());
            }

            //mainCategory = mainCategory.Trim();
            //return _context.Authors.Where(a => a.MainCategory == mainCategory).ToList();

            /* It could be that we only want to apply the filter, only want to apply the
             * search query or both. We want to cover all of these cases, so the first thing
             * we will do is cast the Author DbSet to an IQueryable of author. The Author DbSet
             * is Authors on the context. By doing this, we can work on this collection, adding
             * where clauses for filtering when needed and for searching. There is a good reason
             * to write code like this and it has something to do with deferred execution.
             *
             * DEFERRED EXECUTION
             * Whe working with Entity-Framework Core, we use Linq to build our queries. With deferred
             * execution, the query variable itself never holds the query results and only stores
             * the query commands. Execution of the query is deferred until the query variable is
             * iterated over. So, deferred execution means that query execution occurs sometime after
             * the query is constructed. We can get this behavior by working with IQueryable
             * implementing collections. A query variable stores query commands and not results.
             * IQueryable of T allows us to execute the query against the specific datasource,
             * and while building upon it, it creates an expression tree. But, the query itself
             * is not sent to the datasource until the iteration happens and the iteration can happen
             * in different ways: (1) using the IQueryable in a loop, (2) calling ToList(), ToArray(),
             * ToDictionary() because this means that converting the expression tree to an actual
             * list of items, (3) calling Singleton queries like Average, Count, First,
             */
            var collection = _context.Authors as IQueryable <Author>;

            if (!string.IsNullOrWhiteSpace(authorsResourceParameter.MainCategory))
            {
                authorsResourceParameter.MainCategory = authorsResourceParameter.MainCategory.Trim();
                collection = collection.Where(a => a.MainCategory == authorsResourceParameter.MainCategory);
            }

            if (!string.IsNullOrWhiteSpace(authorsResourceParameter.SearchQuery))
            {
                authorsResourceParameter.SearchQuery = authorsResourceParameter.SearchQuery.Trim();
                collection = collection.Where(a => a.MainCategory.Contains(authorsResourceParameter.SearchQuery) ||
                                              a.LastName.Contains(authorsResourceParameter.SearchQuery) ||
                                              a.FirstName.Contains(authorsResourceParameter.SearchQuery));
            }

            return(collection.ToList());
        }
Exemple #7
0
        /* Creates a links for pagination
         */
        private string CreateAuthorsResourceUri(
            AuthorsResourceParameter authorsResourceParameter,
            ResourceUriType type)
        {
            switch (type)
            {
            case ResourceUriType.PreviousPage:
                return(urlHelper.Link("GetAuthors",
                                      new
                {
                    fields = authorsResourceParameter.Fields,
                    orderBy = authorsResourceParameter.OrderBy,
                    searchQuery = authorsResourceParameter.SearchQuery,
                    genre = authorsResourceParameter.Genre,
                    pageNumber = authorsResourceParameter.PageNumber - 1,
                    pageSize = authorsResourceParameter.PageSize
                }));;

            case ResourceUriType.NextPage:
                return(urlHelper.Link("GetAuthors",
                                      new
                {
                    fields = authorsResourceParameter.Fields,
                    orderBy = authorsResourceParameter.OrderBy,
                    searchQuery = authorsResourceParameter.SearchQuery,
                    genre = authorsResourceParameter.Genre,
                    pageNumber = authorsResourceParameter.PageNumber + 1,
                    pageSize = authorsResourceParameter.PageSize
                }));

            case ResourceUriType.Current:
            default:
                return(urlHelper.Link("GetAuthors",
                                      new
                {
                    fields = authorsResourceParameter.Fields,
                    orderBy = authorsResourceParameter.OrderBy,
                    searchQuery = authorsResourceParameter.SearchQuery,
                    genre = authorsResourceParameter.Genre,
                    pageNumber = authorsResourceParameter.PageNumber,
                    pageSize = authorsResourceParameter.PageSize
                }));
            }
        }
        public IEnumerable <Author> GetAuthors(AuthorsResourceParameter authorsResourceParameter)
        {
            var result = _context.Authors as IQueryable <Author>;

            if (!string.IsNullOrEmpty(authorsResourceParameter.MainCategory))
            {
                result = result.Where(it => it.MainCategory == authorsResourceParameter.MainCategory);
            }

            if (!string.IsNullOrEmpty(authorsResourceParameter.SearchQuery))
            {
                result = result.Where(it =>
                                      it.MainCategory.Contains(authorsResourceParameter.SearchQuery) ||
                                      it.FirstName.Contains(authorsResourceParameter.SearchQuery) ||
                                      it.LastName.Contains(authorsResourceParameter.SearchQuery)
                                      );
            }

            return(result);
        }
Exemple #9
0
        public async Task <IActionResult> GetAuthors([FromQuery] AuthorsResourceParameter authorsResourceParameter,
                                                     [FromHeader(Name = "Accept")] string mediaType) // accept header for getting the media type
        {
            if (!propertyMappingService.ValidMappingExistsFor <AuthorDto, Author>(authorsResourceParameter.OrderBy))
            {
                return(BadRequest());
            }

            if (!typeHelperService.TypeHasProperties <AuthorDto>(authorsResourceParameter.Fields))
            {
                return(BadRequest());
            }

            var authorsFromRepo = await libraryRepository.GetAuthors(authorsResourceParameter);

            var authors = Mapper.Map <IEnumerable <AuthorDto> >(authorsFromRepo);

            if (mediaType == "application/vnd.marvin.hateoas+json")
            {
                var paginationMetaData = new
                {
                    totalCount  = authorsFromRepo.TotalCount,
                    pageSize    = authorsFromRepo.PageSize,
                    currentPage = authorsFromRepo.CurrentPage,
                    totalPages  = authorsFromRepo.TotalPages
                };

                Response.Headers.Add("X-Pagination",
                                     Newtonsoft.Json.JsonConvert.SerializeObject(paginationMetaData));

                // Links for each author for DELETE, POST, GET
                var links = CreateLinksForAuthors(authorsResourceParameter,
                                                  authorsFromRepo.HasNext, authorsFromRepo.HasPrevious);

                var shapedAuthors = authors.ShapeData(authorsResourceParameter.Fields);

                // Links for each author for DELETE, POST, GET
                var shapedAuthorsWithLinks = shapedAuthors.Select(author =>
                {
                    var authorAsDictionary = author as IDictionary <string, object>;
                    var authorLinks        = CreateLinksForAuthor(
                        (Guid)authorAsDictionary["Id"], authorsResourceParameter.Fields);

                    authorAsDictionary.Add("links", authorLinks);

                    return(authorAsDictionary);
                });

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

                return(Ok(linkedCollectionResource));
            }
            else
            {
                var previousPageLink = authorsFromRepo.HasPrevious ?
                                       CreateAuthorsResourceUri(authorsResourceParameter, ResourceUriType.PreviousPage) :
                                       null;

                var nextPageLink = authorsFromRepo.HasNext ?
                                   CreateAuthorsResourceUri(authorsResourceParameter, ResourceUriType.NextPage) :
                                   null;

                var paginationMetaData = new
                {
                    previousPageLink,
                    nextPageLink,
                    totalCount  = authorsFromRepo.TotalCount,
                    pageSize    = authorsFromRepo.PageSize,
                    currentPage = authorsFromRepo.CurrentPage,
                    totalPages  = authorsFromRepo.TotalPages
                };

                Response.Headers.Add("X-Pagination",
                                     Newtonsoft.Json.JsonConvert.SerializeObject(paginationMetaData));

                return(Ok(authors.ShapeData(authorsResourceParameter.Fields)));
            }
        }