Sunday, May 18, 2014

What’s new in ASP.NET MVC 5 Part-1 : Attribute Routing

ASP.NET MVC is a new buzz word in Microsoft.NET stack most of people have started learning into it. So recently before some time Microsoft has released a Major new version of ASP.NET MVC with ASP.NET MVC 5.x. There are lots of new features given with ASP.NET MVC 5.x versions and I’m going to write a few series of blog post to explain all the features in details. So stay tuned with that!!

In this blog post I’m going to explain attribute routing in ASP.NET MVC 5.

Routing in ASP.NET MVC:


From the first version of ASP.NET MVC It’s provides a routing out of box. You don’t need to do much about it. Routing is how ASP.NET MVC matches URL in browsers to action. Based on URL a particular action is called on particular controller and result will be provided as view.

Till ASP.NET MVC 4.0, all routing was done using RouteCollection. If you need to do a routing you need to define a route collection in your RouteConfig file provided in App_Start folder in RegisterRoute static method. This method was called in Application_start event in ASP.NET MVC.

This is how the Register Route looks in ASP.NET MVC 4.0.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}
So when you request any URL it has to be there in route collection otherwise it will give an error.

Attribute routing in ASP.NET MVC 5:


ASP.NET MVC 5.x version supports new type of routing, called attribute routing. As name suggests it uses attribute to define routes. This type of routing will give you more control over URLs and you can create any type of URLS as you want.

So this how Register Route method looks in ASP.NET MVC 5.x versions.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapMvcAttributeRoutes();
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

Please notice routes.MapMvcAttributeRoutes() method in above code. It will map all the routes that is defined as attributes.If it is not there you need to put there to work with attribute routing.rr  Isn’t that amazing!! so what we are waiting for!! Let’s try it.

So first thing you need to create a ASP.NET MVC 5.0 Project from Visual Studio 2013.

Attribute routing demo in asp.net mvc 5.0 creating a new project in visual studio 2013

Once you created project this the Contact action code for the Home controller.

public ActionResult Contact()
{
    ViewBag.Message = "Your contact page.";

    return View();
}

Once you run in browser it will look like this.

contact-page-url-asp-net-mvc-5

If you see carefully you can see URL Home/Contact Now I want to change that URL as Home/ContactUs as I don’t like contact so I can do it very easily with attribute routing like Home/about-us/contact-us with following code.

[Route("Home/about-us/contact-us")]
public ActionResult Contact()
{
    ViewBag.Message = "Your contact page.";
    return View();
}

Now when you run this in browser. It will look like below.

attribute-routing-demo-contact-us-page-mvc5

So it’s very easy. Let’s see some complex example of attributes routing and see how it works there.
To test attribute routing in advance scenario I have created a contact class like to following.

using System;
using System.Linq;

namespace AttributeRoutingDemo.Models
{
    public class Contact
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string State { get; set; }
    }
}

Now it’s time to create a controller for that.

Contacts-Controller-asp-net-mvc

Following is a code for the Index Action result of controller.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using AttributeRoutingDemo.Models;

namespace AttributeRoutingDemo.Controllers
{
    [RoutePrefix("Contacts")]
    public class ContactController : Controller
    {
        [Route]
        public ActionResult Index()
        {
            var contacts = new List<Contact>
            {
                new Contact { Id = 1, Name = "Jalpesh Vadgama", State = "Gujarat" },
                new Contact { Id = 2, Name = "Chitan Shah", State = "Maharastra" },
                new Contact { Id = 3, Name = "Anurag Gothi", State = "Rajashthan" }
            };
            return View(contacts);
        }
    }
}

Route Prefix/Route in ASP.NET MVC 5:

If you see above code carefully you can see that I have putted RoutePrefix attribute on the controller. That attribute will tell URL routing that it will use that prefix commonly for whatever action this controller will have. Also if you have notice that route attribute on top of index controller it will say that this the default action method.

Now let’s add the View and see it in action. Following is a code for the view.

@model IEnumerable<AttributeRoutingDemo.Models.Contact>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.State)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.State)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id })
        </td>
    </tr>
}

</table>
Now let’s run application to see how route prefix works.

RoutePrefix-in-asp-net-mvc

See the URL of above image it is like contacts/.

Optional parameters in ASP.NET MVC 5:

To demonstrate optional parameters I have changed code of controller like following.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using AttributeRoutingDemo.Models;

namespace AttributeRoutingDemo.Controllers
{
    public class ContactController : Controller
    {
        [Route("Contacts/{state?}")]
        public ActionResult Index(string state)
        {
            var contacts = new List<Contact>
            {
                new Contact { Id = 1, Name = "Jalpesh Vadgama", State = "Gujarat" },
                new Contact { Id = 2, Name = "Chitan Shah", State = "Maharastra" },
                new Contact { Id = 3, Name = "Anurag Gothi", State = "Rajashthan" }
            };
            if(!string.IsNullOrEmpty(state))
            {
                contacts = contacts.FindAll(c => c.State == state);
            }
            return View(contacts);
        }
    }
}

Here you can check attribute route with states? which tells its optional. Now let’s see how its work without adding that.

RoutePrefix-in-asp-net-mvc

Now after adding state parameter.

optional-parameter-route-asp-mvc5

Strict Parameters/Route Constraints in ASP.NET MVC 5:

Just like optional parameters you can also have route constraints or strict parameters where you must pass parameters in URL otherwise it will give error. See following action result I have written in contacts controller.

[Route("Contacts/Id/{id:int}")]
public ActionResult GetContactsById(int id)
{
    var contacts = new List<Contact>
    {
        new Contact { Id = 1, Name = "Jalpesh Vadgama", State = "Gujarat" },
        new Contact { Id = 2, Name = "Chitan Shah", State = "Maharastra" },
        new Contact { Id = 3, Name = "Anurag Gothi", State = "Rajashthan" }
    };
   
        contacts = contacts.FindAll(c => c.Id == id);
   
    return View(contacts);
}

Here you can see in the attributes Id is passed as strict parameter as int so if you pass another then integer then it will give error.

strict-parameter-route-constraints-in-asp-net-mvc5

If you pass proper parameter it will give you proper result.

strict-parameter-route-constraints-in-asp-net-mvc5-proper-result

There is a great post by .NET web development and Tools Blog for attribute routing explained attribute routing in very details. I highly recommend referring that post also.

http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx

You can found this example source code on github at following url:https://github.com/dotnetjalps/AttributeRoutingDemoMVC

That’s it. Hope you like it. Stay tuned for more!!
Share:

1 comment:

  1. Nice Article, it might help to other

    http://www.code-sample.com/2014/08/attributerouting-in-web-api-2-mvc-5.html

    ReplyDelete

Your feedback is very important to me. Please provide your feedback via putting comments.

About Me
My Photo

Full Stack Developer,Blogger,Microsoft Mvp, Mentor, Life long learner, 10+ Years of Experience for JavaScript, web and Microsoft technologies. ASP.NET MVC,Web Forms,C#,AngularJs,Golang
Mvp profile
Subscribe to my blog

Enter your email address:

Follow us on facebook
Blog Archive
Total Pageviews