what - La modificación de MVC 3 ViewBag en una vista parcial no persiste en_Layout.cshtml
viewdatadictionary partial view (10)
Como otros han señalado el diseño , las vistas y los parciales obtienen su propio ViewBag . Sin embargo, pude hacer que funcione con lo siguiente: en la Vista o Parcial.
@{ Html.ViewContext.ViewBag.Title = "Reusable Global Variable"; }
Luego en _Layout
@ Html.ViewContext.ViewBag.Title
Al usar explícitamente ViewContext , las vistas ''reutilizan'' el mismo ViewBag.
Estoy usando MVC 3 con el motor Razor view. Quiero establecer algunos valores en el ViewBag dentro de una Vista parcial y quiero recuperar esos valores en mi _Layout.cshtml. Por ejemplo, cuando configura un proyecto predeterminado de ASP.NET MVC 3, obtiene un archivo _Layout.cshtml en la carpeta "/ Vistas / Compartidas". En ese _Layout.cshtml, el título de la página se establece así:
<title>@ViewBag.PageTitle</title>
Luego, en "/Views/Home/About.cshtml" ver los contenidos del ViewBag se modifican:
@{
ViewBag.Title = "About Us";
}
Esto funciona bien Cuando se muestra la vista Acerca de, el título de la página es "Acerca de nosotros". Entonces, ahora quiero hacer una vista parcial dentro de mi vista Acerca de y quiero modificar el ViewBag.Title dentro de mi vista parcial. ("/Views/Shared/SomePartial.cshtml")
@Html.Partial("SomePartial")
En esta vista parcial tengo este código:
@{
ViewBag.Title = "About Us From The Partial View";
}
Cuando depuro este código veo que ViewBag.Title se establece en "About Us" y luego en la vista parcial veo que se restablece a "About Us from Partial View", pero cuando el código toca el _Layout.cshtml va volver a "Sobre nosotros".
¿Esto significa que si los contenidos de ViewBag se modifican en una vista parcial, esos cambios no aparecerán (serán accesibles) en la vista principal (About.cshtml) o en el _Layout.cshtml?
¡Gracias por adelantado!
Esto es para lo que los datos de la página están diseñados. Pop esto en su vista.
@Page.somePropertyName = "Whatever you want";
Y luego acceda a ella en su vista de diseño. Asegúrese de verificar que no sea nulo primero.
@{
if(Page.somePropertyName != null)
{
//Do stuff
}
}
He intentado lo siguiente y funciona:
En la vista (principal) ...
@Html.Partial("SomePartial", ViewData, null)
Nota: ViewData
se pasa como argumento del model
, pero debe especificar null
para que el argumento viewData
use la sobrecarga correcta. No puede usar ViewBag
porque a Html.Partial
no le gusta la dinámica.
Luego, en la vista parcial ...
@model ViewDataDictionary
@{
Model["Title"] = "About us from the partial view";
}
Por supuesto, si necesita usar el argumento del model
para un modelo real, tendrá que ser más creativo.
La vista parcial tiene su propio ViewBag
.
Puede obtener la ViewBag de la página desde ((WebViewPage) WebPageContext.Current.Page).ViewBag
Me encontré con el mismo problema cuando uso mvc3, y encontré que
this.ViewBag.ViewBag.PropertyName
funciona en tu control personalizado
Puede hacer este truco en su vista parcial para anular el título en su _Layout.cshtml:
@{
ViewBag.Title = "About Us From The Partial View";
}
......
<script type="text/javascript">
document.title = "@ViewBag.Title";
</script>
Si alguien todavía está buscando una solución para esto, parece que puede hacerlo con TempData:
TempData["x"] = x;
TempData se conserva hasta que se lee, por lo que puede leerlo en su _Layout. Solo debe tener cuidado de leer todo para que se borre para la próxima solicitud.
Si pasa el ViewBag a la vista de la vista del parcial, luego lo extrae (y lo echa), puede hacer lo que quiera y se guarda la referencia. Lo bueno es que, dado que es dinámico, incluso puedes agregar propiedades y luego aparecerán en Viewbag de la página principal.
Página:
//set the viewbag into the partial''s view data
@{Html.RenderPartial("Elaborate", Model, new ViewDataDictionary { {"vb", ViewBag}});}
Parcial:
@{
var vb = ((dynamic)ViewData["vb"]);
vb.TheTitle = "New values";
}
Página
@ViewBag.TheTitle = "New value"
También tuve este problema y no pude encontrar ninguna solución limpia y obvia.
La solución que se me ocurrió fue implementar un método de extensión Html que devuelve una clase ''PageData'' que usted define, que contiene los datos que necesita:
[ThreadStatic]
private static ControllerBase pageDataController;
[ThreadStatic]
private static PageData pageData;
public static PageData GetPageData(this HtmlHelper html) {
ControllerBase controller = html.ViewContext.Controller;
while (controller.ControllerContext.IsChildAction) {
controller = controller.ControllerContext.ParentActionViewContext.Controller;
}
if (pageDataController == controller) {
return pageData;
} else {
pageDataController = controller;
pageData = new PageData();
return pageData;
}
}
Encuentra el controlador de nivel superior para la solicitud actual y devuelve el mismo objeto PageData cada vez que se llama al método dentro de la misma solicitud HTTP. Crea un nuevo objeto PageData la primera vez que se llama en una nueva solicitud HTTP.
prueba el código @SLaks con
(((WebViewPage) WebPageContext.Current.Page).ViewBag).PropertyName