2009-06-10 19 views
28

Estoy usando una página maestra en mi proyecto ASP.NET MVC. Esta página maestra espera que algunos ViewData estén presentes, lo que se muestra en cada página.ASP.NET MVC - Establecer ViewData para la página maestra en el controlador base

Si no configuro esta clave ViewData en mis controladores, aparece un error que no puede encontrarla. Sin embargo, no quiero configurar ViewData en cada controlador (no quiero decir ViewData["foo"] = GetFoo(); en cada controlador).

Por lo tanto, estaba pensando en configurar esto en un controlador base y que cada controlador herede de este controlador base. En la construcción predeterminada del controlador base, configuro ViewData. Encontré un enfoque similar aquí: http://www.asp.net/learn/MVC/tutorial-13-cs.aspx. Hasta ahora todo bien, esto funciona ... pero el problema es que estos datos provienen de una base de datos en alguna parte.

Ahora, cuando quiero probar la unidad de mis controladores, los que heredan del controlador base llaman a su constructor predeterminado. En el constructor predeterminado, inicializo mi clase de repositorio para obtener estos datos de la base de datos. Resultado: mis pruebas de unidad fallan, ya que no puede acceder a los datos (y ciertamente no los quieren para acceder a estos datos).

Tampoco quiero pasar la clase correcta de Repositorio (o DataContext, como lo llame) a cada controlador que a su vez la pase al controlador predeterminado, que luego podría simular con mis pruebas unitarias. Los controladores a su vez dependen de otras clases de repositorio, y yo terminaría pasando múltiples parámetros al constructor. Demasiado trabajo para mi sentimiento, ¿o estoy equivocado? ¿Hay alguna otra solución?

He intentado usar StructureMap pero al final no sentí que eso vaya a solucionar mi problema, ya que cada controlador tendrá que llamar al constructor base que inicializará la clase del repositorio, así que puedo ' t se burla.

This es una pregunta similar pero no encuentro una respuesta satisfactoria. ¿Puedo resolver esto de una manera ordenada, tal vez usando StructureMap como solución? ¿O debería simplemente chuparlo y pasar un repositorio a cada controlador y pasarlo de nuevo al controlador base? De nuevo, parece que hay tanto trabajo para algo tan simple. ¡Gracias!

Respuesta

45

veo dos opciones:

Primero:

Ajuste el ViewData para MasterPage en YourBaseController.OnActionExecuting() o YourBaseController.OnActionExecuted():

public class YourBaseController : Controller 
{ 
    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // Optional: Work only for GET request 
     if (filterContext.RequestContext.HttpContext.Request.RequestType != "GET") 
      return; 

     // Optional: Do not work with AjaxRequests 
     if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) 
      return; 

     ... 

     filterContext.Controller.ViewData["foo"] = ... 
    } 
} 

Segundo:

O crear filtro personalizado:

public class DataForMasterPageAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // Optional: Work only for GET request 
     if (filterContext.RequestContext.HttpContext.Request.RequestType != "GET") 
      return; 

     // Optional: Do not work with AjaxRequests 
     if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) 
      return; 

     ... 

     filterContext.Controller.ViewData["foo"] = ... 
    } 
} 

y luego se aplican a los controladores:

[DataForMasterPage] 
public class YourController : YourBaseController 
{ 
    ... 
} 

creo que la segunda solución es exactamente para su caso.

+1

hmm, que parece prometedor. Estoy en casa ahora, así que probaré esto mañana, aunque creo que el segundo va a funcionar (manteniendo los dedos cruzados, ya pasó demasiadas horas intentando todo tipo de cosas). Me gusta el estilo de AOP. – Razzie

+0

Estoy usando la segunda solución en mis proyectos y funciona sin problemas –

+0

Esto lo hizo por mí. ¡Gracias! – Razzie

Cuestiones relacionadas