Wednesday, January 10, 2018

Attribute Based Routing

There are two types of routing (introduced in ASP.NET MVC 5).

Convention based routing - using MapRoute
Attribute based routing - Specify the route on each action method.

routes.MapRoute(
   name: "MyCustomRoute",
   url: "CustomController/{action}/{id}",
   defaults: new { action = "Index", id = UrlParameter.Optional }
 );

It will call CustomController and specified action method.


Attribute Based Routing :

Attribute Routing (introduced in MVC 5) is the ability to add routes to the Route Table via attributes so that the route definitions are in close proximity to their corresponding actions. We will still populate the Route Table, but we will do it in a different manner.

To enable attribute routing, we need to use MapMvcAttributeRoutes() in the RouteConfig

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapMvcAttributeRoutes(); //Enables Attribute Routing
    }
}

Example

public class HomeController : Controller
{
[Route("Users/Index")] //Route: /Users/Index
    public ActionResult Index() { ... }
}

What that [Route] attribute does is specify a route to be added to the Route Table which maps to this action.

Comman Route Prefix with Attribute Routing


To make your url neat, clear and user friendly, we can define the prefix in URL after domain name. We can use RoutePrefix attribute to define the prefix.

[RoutePrefix("Articles")]  
public class ArticleController: Controller  
{  
    [Route("{id}")] //Route: /Articles/13  
    public ActionResult Details(int id)  
        {  
            //other code goes here  
        }  
        [Route("{username}")] //Route: /Articles/mukeshkumar  
    public ActionResult MyArticleDetails(string username)  
    {  
        //other code goes here  
    }  
}  

Override the common route prefix with Attribute Routing


Sometimes, it is required to show different prefix in url with particular action. If you have already defined the Prefix for the whole controller then you can override it. To override the RoutePrefix, use ~ sign with prefix name with particular action in the Route attribute.

[RoutePrefix("Articles")]  
public class ArticleController: Controller  
{  
    [Route("~/ArticleList/{id}")] //Route: /ArticleList/13  
    public ActionResult Details(int id)  
    {  
        //other code goes here  
    }  
}  

Route Constraints with Attribute Routing


When we use Route Constraints with Route attribute, it basically restrict or force how parameters will match.

public class ArticleController: Controller  
{  
    [Route("Articles/{id:int}")] //Route: /Articles/13  
    public ActionResult Details(int id)  
        {  
            //other code goes here  
        }  
        [Route("Articles/{username}")] //Route: /Articles/mukeshkumar  
    public ActionResult GetUserDetails(string username)  
    {  
        //other code goes here  
    }  
}  

Attribute Routing in Area of ASP.NET MVC


In we are using Area in ASP.NET MVC project and want to use attribute routing, we need to use RouteArea attribute to define the area name and all will be same.

[RouteArea("Admin")]  
[RoutePrefix("Home")]  
[Route("{action}")]  
public class HomeController: Controller  
{  
    // route: /Admin/Home/Index  
    public ActionResult Index()  
        {  
            return View();  
        }  
        // route: /Admin/Home/Employees  
        [Route("employees")]  
    public ActionResult GetEmployees()  
        {  
            return View();  
        }  
        // route: /department  
        [Route("~/Department")]  
    public ActionResult Departments()  
    {  
        return View();  
    }  
}  

Name attribute

As we use Custom Routing in ASP.NET MVC. We can achieve Custom Routing to define the Name of Route and use this route on the basis of Route name.

[Route("Articles", Name = "MyArticle")]  
 public ActionResult GetAllArticle()  
 {  
 }  
<a href="@Url.RouteUrl("MyArticle ")">My Article</a>

In the above code, if you pass integer value as parameter after “Articles/” then it will hit to first route otherwise second.

No comments:

Followers

Link