2011-10-15 15 views
5

Quizás no entiendo correctamente cómo funcionan las áreas de MVC, pero esto me tiene un poco confundido.Controlador de área ASP.NET MVC3 accesible desde rutas globales?

  1. Añadir una zona llamada "MiArea" usando Haga clic en "Añadir Zona" en Visual Studio en el proyecto MVC3
  2. Crear un controlador para MiArea: "AnArea" a juego con la vista en el área de MiArea.
  3. Agregar "controlador = 'AnArea' para el parámetro por defecto de context.MapRoute en el método MyAreaAreaRegistration.RegisterArea.

Así que en este momento si se inicia la aplicación y vaya a/MiArea/usted debe cargar el controlador con AnArea es juego de la visión Si se desplaza a/MiArea/AnArea, se mostrará el mismo resultado

Pero, si navega a/AnArea /, el controlador todavía se encuentra y se muestra el siguiente mensaje de error:..

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched: 
~/Views/anarea/Index.aspx 
~/Views/anarea/Index.ascx 
~/Views/Shared/Index.aspx 
~/Views/Shared/Index.ascx 
~/Views/anarea/Index.cshtml 
~/Views/anarea/Index.vbhtml 
~/Views/Shared/Index.cshtml 
~/Views/Shared/Index.vbhtml 

¿Es este el comportamiento correcto? Pensé que el controlador de un área solo se podía acceder a través de su propia área y no a nivel mundial.

+0

posible duplicado de [ASP.NET MVC rutas predeterminadas accesibles a través de rutas de área] (http://stackoverflow.com/questions/4612279/asp-net-mvc-default-routes-accessible-via-area-routes) –

Respuesta

6

Cada vez que se crea un proyecto con áreas, puedo cambiar mi ruta Default de la siguiente manera:

routes.MapRoute( 
     "Default", // Route name 
     "{controller}/{action}/{id}", // URL with parameters 
     new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // defaults 
     null, // constraints 
     new string[] { "MyApplication.Controllers" } // namespaces 
    ); 

El parámetro final limita la ruta predeterminada a los controladores en el espacio de nombres MyApplication.Controllers. Esto asegura que la ruta predeterminada esté limitada a acciones fuera de cualquier área.

ACTUALIZACIÓN

Después de una inmersión profunda en el código, he descubierto donde surge el problema, y ​​tienen una solución. Cambiar la ruta por defecto a la siguiente:

routes.Add(
    "Default", 
    new Route("{controller}/{action}/{id}", 
     new RouteValueDictionary(
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ), 
     null, 
     new RouteValueDictionary(
      new { 
       Namespaces = new string[] { "MyApplication.Controllers" }, 
       UseNamespaceFallback = false 
      } 
     ), 
     new MvcRouteHandler() 
    ) 
); 

La clave está en la adición de la ficha UseNamespaceFallback. Esto evitará que la ruta predeterminada busque en otros espacios de nombres.

Esto es un comportamiento inesperado, y era un problema que desconoce que afecta a un proyecto en el que estoy trabajando. Lo mencionaré como un problema en aspnet.codeplex.com. Yo no llamaría esto un error, pero el comportamiento definitivamente parece violar las convenciones para el enrutamiento MVC.

+0

Esto no parece funcionar, el controlador de área aún se está activando a través de/anarea/ Mi controlador reside en el espacio de nombres: TestAreaControllerAccessibleFromGlobal.Areas.MyArea.Controllers, y agregué el espacio de nombres 'TestAreaControllerAccessibleFromGlobal.Controllers' al registro de ruta predeterminado (aquí es donde se colocó HomeController al crear el nuevo proyecto) – Duane

+0

¿Tiene alguna otra ruta definida en Global.asax.cs? – counsellorben

+0

No, solo la ruta "Predeterminada" con las modificaciones sugeridas en su respuesta: routes.MapRoute ( "Predeterminado", // Nombre de ruta "{controller}/{action}/{id}", // URL con los parámetros new {controller = "Home", action = "Index", id = UrlParameter.Optional}, // Parámetros predeterminados null, // constraints new [] {"TestAreaControllerAccessibleFromGlobal.Controllers"} // espacios de nombres ); – Duane

0

Tiene que aplicar una restricción de espacio de nombre en el área y en la ruta general.

En global.asax.cs debería editar RegisterRoutes método como este

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 string[] { "MyProject.Controllers" } 
    ); 
} 

que restringirá "//", sólo para los "espacios de nombres" MyProject.Controllers

Pero también you'll tiene que aplicar la restricción del espacio de nombres al Área para restringir "//" solo al espacio de nombres "MyProject.Areas.MyArea.Controllers"

Para eso, tendrá que editar el método "RegisterArea" de "MyAreaAreaRegistration.cs" como a continuación ("MyAreaRegistration.cs" se encuentra en '/ Áreas/MiArea carpeta/MiProyecto'):

//Some default code stuff 
... 
public override void RegisterArea(AreaRegistrationContext context) 
{ 
    context.MapRoute(
     "MyArea_default", 
     "MyArea/{controller}/{action}/{id}", 
     new { action = "Index", id = UrlParameter.Optional }, 
     new string[] { "MyProject.Areas.MyArea.Controllers" } 
    ); 
} 

espero que ayude !!

+0

Tiene que haber algo que falta, creé un nuevo proyecto MVC3, agregué una nueva área llamada MyArea, realicé los cambios anteriores que sugirió, pero el controlador del Área aún es visible desde el punto de vista global ... es decir, // AreaHome invoca el/MyArea/Controllers/AreaHomeController en el espacio de nombres "MyProject.Areas.MyArea.Controllers". – Duane

0

Usted parece estar navegando a /AnArea mientras que su área se llama MyArea por lo que debe navegar hasta . /MyArea/ Así es como se ve el registro de rutas zona como:.

context.MapRoute(
    "MyArea_default", 
    "MyArea/{controller}/{action}/{id}", 
    new { controller = "AnArea", action = "Index", id = UrlParameter.Optional } 
); 

AnArea es el nombre del controlador, no en la zona Si desea desplazarse a algún controlador de esta área siempre se debe anteponer su url con MyArea que es el nombre del área.

+0

Entiendo esto, el comportamiento que me produce curiosidad es cómo detener/AnArea/de resolver en el controlador AnArea de MyArea. Parece que counsellerben ha encontrado una solución, así que gracias de todos modos – Duane

Cuestiones relacionadas