Learn how to create a REST API with Attribute Routing in WEB API Part 4

Rama Sagar
Posted by in ASP.NET Web API category on for Beginner level | Points: 250 | Views : 7694 red flag
Rating: 4 out of 5  
 1 vote(s)

According to MSDN, Routing is how Web API matches a URI to an action. Web API 2 supports a new type of routing, called attribute routing.
In this article we will look into creating a REST API using Attribute Routing in WEB API2

Introduction


In this article, we will use attribute routing to create a REST API for a collection of products.For a general overview of attribute routing, see previous articles Part 1 ,Part 2,


Objective


The Objective of the article is to create a REST API using Attribute Routing in WEB API 2



  • Step 1  We will convert the Productscontroller to use attribute routing. First, add a RoutePrefix attribute to the controller. This attribute defines the initial URI segments for all methods on this controller.

    [RoutePrefix("api/products")]
    public class ProductsController : ApiController
    {
	//.......
    }

       Then add [Route] attributes to the controller actions, as follows

	[Route("")]
        public IQueryable GetProducts()
        {
            return db.Products.Include(b => b.Manufacturer).Select(AsProductDtO);
        }



        [Route("{id:int}")]
        [ResponseType(typeof(ProductDtO))]
        public async Task GetProduct(int id)
        {




  • Step 2 To get product details, the client will send a GET request to /api/products/{id}/details, where {id} is the ID of the product,

Add the following method to the ProductsController class.

       [Route("{id:int}/details")]
        [ResponseType(typeof(ProductDetailDto))]
        public async Task<IHttpActionResult> GetProductDetail(int id)
        {
            var product = await (from b in db.Products.Include(b => b.Manufacturer)
                                 where b.ManufacturerId == id
                                 select new ProductDetailDto
                              {
                                  Title = b.Title,
                                  Category = b.Category,
                                  ReleaseDate = b.ReleaseDate,
                                  Price = b.Price,
                                  Description = b.Description,
                                  Manufacturer = b.Manufacturer.Name
                              }).FirstOrDefaultAsync();

            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }

Now If we request /api/products/1/details, the response looks like this



  • Step 3 : To get a list of products in a specific category,the client will send a GET request to /api/products/category, where category is the name of the category. (For example, /get/products/Electronics.).
Add the following method to ProductsController.


        [Route("{genre}")]
        public IQueryable<ProductDtO> GetProductsByCategory(string category)
        {
            return db.Products.Include(b => b.Manufacturer)
                .Where(b => b.Category.Equals(category, StringComparison.OrdinalIgnoreCase))
                .Select(AsProductDtO);
        }



Here we are defining a route that contains a {category} parameter in the URI template. Notice that Web API is able to distinguish these two URIs and route them to different methods:

/api/products/1

/api/products/Electronics

That's because the GetProduct method includes a constraint that the "id" segment must be an integer value:

Here is the complete code for the ProductsController class

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using ProductsAPI.Models;
using ProductsAPI.DTOs;
using System.Linq.Expressions;

namespace ProductsAPI.Controllers
{
    
    [RoutePrefix("api/products")]
    public class ProductsController : ApiController
    {
        private ProductsAPIContext db = new ProductsAPIContext();

        // Typed lambda expression for Select() method. 
        private static readonly Expression<Func<Product, ProductDtO>> AsProductDtO =
            x => new ProductDtO
            {
                Title = x.Title,
                Manufacturer = x.Manufacturer.Name,
                Category = x.Category
            };

        // GET api/Products
        [Route("")]
        public IQueryable<ProductDtO> GetProducts()
        {
            return db.Products.Include(b => b.Manufacturer).Select(AsProductDtO);
        }

        // GET api/Products/5
        [Route("{id:int}")]
        [ResponseType(typeof(ProductDtO))]
        public async Task<IHttpActionResult> GetProduct(int id)
        {
            ProductDtO product = await db.Products.Include(b => b.Category)
                .Where(b => b.ProductId == id)
                .Select(AsProductDtO)
                .FirstOrDefaultAsync();
            if (product == null)
            {
                return NotFound();
            }

            return Ok(product);
        }

      
        [Route("{id:int}/details")]
        [ResponseType(typeof(ProductDetailDto))]
        public async Task<IHttpActionResult> GetProductDetail(int id)
        {
            var product = await (from b in db.Products.Include(b => b.Manufacturer)
                                 where b.ManufacturerId == id
                                 select new ProductDetailDto
                              {
                                  Title = b.Title,
                                  Category = b.Category,
                                  ReleaseDate = b.ReleaseDate,
                                  Price = b.Price,
                                  Description = b.Description,
                                  Manufacturer = b.Manufacturer.Name
                              }).FirstOrDefaultAsync();

            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }
        [Route("{genre}")]
        public IQueryable<ProductDtO> GetProductsByCategory(string category)
        {
            return db.Products.Include(b => b.Manufacturer)
                .Where(b => b.Category.Equals(category, StringComparison.OrdinalIgnoreCase))
                .Select(AsProductDtO);
        }
        //To get a list of a products for a particular manufacturer, the client will send a GET request to /api/manufacturers/id/products, where id is the ID of the manufacturer.


        [Route("~api/manufacturers/{manufacturerId}/products")]
        public IQueryable<ProductDtO> GetproductsByManufacturer(int manufacturerId)
        {
            return db.Products.Include(b => b.Manufacturer)
                .Where(b => b.ManufacturerId == manufacturerId)
                .Select(AsProductDtO);
        }


        //Here we restricted the route to a particular format by adding a regular-expression constraint to the route template

        [Route("date/{reldate:datetime:regex(\\d{4}-\\d{2}-\\d{2})}")]
        [Route("date/{*reldate:datetime:regex(\\d{4}/\\d{2}/\\d{2})}")]
        public IQueryable<ProductDtO> GetProducts(DateTime pubdate)
        {
            return db.Products.Include(b => b.Manufacturer)
                .Where(b => DbFunctions.TruncateTime(b.ReleaseDate)
                    == DbFunctions.TruncateTime(pubdate))
                .Select(AsProductDtO);
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

    }
}
you can get the complete source code form here

Conclusion

In this article we have seen how to create a REST API using Attribute Routing

Reference

http://www.asp.net/web-api/overview/web-api-routing-and-actions/create-a-rest-api-with-attribute-routing

Page copy protected against web site content infringement by Copyscape

About the Author

Rama Sagar
Full Name: RamaSagar Pulidindi
Member Level: Silver
Member Status: Member,MVP
Member Since: 12/30/2012 1:51:40 AM
Country: India
ramasagar
http://www.ramasagar.com
A Software Profesional working in Microsoft .NET technologies since year 2008, and I work for Dake ACE. I am passionate about .NET technology and love to contribute to the .NET community at Dot Net Funda

Login to vote for this post.

Comments or Responses

Posted by: Kelly23 on: 10/26/2019 | Points: 25
That is loooking to be the best part of this game that we can generate the free fire hack for diamonds and coins free at http://freefiregen.net online.

Login to post response

Comment using Facebook(Author doesn't get notification)