English 中文(简体)
在局部视图中修改MVC 3 ViewBag不会持续到_Layout.cshtml
原标题:Modifying MVC 3 ViewBag in a partial view does not persist to the _Layout.cshtml

我正在使用MVC 3和Razor视图引擎。我想在部分视图内的ViewBag中设置一些值,并在_Layout.cshtml中检索这些值。例如,当您设置默认的ASP.NET MVC 3项目时,您会在“/Views/Shared”文件夹中获得_Layout.chshtml文件。在_Layout.cshtml中,页面标题设置如下:

<title>@ViewBag.PageTitle</title>

然后在“/Views/Home/About.cshtml”视图中修改ViewBag的内容:

@{
    ViewBag.Title = "About Us";
}

这很好用。呈现“关于”视图时,页面标题为“关于我们”。所以,现在我想在About视图中渲染Partial视图,并修改Partial视图中的ViewBag.Title。(“/Views/Shared/SomePartial.cs.html”)

@Html.Partial("SomePartial")

在这个局部视图中,我有以下代码:

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

当我调试此代码时,我看到ViewBag.Title被设置为“关于我们”,然后在Partial视图中,我看到它被重置为“About Us From the Partial view”,但当代码到达_Layout.cshtml时,它会返回到“About Us”。

这是否意味着,如果在Partial视图中修改ViewBag的内容,则这些更改将不会出现(可访问)在主视图(About.cs.html)或_Layout.cshtml中?

提前感谢!

最佳回答

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

我提出的解决方案是实现一个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对象。

问题回答

如果将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"

局部视图有自己的ViewBag

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

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

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

......

<script type="text/javascript">
    document.title = "@ViewBag.Title";
</script>

As others have pointed out Layout, Views and Partials get their own ViewBag. However, I was able to get it to work with the following: In the View or Partial.

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

然后在布局(_L)

@Html视图上下文视图包标题

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

如果有人仍在寻找解决方案,那么您似乎可以使用TempData:

TempData["x"] = x;

TempData一直保持到被读取,因此您可以在_Layout中读取它。你只需要小心阅读所有内容,以便为下一个请求清除这些内容。

我试过以下方法,效果很好:

在(父)视图中。。。

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

注意:ViewData作为模型参数传递,但您必须为ViewDatanull才能使用正确的重载。您不能使用ViewBag,因为Html.Partial不喜欢动态。

然后,在局部视图中。。。

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

当然,如果您需要使用model参数作为真实模型,那么您必须更加富有创造性。

尝试使用@SLaks代码

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

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

this.ViewBag.ViewBag.PropertyName 

在自定义控件中工作。

这就是页面数据的设计目的。将此弹出到您的视图中。

@Page.somePropertyName = "Whatever you want";

然后在布局视图中访问它。请确保首先检查它是否为空。

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




相关问题
Passing Variables between views / view controllers

Hi I m new to ObjectiveC / IPhoneSDK and I m informally trying to study it on my own. What I m basically trying to do is from one view there are 12 zodiac signs. When a user clicks one, it proceeds to ...

Rails - Too much logic in views?

I have an application used by several organizations and I want to check that users of one domain (a.domain.com) cannot edit users of another domain (b.domain.com). My question is where to put the ...

Should I use Response.Write directly from a View?

I have been trying to avoid using Response.Write(...) directly in my MVC Views. The reason being that I just need to type the string literals and the view engine knows what to do. However, in certain ...

How to manage shared vs customizable tables

We have many clients using our application, and each of them has their own, identically structured database on our MS SQL Server. We also have a central database for information that is invariant and ...

热门标签