Thursday, April 1, 2010

Navigation Using Areas in Asp.Net MVC

Asp.Net MVC2 introduced Areas as a feature part of the framework. Areas allow you to divide your application into logical units. It also makes your Url’s look more accurate.

Thinking of a generic store they might have areas such as Inventory, Payroll, Employees and Sales. Here are example ActionLinks for each area.

<%= Html.ActionLink("Home", "Index", "Home", new { area = "" }, new { })%>
<%= Html.ActionLink("Payroll", "Index", "Main", new { area = "Payroll" }, new { })%>
<%= Html.ActionLink("Inventory", "Index", "Main", new { area = "Inventory" }, new { })%>
<%= Html.ActionLink("Employees", "Index", "Main", new { area = "Employees" }, new { })%>
<%= Html.ActionLink("Sales", "Index", "Main", new { area = "Sales" }, new { })%>

Notice that the area is passed as a route value. I wrote my own overload for the ActionLink that takes the Area as an argument.

public static MvcHtmlString ActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, string areaName, object routeValues, object htmlAttributes)
{
    RouteValueDictionary routes = new RouteValueDictionary(routeValues);
    RouteValueDictionary attributes = new RouteValueDictionary(htmlAttributes);
    routes.Add("area", areaName);
    return helper.ActionLink(linkText, actionName, controllerName, routes, attributes);
}

This makes our links look as follows:

<%= Html.ActionLink("Home", "Index", "Home", "", new { }, new { })%>
<%= Html.ActionLink("Payroll", "Index", "Main", "Payroll", new { }, new { })%>
<%= Html.ActionLink("Inventory", "Index", "Main", "Inventory", new { }, new { })%>
<%= Html.ActionLink("Employees", "Index", "Main", "Employees", new { }, new { })%>
<%= Html.ActionLink("Sales", "Index", "Main", "Sales", new { }, new { })%>

If you haven’t worked with Areas yet, your probably looking at the routes and noticing that each area link has a controller called Main with an Index method. You might think we’re calling the same controller and passing the area name as parameter. That is not what we are doing, each area has a controller named Main. Maybe the generated links will help.

http://somedomain.com/Payroll/Main
http://somedomain.com/Inventory/Main
http://somedomain.com/Employees/Main
http://somedomain.com/Sales/Main

Next thing you should notice is that the link for returning to the Home page has an empty area. We need this so that when we’re in an area we can move back up to the root. Otherwise, we’ll get a Resource Not Found error indicating showing that it’s looking for Home in that Area. This can also work in your favor. If you have a Home controller (or Main) in all of your areas, MVC will, by default, navigate within the Area and you don’t need to change your Site.Master.

Overall, areas are a great feature for keeping your applications organized.

No comments: