Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在局部视图中修改MVC 3 ViewBag不会保留到_Layout.cshtml_View_Asp.net Mvc 3_Razor_Partial_Viewbag - Fatal编程技术网

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

在局部视图中修改MVC 3 ViewBag不会保留到_Layout.cshtml,view,asp.net-mvc-3,razor,partial,viewbag,View,Asp.net Mvc 3,Razor,Partial,Viewbag,我正在使用MVC3和Razor视图引擎。我想在局部视图中的ViewBag中设置一些值,并想在my_Layout.cshtml中检索这些值。例如,当您设置默认ASP.NET MVC 3项目时,会在“/Views/Shared”文件夹中获得一个_Layout.cshtml文件。在该_Layout.cshtml中,页面标题设置如下: <title>@ViewBag.PageTitle</title> 这个很好用。呈现“关于”视图时,页面标题为“关于我们”。因此,现在我想在我的

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

<title>@ViewBag.PageTitle</title>
这个很好用。呈现“关于”视图时,页面标题为“关于我们”。因此,现在我想在我的About视图中呈现一个局部视图,并修改局部视图中的ViewBag.Title。(“/Views/Shared/SomePartial.cshtml”)

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

@{
    ViewBag.Title = "About Us From The Partial View";
}
当我调试这段代码时,我看到ViewBag.Title被设置为“关于我们”,然后在部分视图中,我看到它被重置为“从部分视图关于我们”,但当代码点击_Layout.cshtml时,它返回到“关于我们”

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


提前谢谢

局部视图有自己的
ViewBag


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

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

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

如果将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";
 }
部分:

//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"
尝试使用@SLaks代码

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

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

this.ViewBag.ViewBag.PropertyName 

在自定义控件中工作。

正如其他人所指出的那样,视图和局部视图都有自己的视图包。但是,我能够让它与以下各项一起工作: 在视图中或部分视图中

@{ Html.ViewContext.ViewBag.Title = "Reusable Global Variable"; }
然后在布局中

@Html.ViewContext.ViewBag.Title


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

您可以在局部视图中执行此操作,以覆盖_Layout.cshtml中的标题:

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

......

<script type="text/javascript">
    document.title = "@ViewBag.Title";
</script>
@{
ViewBag.Title=“从局部视图了解我们”;
}
......
document.title=“@ViewBag.title”;

我尝试了以下方法,效果良好:

在(父)视图中

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

然后,在局部视图中

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

当然,如果您需要对真实模型使用
model
参数,您必须更具创造性。

I这就是页面数据的设计目的。把这个放到你的视野里

@Page.somePropertyName = "Whatever you want";
然后在布局视图中访问它。一定要先检查它是否不是null

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

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

TempData["x"] = x;

TempData会一直保存到被读取,这样您就可以在_布局中读取它。您只需小心阅读所有内容,以便为下一个请求清除这些内容。

这不起作用。我尝试使用该代码在部分视图中修改ViewBag,但是当我在_Layout.cshtml中访问ViewBag时,我仍然拥有在“About”视图中设置的值。这不起作用(至少在MVC 4中)。部分视图具有不同的WebPageContext.Current.Page对象(它有一个特定的部分。我有点惊讶ASP.NET MVC没有提供更好的方法来做到这一点。我所能想到的是,我们正在尝试打破MVC模式,但我们都知道在现实世界中会发生这种情况。我在我当前的项目中找到了绕过此要求的方法,所以我没有机会尝试您的解决方案。但感谢您的输入。我会将其标记为已接受的答案,希望它能帮助其他人。-谢谢。我尝试了此方法,但无效。我制作了一个名为
PageData
的简单类(未显示在您的答案中)使用1
string
属性。如果您在局部视图中设置了
PageData
的此属性,则它在您的_布局中为
null
,因为_布局在局部视图中设置属性之前访问该属性。或者,您可以直接将其添加到页面的视图包中。即,在页面“ViewBag.PageBag=ViewBag;”中,然后在局部视图中“ViewBag.PageBag.Title=”新值”"当我需要在局部视图中设置页面标题以显示在布局标题标记中时,这是我发现唯一可以使用的方法。不幸的是@page与ViewData存在相同的问题:在局部视图中对其所做的更改不会一直保留到布局。请参阅:查看此解决方案,以获得每个请求的单例,作为上面列出的解决方案的替代方案,这非常好:不是100%确定,但我猜你不能更改ViewBag变量,因为基于.Net中的MVC模型,分区更像是更小的、可重用的组件,而不是完整的视图。视图可以使用分区来添加(渲染)这些组件本身,但不是相反。视图还可以将ViewModels传递给partials,以向其提供需要渲染的数据。我知道这不是很有建设性,但我的直觉是,如果您尝试
TempData["x"] = x;