mvc 3-在局部视图中修改MVC 3 ViewBag不会保留到_Layout.cshtml
我在Razor视图引擎中使用了MVC 3。 我想在局部视图的ViewBag中设置一些值,并想在_Layout.cshtml中检索这些值。 例如,当您设置默认的 MVC 3项目时,会在“ / Views / Shared”文件夹中获得_Layout.cshtml文件。 在_Layout.cshtml中,页面标题设置如下:
@ViewBag.PageTitle
然后在“ /Views/Home/About.cshtml”视图中,修改ViewBag的内容:
@{
ViewBag.Title = "About Us";
}
这很好。 呈现“关于”视图时,页面标题为“关于我们”。 因此,现在我想在About视图中渲染一个Partial视图,并在Partial视图中修改ViewBag.Title。 (“ /Views/Shared/SomePartial.cshtml”)
@Html.Partial("SomePartial")
在此部分视图中,我有以下代码:
@{
ViewBag.Title = "About Us From The Partial View";
}
当我调试此代码时,我看到ViewBag.Title设置为“关于我们”,然后在部分视图中看到它被重置为“关于我们从部分视图”,但是当代码到达_Layout.cshtml时,它将 回到“关于我们”。
这是否意味着如果在部分视图中修改了ViewBag的内容,这些更改将不会出现(可访问)在主视图(About.cshtml)或_Layout.cshtml中?
提前致谢!
10个解决方案
31 votes
如果将ViewBag传递到局部的viewdatadictionary中,然后将其拉出(并强制转换),则可以执行所需的任何操作,并保留引用。 最酷的部分是,由于它是动态的,因此您甚至可以添加属性,然后它们将显示在父页面的Viewbag中。
页:
//set the viewbag into the partial's view data
@{Html.RenderPartial("Elaborate", Model, new ViewDataDictionary { {"vb", ViewBag}});}
部分:
@{
var vb = ((dynamic)ViewData["vb"]);
vb.TheTitle = "New values";
}
页
@ViewBag.TheTitle = "New value"
Tony Basallo answered -08-01T15:01:46Z
12 votes
我也遇到了这个问题,找不到任何整洁而明显的解决方案。
我想到的解决方案是实现一个Html扩展方法,该方法返回您定义的'PageData'类,其中包含所需的任何数据:
[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;
}
}
它找到当前请求的顶级控制器,并在同一HTTP请求中每次调用该方法时都返回相同的PageData对象。 第一次在新的HTTP请求中调用它时,它将创建一个新的PageData对象。
Chris answered -08-01T15:01:12Z
8 votes
部分视图拥有自己的ViewBag。
您可以从((WebViewPage) WebPageContext.Current.Page).ViewBag获取页面的ViewBag
SLaks answered -08-01T15:02:10Z
7 votes
您可以在部分视图中完成此技巧,以覆盖_Layout.cshtml中的标题:
@{
ViewBag.Title = "About Us From The Partial View";
}
......
document.title = "@ViewBag.Title";
marianotigre answered -08-01T15:02:30Z
4 votes
正如其他人指出的,“布局”,“视图”和“部分视图”都有自己的ViewBag。 但是,我能够使其与以下产品一起使用:在视图或局部视图中。
@{ Html.ViewContext.ViewBag.Title = "Reusable Global Variable"; }
然后在_Layout中
@ Html.ViewContext.ViewBag.Title
通过显式使用ViewContext,视图可以“重用”相同的ViewBag。
Dax70 answered -08-01T15:03:03Z
1 votes
我尝试了以下方法,它可以工作:
在(父)视图中...
@Html.Partial("SomePartial", ViewData, null)
注意:将model作为model参数传递,但是必须为viewData参数指定null,才能使用正确的重载。 您不能使用ViewBag,因为Html.Partial不喜欢动态。
然后,在局部视图中...
@model ViewDataDictionary
@{
Model["Title"] = "About us from the partial view";
}
当然,如果您需要将model参数用于真实模型,则必须更具创造力。
Oundless answered -08-01T15:03:41Z
1 votes
尝试使用@SLaks代码
(((WebViewPage) WebPageContext.Current.Page).ViewBag).PropertyName
killebytes answered -08-01T15:04:01Z
0 votes
如果有人仍在寻找解决方案,看来可以使用TempData来解决:
TempData["x"] = x;
TempData一直保留到读取为止,因此您可以在_Layout中读取它。 您只需要注意阅读所有内容,以便在下一个请求时将其清除。
chris answered -08-01T15:04:26Z
-1 votes
使用mvc3时遇到相同的问题,发现
this.ViewBag.ViewBag.PropertyName
在您的自定义控件中工作。
herui answered -08-01T15:04:50Z
-1 votes
我这是页面数据设计的目的。 将其弹出您的视图。
@Page.somePropertyName = "Whatever you want";
然后在布局视图中访问它。 请务必先检查其是否不为null。
@{
if(Page.somePropertyName != null)
{
//Do stuff
}
}
Matt answered -08-01T15:05:14Z