[asp.net-mvc-4] Pasar datos al diseño que son comunes a todas las páginas


Answers

Utilicé RenderAction html helper para la maquinilla de afeitar en el diseño.

@{
   Html.RenderAction("Action", "Controller");
 }

Lo necesitaba para una cadena simple. Entonces mi acción devuelve una cadena y la escribe fácilmente a la vista. Pero si necesita datos complejos, puede devolver PartialViewResult y modelar.

 public PartialViewResult Action()
    {
        var model = someList;
        return PartialView("~/Views/Shared/_maPartialView.cshtml", model);
    }

Solo debe poner su modelo comenzando con la vista parcial '_maPartialView.cshtml' que creó

@model List<WhatEverYourObjeIs>

Luego puede usar datos en el modelo en esa vista parcial con html.

Question

Tengo un sitio web que tiene una página de diseño. Sin embargo, esta página de diseño tiene datos que el modelo de todas las páginas debe proporcionar el título de la página, el nombre de la página y la ubicación en la que realmente estamos para una ayuda HTML que realicé y que realiza alguna acción. Además, cada página tiene sus propias propiedades de modelos de vista.

¿Cómo puedo hacer esto? Parece que es una mala idea escribir un diseño, pero ¿cómo paso las informaciones de tesis?




en lugar de pasar por esto siempre puedes usar otro enfoque que también es rápido

cree una nueva vista parcial en el Directorio compartido y llame a su vista parcial en su diseño como

@Html.Partial("MyPartialView")

en su vista parcial puede llamar a su base de datos y realizar lo que quiera hacer

@{
    IEnumerable<HOXAT.Models.CourseCategory> categories = new HOXAT.Models.HOXATEntities().CourseCategories;
}

<div>
//do what ever here
</div>

asumiendo que ha agregado su base de datos de Entity Framework




Crear una vista base que represente el modelo de vista Diseño es un enfoque terrible. Imagine que desea tener un modelo que represente la navegación definida en el diseño. ¿Haría CustomersViewModel : LayoutNavigationViewModel ? ¿Por qué? ¿Por qué debería pasar los datos del modelo de navegación a través de cada modelo de vista que tiene en la solución?

El modelo de vista Diseño debe ser exclusivo, y no debe obligar al resto de los modelos de visualización a depender de él.

En cambio, puede hacer esto en su archivo _Layout.cshtml :

@{ var model = DependencyResolver.Current.GetService<MyNamespace.LayoutViewModel>(); }

Lo más importante es que no necesitamos un new LayoutViewModel() y obtendremos todas las dependencias que LayoutViewModel tiene, resueltas para nosotros.

p.ej

public class LayoutViewModel
{
    private readonly DataContext dataContext;
    private readonly ApplicationUserManager userManager;

    public LayoutViewModel(DataContext dataContext, ApplicationUserManager userManager)
    {
    }
}



si quieres pasar un modelo completo, ve así en el diseño:

@model ViewAsModelBase
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="utf-8"/>
    <link href="/img/phytech_icon.ico" rel="shortcut icon" type="image/x-icon" />
    <title>@ViewBag.Title</title>
    @RenderSection("styles", required: false)    
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
    @RenderSection("scripts", required: false)
    @RenderSection("head", required: false)
</head>
<body>
    @Html.Action("_Header","Controller", new {model = Model})
    <section id="content">
        @RenderBody()
    </section>      
    @RenderSection("footer", required: false)
</body>
</html>

y agregue esto en el controlador:

public ActionResult _Header(ViewAsModelBase model)



Presumiblemente, el caso de uso primario para esto es obtener un modelo base para la vista para todas (o la mayoría de) las acciones del controlador.

Dado eso, he usado una combinación de varias de estas respuestas, respaldo primario en la respuesta de Colin Bacon.

Es correcto que sigue siendo lógica de controlador porque estamos rellenando un modelo de vista para volver a una vista. Por lo tanto, el lugar correcto para poner esto es en el controlador.

Queremos que esto suceda en todos los controladores porque lo usamos para la página de diseño. Lo estoy usando para vistas parciales que se muestran en la página de diseño.

También queremos el beneficio adicional de un modelo de vista fuertemente tipificado

Por lo tanto, he creado un BaseViewModel y BaseController. Todos los controladores ViewModels heredarán de BaseViewModel y BaseController, respectivamente.

El código:

BaseController

public class BaseController : Controller
{
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        var model = filterContext.Controller.ViewData.Model as BaseViewModel;

        model.AwesomeModelProperty = "Awesome Property Value";
        model.FooterModel = this.getFooterModel();
    }

    protected FooterModel getFooterModel()
    {
        FooterModel model = new FooterModel();
        model.FooterModelProperty = "OMG Becky!!! Another Awesome Property!";
    }
}

Tenga en cuenta el uso de OnActionExecuted como tomado de esta publicación SO

HomeController

public class HomeController : BaseController
{
    public ActionResult Index(string id)
    {
        HomeIndexModel model = new HomeIndexModel();

        // populate HomeIndexModel ...

        return View(model);
    }
}

BaseViewModel

public class BaseViewModel
{
    public string AwesomeModelProperty { get; set; }
    public FooterModel FooterModel { get; set; }
}

HomeViewModel

public class HomeIndexModel : BaseViewModel
{

    public string FirstName { get; set; }

    // other awesome properties
}

FooterModel

public class FooterModel
{
    public string FooterModelProperty { get; set; }
}

Layout.cshtml

@model WebSite.Models.BaseViewModel
<!DOCTYPE html>
<html>
<head>
    < ... meta tags and styles and whatnot ... >
</head>
<body>
    <header>
        @{ Html.RenderPartial("_Nav", Model.FooterModel.FooterModelProperty);}
    </header>

    <main>
        <div class="container">
            @RenderBody()
        </div>

        @{ Html.RenderPartial("_AnotherPartial", Model); }
        @{ Html.RenderPartial("_Contact"); }
    </main>

    <footer>
        @{ Html.RenderPartial("_Footer", Model.FooterModel); }
    </footer>

    < ... render scripts ... >

    @RenderSection("scripts", required: false)
</body>
</html>

_Nav.cshtml

@model string
<nav>
    <ul>
        <li>
            <a href="@Model" target="_blank">Mind Blown!</a>
        </li>
    </ul>
</nav>

Espero que esto ayude.




Related