在部分视图中修改MVC 3 ViewBag不会保留到_Layout.cshtml

我正在使用MVC 3与Razor视图引擎。 我想在部分视图中的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"; } 

这工作正常。 关于视图呈现时,页面标题是“关于我们”。 所以,现在我想在我的关于视图中呈现一个部分视图,我想修改我的部分视图中的ViewBag.Title。 ( “/Views/Shared/SomePartial.cshtml”)

 @Html.Partial("SomePartial") 

在这个部分视图中,我有这样的代码:

 @{ ViewBag.Title = "About Us From The Partial View"; } 

当我debugging这段代码,我看到ViewBag.Title设置为“关于我们”,然后在部分视图,我看到它重置为“关于我们从部分视图”,但是当代码命中_Layout.cshtml它去回到“关于我们”。

这是否意味着如果在部分视图中修改了ViewBag的内容,那么在主视图(About.cshtml)或_Layout.cshtml中不会显示(可访问)这些更改?

提前致谢!

我也有这个问题,找不到任何简洁明了的解决办法。

我想出的解决scheme是实现一个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; } } 

它find当前请求的顶级控制器,并且每次在相同的HTTP请求中调用该方法时返回相同的PageData对象。 它会在第一次在新的HTTP请求中调用它时创build一个新的PageData对象。

如果您将ViewBag传递到partial的viewdatadictionary中,然后将其拉出(并投射),则可以执行任何您想要的操作并保留该引用。 很酷的部分是,因为它是dynamic的,你甚至可以添加属性,然后他们会显示在父页面的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" 

局部视图获取自己的ViewBag

您可以从((WebViewPage) WebPageContext.Current.Page).ViewBag获取页面的ViewBag ((WebViewPage) WebPageContext.Current.Page).ViewBag

你可以在你的局部视图中使用这个技巧来覆盖_Layout.cshtml中的标题:

 @{ ViewBag.Title = "About Us From The Partial View"; } ...... <script type="text/javascript"> document.title = "@ViewBag.Title"; </script> 

正如其他人指出布局视图部分获得自己的ViewBag 。 但是,我能够得到它与以下工作:在视图或部分。

 @{ Html.ViewContext.ViewBag.Title = "Reusable Global Variable"; } 

然后在_Layout

@ Html.ViewContext.ViewBag.Title

通过显式使用ViewContext ,视图'重新使用'相同的ViewBag。

我已经尝试了以下,它的工作原理:

在(父)视图中…

 @Html.Partial("SomePartial", ViewData, null) 

注意: ViewData作为modelparameter passing,但是您必须为viewData参数指定null以使用正确的重载。 您不能使用ViewBag因为Html.Partial不喜欢dynamic。

然后,在局部视图中…

 @model ViewDataDictionary @{ Model["Title"] = "About us from the partial view"; } 

当然,如果您需要将model参数用于真实模型,则必须具有更高的创造性。

尝试使用@SLaks代码

 (((WebViewPage) WebPageContext.Current.Page).ViewBag).PropertyName 

如果有人仍然在寻找解决scheme,看起来你可以用TempData做到这一点:

 TempData["x"] = x; 

TempData被保存直到它被读取,所以你可以在_Layout中读取它。 你只需要小心,你读了一切,以便下一个请求被清除。

我使用mvc3的时候遇到了同样的问题,我发现

 this.ViewBag.ViewBag.PropertyName 

在您的自定义控件中工作。

我这是什么页面数据的devise。 把它放到你的视图中。

 @Page.somePropertyName = "Whatever you want"; 

然后在布局视图中访问它。 一定要检查它不是第一个。

 @{ if(Page.somePropertyName != null) { //Do stuff } } 
Interesting Posts