2011-03-25 20 views
44

He agregado una nueva área a mi proyecto MVC3 y estoy tratando de vincular desde la página _Layout al área nueva. He agregado un área llamada 'Admin' que tiene un controlador 'Meets'.ASP.NET MVC `Html.ActionLink` entre" Areas "

Utilicé el diseñador de estudio visual para agregar el área, por lo que tiene la clase de registro de área correcta, etc. y el archivo global.asax está registrando todas las áreas.

Sin embargo, cuando se utiliza los siguientes 2 enlaces de acción en una página en la raíz, me encuentro con algunos problemas:

@Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null) 
@Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null) 

Al hacer clic en ambos enlaces, me toman a la Meets controlador en la administración área, donde la aplicación procede a arrojar un error que dice que no puede encontrar la página Índice (aunque la página Índice está presente en la carpeta Vistas en el subdirectorio Área.

El href para el primer enlace se ve así :

http://localhost/BCC/Meets?area=Admin

Y el href para el segundo enlace es así:

http://localhost/BCC/Meets

también si golpeo el enlace que espero ser creado:

http://localhost/BCC/Admin/Meets

apenas consigo una recurso no se puede encontrar error. Todo muy desconcertante! Espero que alguien pueda ayudar ...

+0

¿Qué es "BCC" en este caso? Es un directorio virtual? –

Respuesta

7

Me di cuenta de esto - He creado un nuevo proyecto de prueba e hice exactamente el Lo mismo que estaba haciendo antes y funcionó ... luego de una inspección adicional de todas las cosas relacionadas con las rutas entre los dos proyectos, encontré una discrepancia.

En el archivo global.asax en mi solicitud BCC, había una línea de código de pícaro que había aparecido inexplicablemente:

 public static void RegisterRoutes(RouteCollection routes) 
     { 
      // Problem here 
      routes.Clear(); 

      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

      routes.MapRoute(
       "Default", // Route name 
       "{controller}/{action}/{id}", // URL with parameters 
       new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
      ); 
     } 

     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 

      RegisterGlobalFilters(GlobalFilters.Filters); 
      RegisterRoutes(RouteTable.Routes); 
     } 

Como se puede ver en mi comentario es, en algún momento u otro que tenía colocé las rutas. Llamada Clear() al comienzo de RegisterRoutes, lo que significaba que después de haber registrado las Areas en Application_Start, estaba borrando inmediatamente lo que acababa de registrar.

Gracias por la ayuda ... finalmente me condujo a mi salvación!

68

Extraño de hecho. Los pasos que funcionaba perfectamente bien para mí:

  1. Crear una nueva aplicación ASP.NET MVC 3 utilizando la plantilla predeterminada de Visual Studio
  2. Añadir un área llamada Admin utilizando el diseñador de Visual Studio haciendo clic derecho sobre el proyecto
  3. Añadir nuevo controlador de ~/Areas/Admin/Controllers/MeetsController:

    public class MeetsController : Controller 
    { 
        public ActionResult Index() 
        { 
         return View(); 
        } 
    } 
    
  4. Añadir una vista correspondiente ~/Areas/Admin/Views/Meets/Index.cshtml

  5. En la disposición (~/Views/Shared/_Layout.cshtml) añadir enlaces:

    @Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null) 
    @Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null) 
    
  6. ejecutar la aplicación.

HTML representada por las anclas:

<a href="/Admin/Meets">Admin</a> 
<a href="/Meets">Admin</a> 

Como era de esperar los primeros trabajos de enlace mientras que el segundo no lo hace.

¿Cuál es la diferencia con su configuración?

+0

No hay un controlador "Admin" para el área ""; en su caso, ha creado un área nueva "Admin" con un "MeetsController" y, por lo tanto, el primer enlace debería funcionar según lo previsto. Si realmente desea que el controlador del área "Administrador" ejecute "en cualquier lugar" puede intentar mover todas las vistas, parciales, etc. del área "Administrador" y en la raíz de su aplicación web. No estoy seguro de qué tan bien (si) esto funcionaría. –

3

Compruebe que su clase AdminAreaRegistration se ve así:

public class AdminAreaRegistration : AreaRegistration 
{ 
    public override string AreaName 
    { 
     get 
     { 
      return "Admin"; 
     } 
    } 

