Tengo un sitio web que tiene una página de diseño. Sin embargo, esta página de diseño tiene datos que todos los modelos de páginas deben proporcionar, como el título de la página, el nombre de la página y la ubicación en la que realmente estamos para un ayudante HTML que realicé y que realizó 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 estas informaciones?
asp.net-mvc-4
Rushino
fuente
fuente
ViewBag
. Quizás una cuestión de preferencias. Sin embargo, votó por su comentarioRespuestas:
Si se le requiere que pase las mismas propiedades a cada página, sería inteligente crear un modelo de vista base que sea utilizado por todos sus modelos de vista. Su página de diseño puede tomar este modelo base.
Si se requiere lógica detrás de estos datos, esto se debe poner en un controlador base que sea utilizado por todos sus controladores.
Hay muchas cosas que puede hacer, el enfoque importante es no repetir el mismo código en varios lugares.
Editar: actualización de los comentarios a continuación
Aquí hay un ejemplo simple para demostrar el concepto.
Cree un modelo de vista base del que todos los modelos de vista heredarán.
Su página de diseño puede tomar esto como su modelo.
Finalmente establezca los datos en el método de acción.
fuente
public class HomeController : BaseController
. De esta manera, el código común solo necesita escribirse una vez y puede aplicarse a todos los controladores.Utilicé RenderAction html helper para la maquinilla de afeitar en el diseño.
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 model.
Solo necesita poner su modelo a partir de la vista parcial '_maPartialView.cshtml' que creó
Luego puede usar datos en el modelo en esa vista parcial con html.
fuente
Otra opción es crear una clase LayoutModel separada con todas las propiedades que necesitará en el diseño y luego insertar una instancia de esta clase en ViewBag. Yo uso el método Controller.OnActionExecuting para llenarlo. Luego, al comienzo del diseño, puede extraer este objeto de ViewBag y continuar accediendo a este objeto fuertemente tipado.
fuente
OnActionExecuting
. El uso de ViewBag también significa que pierde seguridad de tipo en su controlador, lo que nunca es bueno.Presumiblemente, el caso de uso principal para esto es obtener un modelo base para la vista de todas (o la mayoría de) las acciones del controlador.
Teniendo en cuenta eso, he usado una combinación de varias de estas respuestas, respaldo primario en la respuesta de Colin Bacon.
Es correcto que esto siga siendo la lógica del controlador porque estamos completando 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 representan en la página de diseño.
También queremos el beneficio adicional de un ViewModel fuertemente tipado
Por lo tanto, he creado un BaseViewModel y BaseController. Todos los controladores ViewModels heredarán de BaseViewModel y BaseController respectivamente.
El código:
BaseController
Tenga en cuenta el uso de OnActionExecuted tomado de esta publicación SO
HomeController
BaseViewModel
HomeViewModel
Pie de página
Layout.cshtml
_Nav.cshtml
Espero que esto ayude.
fuente
No tiene que meterse con acciones o cambiar el modelo, solo use un controlador base y emita el controlador existente desde el contexto de la vista de diseño.
Cree un controlador base con los datos comunes deseados (título / página / ubicación, etc.) e inicialización de acciones ...
Asegúrese de que cada controlador use el controlador base ...
Transmita el controlador base existente desde el contexto de vista en su
_Layout.cshml
página ...Ahora puede consultar los valores en su controlador base desde su página de diseño.
ACTUALIZAR
También puede crear una extensión de página que le permita usar
this
.Entonces solo debe recordar usar
this.Controller()
cuando desee el controlador.o controlador específico que hereda de
_BaseController
...fuente
si desea pasar un modelo completo, vaya así en el diseño:
y agregue esto en el controlador:
fuente
No creo que ninguna de estas respuestas sea lo suficientemente flexible para una gran aplicación de nivel empresarial. No soy un fanático del uso excesivo de ViewBag, pero en este caso, por flexibilidad, haría una excepción. Esto es lo que haría ...
Debe tener un controlador base en todos sus controladores. Agregue sus datos de diseño OnActionExecuting en su controlador base (o OnActionExecuted si desea diferir eso) ...
Luego, en su _Layout.cshtml, extraiga su ViewModel de la ViewBag ...
O...
Hacer esto no interfiere con la codificación de los controladores de su página o los modelos de vista.
fuente
MyLayoutViewModel
creado dinámicamente, cómo puedo pasar algunos parámetros alOnActionExecuting
método?base.OnActionExecuting(filterContext)
tuOnActionExecuting
método !!!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. ¿Lo harías
CustomersViewModel : LayoutNavigationViewModel
? ¿Por qué? ¿Por qué debería pasar los datos del modelo de navegación a través de cada modelo de vista individual que tiene en la solución?El modelo de vista Diseño debe ser dedicado, por sí solo y no debe forzar al resto de los modelos de vista a depender de él.
En cambio, puede hacer esto, en su
_Layout.cshtml
archivo:Lo más importante, no necesitamos hacerlo
new LayoutViewModel()
y obtendremos todas las dependencias que seLayoutViewModel
hayan resuelto por nosotros.p.ej
fuente
Scoped
objeto de modelo de diseño en ASP..Net Core también.Otras respuestas han cubierto casi todo sobre cómo podemos pasar el modelo a nuestra página de diseño. Pero he encontrado una manera de usar la cual puede pasar variables a su página de diseño dinámicamente sin usar ningún modelo o vista parcial en su diseño. Digamos que tiene este modelo:
Y desea obtener ciudad y estado dinámicamente. Por ej.
en su index.cshtml puede poner estas dos variables en ViewBag
Y luego en tu layout.cshtml puedes acceder a esas variables de viewbag
fuente
Hay otra forma de manejar esto. Quizás no sea la forma más limpia desde el punto de vista arquitectónico, pero evita mucho dolor involucrado con las otras respuestas. Simplemente inyecte un servicio en el diseño de Razor y luego llame a un método que obtenga los datos necesarios:
Luego, más tarde en la vista de diseño:
Una vez más, no es limpio en términos de arquitectura (obviamente, el servicio no debe inyectarse directamente en la vista), pero hace el trabajo.
fuente
@inject
es la mejor solución, en mi opinión.También puede hacer uso de RenderSection , que le ayuda a inyectar sus
Model
datos en la_Layout
vista.Usted puede inyectar
View Model
datos,Json
,Script
,CSS
,HTML
etc.En este ejemplo, estoy inyectando
Json
de miIndex
vista aLayout
vista.Index.chtml
_Layout.cshtml
Esto elimina la necesidad de crear una Base separada
View Model
.La esperanza ayuda a alguien.
fuente
lo que hice es muy simple y funciona
Declare la propiedad estática en cualquier controlador o puede hacer una clase de datos con valores estáticos si lo desea así:
Los controladores pueden actualizar estos valores en función de las operaciones. luego puedes usarlos en tu _Diseño
En _layout.cshtml
fuente
¿Por qué nadie ha sugerido métodos de extensión en ViewData?
Opción 1
Me parece, con mucho, la solución menos intrusiva y más simple al problema. Sin cadenas codificadas. Sin restricciones impuestas. Sin codificación mágica. Sin código complejo
Establecer datos en la página
Opcion 2
Otra opción, facilitando la declaración de campo.
Establecer datos en la página. La declaración es más fácil que la primera opción, pero la sintaxis de uso es un poco más larga.
Opción # 3
Luego, puede combinar eso con devolver un solo objeto que contenga todos los campos relacionados con el diseño con sus valores predeterminados.
Establecer datos en la página
Esta tercera opción tiene varios beneficios y creo que es la mejor opción en la mayoría de los casos:
La declaración más simple de campos y valores predeterminados.
La sintaxis de uso más simple al configurar múltiples campos.
Permite configurar varios tipos de datos en ViewData (por ejemplo, Diseño, Encabezado, Navegación).
Permite código y lógica adicionales dentro de la clase LayoutData.
PD: No olvide agregar el espacio de nombres de ViewDataExtensions en _ViewImports.cshtml
fuente
Puede crear un archivo de afeitar en la carpeta App_Code y luego acceder a él desde sus páginas de vista.
Proyecto> Repositorio / IdentityRepository.cs
Proyecto> Código_aplicación / IdentityRepositoryViewFunctions.cshtml:
Proyecto> Vistas / Compartido / _Layout.cshtml (o cualquier otro archivo .cshtml)
fuente
en lugar de pasar por esto, siempre puedes usar otro enfoque que también sea rápido
cree una nueva vista parcial en el Directorio compartido y llame a su vista parcial en su diseño como
en su vista parcial, puede llamar a su base de datos y realizar lo que quiera hacer
suponiendo que haya agregado su base de datos de Entity Framework
fuente
Es increíble que nadie haya dicho esto aquí. Pasar un modelo de vista a través de un controlador base es un desastre. Estamos utilizando reclamos de los usuarios para pasar información a la página de diseño (por ejemplo, para mostrar los datos del usuario en la barra de navegación). Hay una ventaja más. Los datos se almacenan a través de cookies, por lo que no es necesario recuperar los datos en cada solicitud a través de parciales. Simplemente haga algunas "reclamaciones de identidad de la red asp" en Google.
fuente
Puedes usar así:
fuente