2011-06-07 9 views
11

En mi aplicación tengo información básica del usuario que debe mostrarse en cada página (nombre, perfil img). Por el momento, simplemente configuré el modelo en la página _Layout.cshtml para que sea una clase llamada ApplicationBaseModel y cualquier otro modelo de vista en toda la aplicación debe heredar de esta clase, y cada acción debe establecer los datos apropiados para el modelo base.La forma más elegante de garantizar la visualización de los datos del modelo para _Layout.cshtml

No me importa la herencia simple de esta manera, es el hecho de que en cada método de acción único debo recuperar los datos y almacenarlos en el modelo de vista. No es una solución muy elegante en mi opinión.

¿Alguien tiene alguna idea sobre otras formas de resolver este problema?

+0

¿Estás usando Razor? – mnemosyn

+0

Sí, estoy usando la afeitadora – jcvandan

+0

No importa ... He estado pensando en reemplazar el tipo base de la página (que es específico de la cuchilla), pero eso no resuelve tu problema * y * es complicado ... lo siento – mnemosyn

Respuesta

23

Crearía un BaseController que recupera los datos en la anulación Initialize() y lo establece en una propiedad ViewBag. Ahora obtenga cada Controlador que cree desde BaseController y en su diseño use la propiedad ViewBag para acceder a sus datos de usuario.

public class BaseController : Controller 
{ 
    protected override void Initialize(System.Web.Routing.RequestContext requestContext) 
    { 
     base.Initialize(requestContext); 

     // retireve data 
     var data = new ApplicationBaseModel(); 

     // set to viewbag 
     ViewBag.UserData = data; 
    } 
} 

De esta manera usted no tiene que derivar todos las clases del modelo de ApplicationBaseModel. Puede tener vistas fuertemente tipadas y, además, sus datos de usuario como una propiedad ViewBag.

+0

Nice compromiso, gracias. –

+0

Esto parece una solución decente. ¿Se llamará al 'BaseController.Initialize' para cada controlador que se derive de' BaseController' o se ejecutará solo una vez, al invocar una acción en el primer controlador que se deriva de 'BaseController'. En otras palabras, si tengo 3 controladores - 'HomeController',' AboutController', 'AccountsController', y un usuario accede a los 3 controlador de enlaces de la página, a la' BaseController' ser ejecutado 3 veces, o sólo una vez (por la vida útil de la aplicación hasta que se recicla el grupo de aplicaciones)? – Shiva

+0

@Shiva: Es un método de instancia, por lo que se ejecutará para cada instancia de controlador e incluso en cada solicitud, antes de se llaman cualesquiera métodos ActionResult. Lo que describa con el ciclo de vida del conjunto de aplicaciones se aplicará a los métodos estáticos. – DanielB

3

Dependiendo de cuándo desee generar los datos de ViewBag, también podría usar las funciones OnActionExecuting o OnActionExecuted. Esto podría ser más adecuado porque algunos datos podrían no estar disponibles en el momento en que se creó el Controlador.

public class MyController : Controller 
{ 
    //Executes before every action 
    protected override void OnActionExecuting(ActionExecutedContext context) 
    { 
     //Call the method from the base class 
     base.OnActionExecuting(context); 

     //Create the ViewBag data here 
     ViewBag.XYZ = XYZ(); 
    } 

    //Executes after every action 
    protected override void OnActionExecuted(ActionExecutedContext context) 
    { 
     //Call the method from the base class 
     base.OnActionExecuted(context); 

     //Create the ViewBag data here 
     ViewBag.XYZ = XYZ(); 

    } 
} 
+1

+1 sin embargo, mis datos estarán disponibles en la creación de objetos – jcvandan

1

Otra opción sería arrancar las partes de la vista de diseño que requieren datos y colocarlas en parciales. Luego, desde su vista de diseño, realice una llamada Html.Action a las acciones que devuelvan esos parciales con los datos de viewmodel necesarios.

Cuestiones relacionadas