Mon ami et moi avons rencontré le même problème avec les zones dans ASP.NET MVC 2. Nous avons trouvé un « hack » qui, jusqu'à présent, semble fonctionner. Pour la version tl; dr, voir le bas de cette réponse.
Vous avez probablement quelque chose de semblable à ce qui suit dans votre « Admin » zone de la classe « AdminAreaRegistration.cs »:
// Web/Areas/Admin/AdminAreaRegistration.cs
public override void RegisterArea(AreaRegistrationContext context) {
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
Ainsi, il faut donner un sens que lorsque vous faites une demande de « http://website/Abstract » , la route "Admin_default" ne correspond pas à la demande. Ainsi, de par sa conception, le framework MVC tente de faire correspondre la requête à d'autres routes définies. Si vous avez utilisé l'outil MVC dans Visual Studio pour créer votre projet Web, une route "Default" sera définie dans votre fichier "Global.asax" (à la racine de votre projet Web). Il devrait ressembler à ceci:
// Web/Global.asax.cs
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
La route « par défaut » réussit à faire correspondre la demande de « http://website/Abstract », avec « contrôleur » = « abstrait », « action » = « Index » (valeur par défaut), et "id" = UrlParameter.Optional (valeur par défaut). C'est le comportement correct et prévu ... jusqu'à présent.
Maintenant, l'infrastructure MVC tentera de charger le contrôleur "abstrait". De par sa conception, MVC recherchera une classe appelée "AbstractController" qui étend "Controller" n'importe où dans la hiérarchie des fichiers/espaces de noms du projet web. Il est important de noter que l'emplacement et l'espace de noms d'un contrôleur n'affectent pas la capacité de MVC à le trouver; en d'autres termes, juste parce que vous avez placé le "AbstractController" dans un dossier appelé "Areas \ Admin \ Controllers" et changé l'espace de noms en "Web.Areas.Admin.Controllers" au lieu de, disons, "Web.Controllers" , ne signifie pas que MVC ne l'utilisera pas. Lorsque MVC exécute l'action "Index" dans "AbstractController" qui, très probablement, renvoie juste "View()", MVC devient confus car il ne sait pas où trouver la vue "Index". Parce que MVC a correspondu à un itinéraire non-zone (la route "par défaut" dans Global.asax), il pense que la vue correspondante doit être située dans des dossiers de vue non-zone. Ainsi, vous obtenez le message d'erreur familier:
The view 'Index' or its master was not found. The following locations were searched:
~/Views/Abstract/Index.aspx
~/Views/Abstract/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
Nous, comme vous, ne voulez pas les demandes de « http://website/Abstract » pour résoudre à « AbstractController » de la zone « Admin »; seul "http://website/Admin/Abstract" devrait fonctionner. Je ne peux pas penser à pourquoi quelqu'un voudrait ce comportement.
Une solution simple est de supprimer la route "par défaut" dans Global.asax, mais cela va casser tous les contrôleurs/vues non-zone réguliers. Ce n'est probablement pas une option pour la plupart des gens ...
Alors, nous avons pensé que nous pourrions limiter l'ensemble des contrôleurs que MVC utiliserait pour les demandes assorties par la voie « par défaut » dans Global.asax:
// Web/Global.asax.cs
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional},
new[] {"Web.Controllers"} // Added this line
);
}
Non. Une demande pour "http://website/Abstract" encore utilise "AbstractController" dans la zone "Admin", même si l'espace de noms "AbstractController" est "Web.Areas.Admin.Controllers" et (clairement) pas "Web.Controllers" . C'est complètement déroutant; il semble que cette liste blanche n'a aucun effet sur la résolution du contrôleur de MVC.
- tl; dr réponse commence ici -
Après quelques bidouillages, nous avons compris comment forcer MVC à utiliser uniquement les contrôleurs au sein de l'espace de noms liste blanche (s).
// Web/Global.asax.cs
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional},
new[] {"Web.Controllers"}
).DataTokens["UseNamespaceFallback"] = false; // Added this line
}
Définir la clé "UseNamespaceFallback" du dictionnaire de DataTokens sur la route "par défaut" false. Maintenant, quand nous faisons une demande pour "http://website/Abstract", la route "Default" sera toujours correspondue (ceci est un comportement valide!) Mais MVC pas utiliser un contrôleur qui n'est pas dans les espaces de noms définis; dans ce cas, seuls les contrôleurs dans l'espace de noms "Web.Controllers" sont valides. Enfin, c'est la fonctionnalité que nous recherchions! Nous ne pouvons pas comprendre pourquoi ce n'est pas le comportement par défaut. Bizarre, hein?
Espérons que cela aide.
Que pensez-vous de cela: http://stackoverflow.com/questions/2314524/asp-net-mvc-2-rc-2-returns-area-specific-controller-when-no-area-specified Est-ce que haack dit essentiellement que mon problème est dû à la conception et que le seul moyen de le contourner est de router les routes vers tous les contrôleurs de l'espace de noms par défaut? – Bryan
ci-dessus lien vers le commentaire de hack est faux. correct: http://stackoverflow.com/questions/1639971/mvc-2-arearegistration-routes-order/1640825#1640825 – Bryan
Sans voir les routes que vous avez définies dans votre région et dans votre site principal, il est impossible de dire. – Haacked