Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible, in MVC3, to have the same controller name in different areas?

In MVC3, I have the following areas:

  • Mobile
  • Sandbox

Then i route maps like this:

    context.MapRoute(         "Sandbox_default",         "Sandbox/{controller}/{action}/{id}",         new { controller = "SandboxHome", action = "Index", id = UrlParameter.Optional } 

and

    context.MapRoute(         "Mobile_default",         "Mobile/{controller}/{action}/{id}",         new { controller = "MobileHome", action = "Index", id = UrlParameter.Optional }     ); 

The problem is this gives urls like:

http://localhost:58784/Mobile/MobileHome

and

http://localhost:58784/Sandbox/SandboxHome

But I want it like this:

http://localhost:58784/Mobile/Home
http://localhost:58784/Sandbox/Home

The problem is when I rename the SandboxHome-Controller to Home, and the MobileHome-Controller to Home, which would give the desired URLs, it won't compile, saying it has two classes for HomeController.

How can I have the same controller name in different areas ?

like image 488
Stefan Steiger Avatar asked Feb 21 '11 11:02

Stefan Steiger


People also ask

What is controller name in MVC?

In ASP.NET MVC, every controller class name must end with a word "Controller". For example, the home page controller name must be HomeController , and for the student page, it must be the StudentController . Also, every controller class must be located in the Controller folder of the MVC folder structure.


2 Answers

Yes.

As explained by this blog post: http://haacked.com/archive/2010/01/12/ambiguous-controller-names.aspx

Assuming you have a call to RegisterAllAreas and the AreaRegistration files generated by Visual Studio. All you need to do is the namespace on the default route in global ASAX to prevent conflicts.

//Map routes for the main site. This specifies a namespace so that areas can have controllers with the same name routes.MapRoute(         "Default",         "{controller}/{action}/{id}",         new { controller = "Home", action = "Index", id = UrlParameter.Optional },         new[]{"MyProject.Web.Controllers"}  ); 

As long as you keep the Area controllers within their own namespaces. This will work.

like image 167
Rob Stevenson-Leggett Avatar answered Sep 20 '22 21:09

Rob Stevenson-Leggett


Yes it is but you'll have to change your routing:

context.MapRoute(     "Default",     "{area}/{controller}/{action}/{id}",     new { area = "Mobile", controller = "Home", action = "Index", id = UrlParameter.Optional } ); 

You could as well keep both routes but don't forget to define area in your defaults.

Important

Of course you must keep controllers in their own area namespaces:

namespace MyApp.Areas.Mobile.Controllers {     public class HomeController : Controller     {         ...     } }  namespace MyApp.Areas.Sandbox.Controllers {     public class HomeController : Controller     {         ...     } } 

Check this link on MSDN and see the walktrough. And don't forget to also check out this MSDN article that talks about area registration, because you will have to call RegisterAllAreas() method.

And since you still want to keep original non-area controllers, you should also read this Phil Haack's article how to do just that (Credit should go to @Rob in his answer for pointing to this blog post first).

like image 41
Robert Koritnik Avatar answered Sep 21 '22 21:09

Robert Koritnik