    public override void RegisterArea(AreaRegistrationContext context) 
    { 
     context.MapRoute(
      "Admin_default", 
      "Admin/{controller}/{action}/{id}", 
      new { action = "Index", id = UrlParameter.Optional } 
     ); 
    } 
} 

y que tiene esto en Global.asax.cs:

protected void Application_Start() 
{ 
    ... // ViewEngine Registration 
    AreaRegistration.RegisterAllAreas(); 
    ... // Other route registration 
} 
2

He resuelto este problema haciendo lo siguiente.

En mis Global.asax.cs, tengo

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
    } 

    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
     routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" }); 
    } 

    protected void Application_Start() 
    { 
     //Initialise IoC 
     IoC.Initialise(); 

     AreaRegistration.RegisterAllAreas(); 
     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 
    } 

En mis PublicAreaRegistration.cs (área pública), tengo

public class PublicAreaRegistration : AreaRegistration 
{ 
    public override string AreaName 
    { 
     get 
     { 
      return "Public"; 
     } 
    } 

    public override void RegisterArea(AreaRegistrationContext context) 
    { 
     context.MapRoute("Root", "", new { controller = "Home", action = "Index" }); 

     context.MapRoute(
      "Public_default", 
      "Public/{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      , new[] { "<Project Namespace here>.Areas.Public.Controllers" } 
     ); 
    } 
} 

En mis AuthAreaRegistration.cs (Area de El acceso restringido), tengo

public class AuthAreaRegistration : AreaRegistration 
{ 
    public override string AreaName 
    { 
     get 
     { 
      return "Auth"; 
     } 
    } 

    public override void RegisterArea(AreaRegistrationContext context) 
    { 
     context.MapRoute(
      "Auth_default", 
      "Auth/{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 
    } 
} 

Y, por último, mis enlaces en mis páginas .cshtml * sería como

1) @ Html.ActionLink ("Cerrar sesión", "desconexión", la nueva área de {= "Público", el controlador = "Inicio"})

o

2) @ Html.ActionLink ("Área de administración", "Índice", nuevo {area = "Auth", controller = "Home"})

¡Espero que esto le ahorre a alguien horas de investigación! Por cierto, estoy hablando de MVC3 aquí.

Kwex.

+0

Una nota para los lectores, los ejemplos de ActionLink aquí producirían el mismo problema que el OP, a pesar de los otros cambios, deberían escribirse de la siguiente manera: 1) @ Html.ActionLink ("Cerrar sesión", "LogOff" , nuevo {area = "Public", controller = "Home"}, nulo) o 2) @ Html.ActionLink ("Área de administración", "Índice", nuevo {area = "Auth", controller = " Inicio "}, nulo) –

28

Otra opción es utilizar RouteLink() en lugar de ActionLink(), que no pasa por los registros de área en total:

ActionLink Versión:

versión
Html.ActionLink("Log Off", "LogOff", "Account", new { area = "" }, null) 

RouteLink:

Html.RouteLink("Log Off", "Default", 
    new { action = "LogOff", controller = "Account" }) 

El El segundo parámetro es un "Nombre de ruta" que está registrado en Global.asax.cs y en varias subclases 'Registro de área'. Para usar 'RouteLink' para vincular las diferentes áreas, solo necesita especificar el nombre de la ruta correcta.

Este ejemplo siguiente muestra cómo iba a generar tres enlaces a diferentes zonas de una compartida parcial, que funciona correctamente, independientemente de la zona en la que estoy 'en' (si los hay):

@Html.RouteLink("Blog", "Blog_default", 
    new { action = "Index", controller = "Article" }) 
<br/> 
@Html.RouteLink("Downloads", "Download_default", 
    new { action = "Index", controller = "Download" }) 
<br/> 
@Html.RouteLink("About", "Default", 
    new { action = "Index", controller = "About" }) 

de codificación feliz!

1

Puede que este no sea el caso para la mayoría de los desarrolladores, pero encontré este problema cuando agregué una de mis primeras áreas y no construí mi solución. Tan pronto como construí mi solución, los enlaces comenzaron a poblarse correctamente.

Cuestiones relacionadas