Cómo crear un establecimiento inflexible de tipos de página maestra en el uso de un controlador de base en ASP.NET MVC
-
12-09-2019 - |
Pregunta
El siguiente NerdDinners ejemplo, estoy interesado en la creación de un establecimiento inflexible de tipos de Página Maestra.Para lograr esto, yo uso un controlador de base que recupera los datos de la página maestra.Todos los otros controladores de heredar de esta clase.Del mismo modo, he ViewModels
para la página principal y otras opiniones.La vista ViewModel
las clases heredan de la página principal ViewModel
.
Pregunta
¿Cómo debe un niño controlador de asegurarse de que la página principal se pasan los datos a la Vista sin necesidad de configuración de las propiedades de sus ViewModel
que pertenecen a la página principal de la misma?
A mi la página principal mostrará un número de botones, los cuales son determinados en un archivo XML, por lo tanto el Buttons
la clase que estoy rellenar.
MasterPage ViewModel Fragmento De Código
using System.Collections.Generic;
namespace Site1.Models
{
public class MasterViewModel
{
public List<Button> Buttons{set; get;}
}
}
Ver ViewModel
namespace Site1.Models
{
public class View1ViewModel : MasterViewModel
{
public SomeDataClass SomeData { get; set; }
}
}
Controlador De La Base
using System.Collections.Generic;
using System.Web.Mvc;
using Site1.Models;
namespace Site1.Controllers
{
public abstract class BaseController : Controller
{
protected MasterViewModel model = new MasterViewModel();
public BaseController()
{
model.Buttons = new List<Button>();
//populate the button classes (doesn't matter how)
PopulateButtons(model.Buttons);
}
}
}
Vista del controlador:
using System.Web.Mvc;
namespace Site1.Controllers
{
public class View1Controller : BaseController
{
public ActionResult Index()
{
Models.View1ViewModel viewModel = new Models.View1ViewModel();
SomeDataClass viewData = new SomeDataClass()
//populate data class (doesn't matter how)
PopulateDataClass(viewData);
viewModel.SomeData = viewData;
//I WANT TO ELIMINATE THE FOLLOWING LINE!
viewModel.Buttons = model.Buttons;
return View("Index", viewModel);
}
}
}
La página principal hereda System.Web.Mvc.ViewMasterPage<Site1.Models.MasterViewModel>
.
La vista hereda System.Web.Mvc.ViewMasterPage<Site1.Models.View1ViewModel>
.
Solución
Se puede crear un filtro de acción ejecutada después de lo cual se ve un modelo de ese tipo y establece las propiedades en consecuencia, tal vez llamando a una función de controlador base. A continuación, poner el filtro en la clase base, y todas las acciones que se vería automáticamente.
El atributo filtro acción consigue ViewModel
del controlador, y lo pasa a la función SetModel
del controlador:
using System.Web.Mvc;
using Site1.Controllers;
namespace Site1.Models
{
public class MasterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
MasterViewModel viewModel = (MasterViewModel)((ViewResultBase)filterContext.Result).ViewData.Model;
BaseController controller = (BaseController)filterContext.Controller;
controller.SetModel(viewModel);
}
}
}
se añade esta función a la BaseController
:
public void SetModel(MasterViewModel childViewModel)
{
childViewModel.Buttons = model.Buttons;
}
Otros consejos
En lugar de crear un atributo, ¿por qué no anular Controller.OnActionExecuted y poner el código de inicialización allí? Parece un poco más simple.