Cómo crear un establecimiento inflexible de tipos de página maestra en el uso de un controlador de base en ASP.NET MVC

StackOverflow https://stackoverflow.com/questions/768236

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>.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top