我正在使用带有Razor视图引擎的MVC 3。我想在部分视图中的ViewBag中设置一些值,并希望在_Layout.cshtml中检索这些值。例如,当您设置默认的ASP.NET MVC 3项目时,您将在“/ Views / Shared”文件夹中获得_Layout.cshtml文件。在_Layout.cshtml中,页面标题设置如下:
<title>@ViewBag.PageTitle</title>
然后在“/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设置为“关于我们”,然后在Partial视图中我看到它重置为“关于我们从部分视图”,但是当代码命中_Layout时。 cshtml它可以追溯到“关于我们”。
这是否意味着如果在部分视图中修改了ViewBag的内容,那么这些更改将不会在主视图(About.cshtml)或_Layout.cshtml中显示(可访问)?
提前致谢!
答案 0 :(得分:31)
如果您将ViewBag传递给partial的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"
答案 1 :(得分:12)
我也有这个问题,找不到任何简洁明了的解决方案。
我提出的解决方案是实现一个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对象。
答案 2 :(得分:8)
部分视图有自己的ViewBag
。
您可以从((WebViewPage) WebPageContext.Current.Page).ViewBag
答案 3 :(得分:8)
您可以在局部视图中执行此操作以覆盖_Layout.cshtml中的标题:
@{
ViewBag.Title = "About Us From The Partial View";
}
......
<script type="text/javascript">
document.title = "@ViewBag.Title";
</script>
答案 4 :(得分:4)
正如其他人指出布局,观看次数和部分获取他们自己的 ViewBag 。但是,我能够使用以下内容: 在视图或部分中。
@{ Html.ViewContext.ViewBag.Title = "Reusable Global Variable"; }
然后在_Layout
@ Html.ViewContext.ViewBag.Title
通过显式使用 ViewContext ,视图'重复使用'相同的ViewBag。
答案 5 :(得分:1)
使用
尝试@SLaks代码(((WebViewPage) WebPageContext.Current.Page).ViewBag).PropertyName
答案 6 :(得分:1)
我尝试了以下内容并且有效:
在(父)视图中......
@Html.Partial("SomePartial", ViewData, null)
注意:ViewData
作为model
参数传递,但您必须为null
参数指定viewData
才能使用正确的重载。您无法使用ViewBag
,因为Html.Partial
不喜欢动态。
然后,在局部视图中......
@model ViewDataDictionary
@{
Model["Title"] = "About us from the partial view";
}
当然,如果您需要将model
参数用于实际模型,则必须更具创造性。
答案 7 :(得分:0)
如果有人仍在寻找解决方案,那么看起来你可以使用TempData:
TempData["x"] = x;
TempData会一直存在,直到被读取为止,您只需在_Layout中读取即可。你必须要小心,你要读取所有内容,以便为下一个请求清除它。
答案 8 :(得分:-1)
当我使用mvc3时遇到了同样的问题,我发现了
this.ViewBag.ViewBag.PropertyName
适用于您的自定义控件。
答案 9 :(得分:-1)
我这是设计用于页面数据的内容。把它放到你的视野中。
@Page.somePropertyName = "Whatever you want";
然后在布局视图中访问它。请务必先检查它是否为空。
@{
if(Page.somePropertyName != null)
{
//Do stuff
}
}