Custom Routing in MVC5 with Attributes

Share httpJunkie.com on..
Tweet about this on TwitterShare on FacebookShare on Google+Share on TumblrEmail this to someone

SKIP SETUP OF APPLICATION AND HEAD TO THE MEAT AND POTATOES OF THE CONTROLLER/CODE EXAMPLE

In ASP.NET MVC 5 we now have a quick and easy way of changing the routing of a specific action inside a controller. In the previous version of ASP.NET MVC 4 we had a routing config file that could be changed to provide for custom routing, but it was on a global level or you could create many rules and one would win over the other. Here is an example of the default routing (Which still exists BTW in MVC 5).

This file is located in the AppStart/RouteConfig.cs.

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

So you could create many routing rules to customize the different requirements for routes in your project and this was a bit of a pain point for novices and took quite a bit of tinkering to get what you wanted. But now in MVC 5 we have the ability to simply set an attribute in front of the Action in the specific Controller you want to route differently than the default routing configuration. Let’s start a new project and put some code in to help us understand how this works:

It would be best to use Visual Studio 2013 (Pro, Premium or Ultimate) or Visual Web Developer 2013 because they will let you start with a Full MVC 5 Web Application. If you need to use Visual Studio 2012 you will need to get your project updated to MVC 5. If you need to get up to speed on creating MVC 5 applications, See my other tutorials on how to get a full MVC 5 application as shipped in Visual Studio 2013 (But using Visual Studio 2012). Develop MVC 5 with ASP.NET Identity in Visual Studio 2012

I will be using Visual Web Developer 2013. This is a free tool. Instructions should be nearly identical.

1) Create a New Project > select ASP.NET Web Application and name it “RoutingDemo2013”. Hit OK

2) Select MVC template and click OK. (No need to add core references here)

Visual Studio will open up to a default Readme file. Lets close that. We are going to create a Model for some fictitious products and add custom routing attributes. At this point your project should build with no errors and display a Home, about and contact page. We will leave these alone.

3) Right click on the Models folder and select Add > Class and name it Product.cs

4) Put the following code into the file.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

  namespace RoutingDemo2013.Models
  {
    public class Product
    {
      public int ProductID { get; set; }
      public string Name { get; set; }
      public decimal Price { get; set; }
      public string Description { get; set; }
    }
  }

This will create a basic Products model so that we can scaffold out some CRUD operations. It is on those CRUD views that we will scaffold out that we will place the custom routing attributes for Product Details.

5) Let’s right click on our solution and select Build Solution this should give us a clean bill of health:
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

6) Now let’s right click on the Controllers folder and select:
Add > Controller > MVC 5 Controller with views using Entity Framework > Add

7) Now let’s name our Controller ProductsController and select Product under Model Class and ApplicationDBCOntext under Data Context class and click Add.

*Note: If you have problems adding a controller, it may be because you did not Build your project after adding your Product model. If this is the case, close out of your controller dialog box, Build the project and try again.

Visual Studio will now scaffold your views out and make sure we have the proper requirements like Entity Framework 6) etc.. Once it’;s done it will load your ProductController.cs

7) Before we do anything else we need to enable Entity Framework Code Migrations. Let’s open up our console and type the following:

PM> Enable-Migrations -EnableAutomaticMigrations

*Note: You can pull up the Package manager console by either navigating to:

Tools > Library Package Manager > Package Manager Console

Or by typing Console and hitting Enter in the Quick Launch at the top right of the Visual Studio IDE.

If you entered this correctly you will receive the following in your command line:
Checking if the context targets an existing database…
Code First Migrations enabled for project RoutingDemo2013.

8) Now let’s update the database to match the schema we just created by adding the Products model and controller. Type the following into your Package Manager Console:

PM> Update-Database -Verbose

*Note: YOu can omit the -Verbose line, but I put it in there just incase you want to see everything that happened when you ran Update-Database

So with that command we Created a Products table and constraints needed for our automatic migrations and since we did not have a database targeted in a custom connection string, Visual Studio set this all up in our localDB. YOu can see that DB if you go into the Solutions Explorer and click Show All Files. The AppData Folder will refresh and show a triangle next to it and once clicked you will see your DB named something like: aspnet-RoutingDemo2013-2014010XXXXXXX. OK back to the tutorial..

Let’s make a link to our Products view.

9) Open up the Views/Shared/_Layout.cshtml file and make the navigation code look like this:

 <ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", "Index", "Home")</li>
    <li>@Html.ActionLink("About", "About", "Home")</li>
    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
    <li>@Html.ActionLink("Products", "Index", "Product")</li>
 </ul>

10) OK, so let’s compile and run our application by hitting Ctrl+F5 and navigate to the Products page and create a few products just for filler content.

Name: Apples > Price: 1.05 > Description: Red and crunchy
Name: Oranges > Price: 1.50 > Description: Orange and juicy

that’s enough data for now.

Now let’s click on details instead of create. This is not the route we want. In the address bar you will see: /Product/Details/5 but we want to change it to look like this /Product-5

Lets go back to our ProductController.cs page

If you scroll down to the Details Action of this controller you will see that in order to get to the details of a specific product your URL needs to look like this:

/Product/Details/5 but we want to change it to look like this /Product-5

11) Lets replace the following code in the Details Controller:

// GET: /Product/Details/5
public ActionResult Details(int? id)

with this:

// GET: /Product-5
[Route("Product-{id}")]
public ActionResult Details(int? id)

12) That’s all we have to add to the controller.

13) Lets go to the AppStart/RouteConfig.cs file and add right after the line that says:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

Add:

routes.MapMvcAttributeRoutes();

Go test your Products page now and click on Details link. It should be routing to the new specification per your attribute. Try changing Product-{id} to Produce-{id} or Supercalifragilistic-{id}. It will work. This is how simple and powerful it is.

For Details

// GET: /Product-5
[Route("Service-{id}")]

For Edit (Get)

// GET: /Product-5/Edit
[Route("Product-{id}/Edit")]

Do the same for the Edit (Post)

[HttpPost]
[ValidateAntiForgeryToken]
[Route("Product-{id}/Edit")]

Now for Delete (Get)

// GET: /Product-5/Delete
[Route("Service-{id}/Delete")]

And finally for Delete (Post)

// POST: /Product-5/Delete
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
[Route("Product-{id}/Delete")]

That’s it, you can link to this article at anytime using our easy URL from TinyURL.com
TinyURL.com/MVC-AttributeRouting

This tutorial covered just the basics of Attribute Routing and setting up a database and controllers/views with a products table, you can find more advanced and in depth explanations on Attribute Routing from these resources:

Sampath Lokuge’s Tech Blog
Attribute Routing With ASP.net MVC 5 &
Attribute Routing With ASP.net MVC 5 – Route Constraints

Blogs.MSDN
Attribute Routing in ASP.NET MVC 5.

IT World
ASP.NET MVC 5 brings attribute based routing.

Leave a Reply

You must be logged in to post a comment.