Monday, May 10, 2010

Handling duplicate Area/Controller names in ASP.NET MVC 2

When dealing with duplicate names for an "Area" and "Controller" in ASP.NET MVC, we could run into issues. The ASP.NET routing mechanism needs to be understood to produce the proper links. In this post, I will walk through the problem, and the fix for ASP.NET MVC 2 on Visual Studio 2010.

First create an ASP.NET MVC 2 application from File -> New -> Project, and choose the project type shown below.

Next create an "AdministrationController" and an associated folder, called "Administration" inside the "Views" folder. Also create an empty view page (Index.aspx) inside this folder.

Place the below text inside the Content2 section of this view page.

   1:   <h2>Administration in Root</h2>

Then create a link to this controller/view from the "Home/Index.aspx" file as shown below.

   1:   <%=Html.ActionLink("Administration in Root", "Index", "Administration") %>

Make sure the link works as supposed to.

Stop debugger, and add a new area by right clicking on the solution, selecting "Area". Give the Area as "Administration".
Create an "Administration" controller as in the application's root, but this time inside the "Administration" area. Create the associated view folder/index.aspx page.Place the following text in the content area.

   1:  <h2>Administration in Area</h2>

Run the application as before, and verify that "Administration in Root" this time fails with a message similar to below:

Add another link to the "Administration" area from the "Home/Index.aspx".

   1:  <%= Html.ActionLink("Adminstration in Area ", "Index", "Administration", new { area = "Administration" }, null)%>

This link now will work from the Home/Index.aspx page hitting the "Administration in Areas" as shown below:

Now we need to fix the "Administration" in the application's root path.
To do that, we add the "namespaces" optional parameter in the routes.MapRoute function as shown below.

   1:     routes.MapRoute(

   2:                  "Default", // Route name

   3:                  "{controller}/{action}/{id}", // URL with parameters

   4:                  new { controller = "Home", action = "Index", id = UrlParameter.Optional },  // Parameter defaults

   5:                  new string[]{"DuplicateAreaControllerName.Controllers"}

   6:              );

By adding namespace to the routes.MapRoute(...), the previous Html.ActionLink(..) to the application's root "Administration" screen will work as before. Ideally, you will not run into this, but my team had this problem while trying to develop a similar feature set inside the areas with the same name. Looks like ASP.NET MVC 1.0 does not have a direct solution, but ASP.NET MVC 2.0 has better built-in support, although not very obvious at first. Hopefully you will be careful with your naming and avoid such situations in the first place.