web-development-kb-es.site

Pasando datos a la página maestra en ASP.NET MVC

¿Cuál es su forma de pasar datos a la página maestra (usando ASP.NET MVC) sin romper las reglas de MVC?

Personalmente, prefiero codificar el controlador abstracto (controlador base) o la clase base que se pasa a todas las vistas.

102
Łukasz Sowa

Si prefiere que sus vistas tengan clases de datos de vista fuertemente escritas, esto podría funcionar para usted. Otras soluciones son probablemente más correctas pero este es un buen equilibrio entre diseño y practicidad IMHO.

La página maestra toma una clase de datos de vista fuertemente tipada que contiene solo información relevante para ella:

public class MasterViewData
{
    public ICollection<string> Navigation { get; set; }
}

Cada vista que usa esa página maestra toma una clase de datos de vista fuertemente tipada que contiene su información y que deriva de los datos de vista de las páginas maestras:

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
}

Como no quiero que los controladores individuales sepan nada sobre la recopilación de los datos de las páginas maestras, encapsulo esa lógica en una fábrica que se pasa a cada controlador:

public interface IViewDataFactory
{
    T Create<T>()
        where T : MasterViewData, new()
}

public class ProductController : Controller
{
    public ProductController(IViewDataFactory viewDataFactory)
    ...

    public ActionResult Index()
    {
        var viewData = viewDataFactory.Create<ProductViewData>();

        viewData.Name = "My product";
        viewData.Price = 9.95;

        return View("Index", viewData);
    }
}

La herencia coincide con el maestro para ver bien la relación, pero cuando se trata de representar parciales/controles de usuario, componeré sus datos de vista en los datos de vista de páginas, por ejemplo.

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
    public SubViewData SubViewData { get; set; }
}

<% Html.RenderPartial("Sub", Model.SubViewData); %>

Este es solo un código de ejemplo y no está diseñado para compilarse como está. Diseñado para ASP.Net MVC 1.0.

77
Generic Error

Prefiero dividir las partes controladas por datos de la vista maestra en parciales y renderizarlas usando Html.RenderAction . Esto tiene varias ventajas distintas sobre el enfoque de herencia del modelo de vista popular:

  1. Los datos de la vista maestra están completamente desacoplados de los modelos de vista "normales". Esta es la composición sobre la herencia y da como resultado un sistema acoplado más holgado que es más fácil de cambiar.
  2. Los modelos de vista maestra están construidos por una acción de controlador completamente separada. Las acciones "regulares" no tienen que preocuparse por esto, y no hay necesidad de una fábrica de datos de visualización, lo que parece demasiado complicado para mi gusto.
  3. Si utiliza una herramienta como AutoMapper para asignar su dominio a sus modelos de vista, le resultará más fácil de configurar porque sus modelos de vista se parecerán más a sus modelos de dominio cuando no heredan los datos de vista maestra .
  4. Con métodos de acción separados para datos maestros, puede aplicar fácilmente el almacenamiento en caché de resultados a ciertas regiones de la página. Normalmente, las vistas maestras contienen datos que cambian con menos frecuencia que el contenido de la página principal.
59
Todd Menier

EDITAR

Error genérico ha proporcionado una mejor respuesta a continuación. ¡Por favor leelo!

Respuesta original

Microsoft ha publicado una entrada en la forma "oficial" para manejar esto. Esto proporciona un recorrido paso a paso con una explicación de su razonamiento.

En resumen, recomiendan usar una clase de controlador abstracta, pero véanlo usted mismo.

20
Michael La Voie

Los controladores abstractos son una buena idea, y no he encontrado una mejor manera. También me interesa ver lo que otras personas han hecho.

7
Ian P
3
David Negron

Encuentro que un padre común para todos los objetos modelo que pase a la vista es excepcionalmente útil.

De todos modos, siempre habrá algunas propiedades comunes de modelo entre las páginas.

2
Matt Mitchell

Creo que otra buena manera podría ser crear una Interfaz para ver con alguna Propiedad como ParentView de alguna interfaz, de modo que pueda usarla tanto para los controles que necesitan una referencia a la página (control principal) como para las vistas maestras a las que se debe acceder puntos de vista.

0
dimarzionist

Las otras soluciones carecen de elegancia y tardan demasiado. Me disculpo por hacer esta cosa muy triste y empobrecida casi un año después:

<script runat="server" type="text/C#">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        MasterModel = SiteMasterViewData.Get(this.Context);
    }

    protected SiteMasterViewData MasterModel;
</script>

Claramente tengo este método estático Get () en SiteMasterViewData que devuelve SiteMasterViewData.

0
rasx

El objeto Request.Params es mutable. Es muy fácil agregarle valores escalares como parte del ciclo de procesamiento de la solicitud. Desde la perspectiva de la vista, esa información podría haber sido proporcionada en QueryString o FORM POST. hth

0
mtutty