Controller omonimi in ASP.NET MVC
Oggi mi è capitato di dover gestire una nuova problematica in un’applicazione ASP.NET MVC. Nello specifico mi trovavo nella condizione di avere due controller con lo stesso nome; il primo era all’interno della struttura principale dell’applicazione, il secondo dentro un Area di MVC.
Il problema è identificabile e risolvibile a livello di routing; di fatto se si prova a guardare i seguenti controller (dai namespace è facilmente identificabile l’area):
namespace Dexter.Web.UI.Areas.Admin.Controllers {
public class HomeController : BackOfficeControllerBase {
[AcceptVerbs ( HttpVerbs.Get )]
[OutputCache ( VaryByParam = "id" , Duration = 600 )]
public ActionResult Index ( string id ){
return View();
}
}
}
namespace Dexter.Web.UI.Controllers {
public class HomeController : BackOfficeControllerBase {
[AcceptVerbs ( HttpVerbs.Get )]
[OutputCache ( VaryByParam = "id" , Duration = 600 )]
public ActionResult Index ( string id ){
return View();
}
}
}
per la seguente Route:
routes.MapRoute (
"Default" ,
"{controller}/{action}/{id}" ,
new {controller = "Home" , action = "Index" , id = UrlParameter.Optional}
);
ed ad associarla all’url http://www.miosito.com/Home/Index, si può capire come MVC non sia in grado di identificare correttamente quale dei due controller Home deve essere invocato per tale richiesta, e si trova “obbligato” a sollevare un’eccezione come la seguente:
Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
The request for 'Home' has found the following matching controllers:
Dexter.Web.UI.Controller.HomeController
Dexter.Web.UI.Areas.Admin.Controllers.HomeController
Nulla di allarmante, il problema è facilmente risolvibile specificando il namespace contenente il Controller corretto nella registrazione della Route, come mostrato di seguito:
routes.MapRoute (
"Default" ,
"{controller}/{action}/{id}" ,
new {controller = "Home" , action = "Index" , id = UrlParameter.Optional} ,
new string[] {"Dexter.Web.UI.Controller"}
);
A questo punto l’engine di MVC sa quale controller invocare e può esaudire correttamente la richiesta web.