Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

ASP.NET MVC Routing Basics

DZone's Guide to

ASP.NET MVC Routing Basics

·
Free Resource

Having worked building websites for several years now, on thing that I love is being able to build SEO friendly URLs. A framework that makes that easy is even better.  I have used URL rewriters and other various techniques to turn non-friendly URLs into something that works better for SEO.  For example, company.com/products.aspx?productId=4 isn't as friendly or as readable as company.com/products/4/red-stapler.  Search engines have gotten better at this, but it used to be that company.com/products.aspx?productId=4 would only be seen as company.com/products.aspx.  With this method, only one product would be indexed.  Luckily search engines have gotten better about handling dynamic urls, but why not make it easier on them.  The routing engine in ASP.NET MVC makes this super easy.

I am not also only concerned about SEO, but just URLs that make more sense.  I personally prefer URLs that don't have an extension, like .aspx or .php.  A lot of it is preference, but I have had to port applications before and it is very nice when you can use the same URLs.  While many sites aren't built this way, ASP.NET MVC sets you up to do it this way right off the bat.  I have worked on sites before where the URLs kept changing, usually for SEO reasons, and this can be a major pain.  Combined with some custom routes, this can be a breeze.

When you create a new ASP.NET MVC project, if you look in the global.asax.cs file, you will see the default routes:

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

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

The first line is just ignoring all *.axd requests but call to routes.MapRoute is what I want to look at.  This overload of the MapRoute method takes 3 parameters: Route Name, Url & Parameter Defaults.  The route name must be unique (more on that later) and can be used to build a link based on the url.  The URL is the actual URL of the resource.  Notice that there are sections inside brackets "{ }". These are defining parameters that you wish to pass through via the route.  In this case we have the controller, action and id.  The controller and action refers to the MVC controller and the action method on that controller.  The id parameter is used to pass some form of identifier to the action method.  The third parameter defines the defaults for the missing areas from the URL.  If you don't don't have any URL parameters, you don't need to include the third parameter.

If I were to hit my web server with just company.com, the URL is missing all parameters.  This is when the defaults kick in.  the controller is set to "Home", the action to "Index" and the id is null since it is optional.  This will execute the Index action on the HomeController class. If I fill out the full URL, then the parameters are filled based on the URL and the defaults are not used.  If I use company.com/Home/Index, it will still execute the Index method on the HomeController.  If I use company.com/Home, it will do the same since the Index action method is set as a default.  If I call company.com/Home/Privacy, it will attempt to execute the Privacy method on the HomeController.  While this definitely works when building a more application based site, when SEO is important, you may want to refine the routes just a bit.

Let's say that I want the privacy link to be just company.com/privacy to serve up the privacy policy for the site.  This makes sense as it would likely be on the HomeController, but company.com/privacy looks a little more normal than company.com/home/privacy.  To get around this we can go ahead and create our own route above the default route:

routes.MapRoute(
  "Privacy", 
  "privacy", 
  new { controller = "Home", action = "Privacy" }
);

Here I am creating a second route with the name of "Privacy" the url of just "privacy" and I'm setting the defaults to be the controller and action I am looking for.  At a very minimum when creating a new route, the controller and action must be specified.  Now, if I hit the site with company.com/privacy, the Privacy method on the HomeController will be executed and that will load the view that contains the privacy policy copy. I can also get this url, by using the route name so if I decide later that it needs to be changed to company.com/privacypolicy, I don't have to change my code in multiple places.  I'll have a future article in a few days on using the routes to create links and such.

So this is a basic route that gives us some SEO-friendliness.  What about the product example?

Let's say that I want my product URL to be company.com/products/4/red-stapler for my red stapler.  The "4" in the URL would be the product id, probably from the database.  The "red-stapler" text is there just for SEO and to make the URL be more descriptive.  The route for something like this would look like:

routes.MapRoute(
"Products",
"products/{productId}/{productName}",
new { controller = "Product", action = "Index", productId = "", productName = "" }
);

This would allow the url company.com/products/4/red-stapler to pass in the actual product id which would be used for looking up the product in the database for display as well as adding the product name for SEO purposes.  The Index method on the ProductController would get executed and would look like:

public ActionResult Index(string productId)
{
// Do some Product Lookup Here
return View();
}

Notice that the action has a parameter of productId and it is a string.  All URL parameters will be strings and not everyone has to be included in the action method.  For example, I want the productId because I need it to load the data from the database.  I'm not concerned about the productName because I'm not really using it for anything but SEO.  If I wanted to, I could add a second parameter to the action method for productName if I needed it. I can now do some work with the database and look up the product data to be sent to the database.

Using routes in ASP.NET MVC is both easy and fun.  I'm sure you will agree that company.com/products/4/red-stapler, is a much better URL than company.com/products.aspx?productId=4.  What is really nice is that now ASP.NET 4 has a routing engine built in so you can do MVC style routes within the normal ASP.NET framework.    Most web developers I know would much rather have these style routes and sometimes will go to great lengths to get them.  ASP.NET MVC just makes it really easy.

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}