Asp.net mvc 3 为什么ViewBag中的项目没有传播到_布局页面?

Asp.net mvc 3 为什么ViewBag中的项目没有传播到_布局页面?,asp.net-mvc-3,Asp.net Mvc 3,我有一个SiteNavigation类,它在我的基本控制器的初始化事件中被更新,例如 [Serializable] public class SiteNavigation { public SiteNavigation() { IsSummarySelected = true; } public Model.Dtos.Folder[] Folders { get; set; } public bool IsSummarySelect

我有一个SiteNavigation类,它在我的基本控制器的初始化事件中被更新,例如

[Serializable]
public class SiteNavigation
{

    public SiteNavigation()
    {
        IsSummarySelected = true;
    }

    public Model.Dtos.Folder[] Folders { get; set; }


    public bool IsSummarySelected { get; set; }

}

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
    base.Initialize(requestContext);

    var siteNavigation = new SiteNavigation();

    siteNavigation.Folders = GetMeMyFolders() as Folder[];

    ViewBag.SiteNavigation = siteNavigation;

}
在控制器中,IsSummarySelected属性将更改为此值

ViewBag.SiteNavigation.IsSummarySelected = false;
当我使用这行代码访问_布局文件中的属性时,该值始终为true。这就好像导航对象正在重新设置,而构造函数正在将其设置为true

 @if (ViewBag.SiteNavigation.IsSummarySelected)
我已经尝试将nav对象转换回一个变量,并以这种方式设置属性,没有骰子。任何帮助都将不胜感激

叫我莫名其妙

谢谢,,
Stephen

我刚刚将您的代码复制粘贴到我的示例mvc项目中,并且在我的操作中正确更改IsSummarySelected会反映在_布局文件中。你确定你的控制器的任务被击中了,并且你没有在其他地方重新分配它吗

编辑:您的问题就是一个例子,说明了为什么我认为使用ViewBag进行本地化快速修复以外的任何操作都不是一个好主意。调试动态全局对象并不有趣。重构建议:在基本控制器中创建站点导航属性

SiteNavigation siteNavigation;
public SiteNavigation SiteNavigation
{
    get
    {
       return siteNavigation;
    }
    set
    {
        siteNavigation = value;
    }
}
并用此替换对ViewBag.SiteNavigation的所有引用。然后创建一个自定义WebViewPage并放入其中

public SiteNavigation SiteNavigation
{
    get
    {
        return ((BaseController)ViewContext.Controller).SiteNavigation;
    }
}
这不会解决您的问题,但现在您可以在SiteNavigation的get和set属性上粘贴断点,现在调试问题应该很容易。

当调用筛选器时,我会通过OnResultExecuting方法填充我的TempData[“SplitterIsCollapsed”]。此外,我从UserContext类中获取属性状态,该类在每个会话中只注册一次:builder.RegisterType().As().CacheInSession()。 基本信息:我使用依赖注入法

将过滤器分配给控制器:

控制器:

[LayoutTempData]
public class HomeController : Controller
{
    //....
}
namespace MyProject.Web.Infrastructure.Filters
{
    public class LayoutTempDataAttribute : ActionFilterAttribute
    {
        private readonly IUserContext _userContext;
        public LayoutTempDataAttribute()
        {
            _userContext = DependencyResolver.Current.GetService<IUserContext>();
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            if (context.Controller.TempData.ContainsKey("SplitterIsCollapsed"))
                context.Controller.TempData["SplitterIsCollapsed"] = _userContext.LayoutInformation.SplitterIsCollapsed;
            else
                context.Controller.TempData.Add("SplitterIsCollapsed", _userContext.LayoutInformation.SplitterIsCollapsed);
        }
    }
}
过滤器属性类:

[LayoutTempData]
public class HomeController : Controller
{
    //....
}
namespace MyProject.Web.Infrastructure.Filters
{
    public class LayoutTempDataAttribute : ActionFilterAttribute
    {
        private readonly IUserContext _userContext;
        public LayoutTempDataAttribute()
        {
            _userContext = DependencyResolver.Current.GetService<IUserContext>();
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            if (context.Controller.TempData.ContainsKey("SplitterIsCollapsed"))
                context.Controller.TempData["SplitterIsCollapsed"] = _userContext.LayoutInformation.SplitterIsCollapsed;
            else
                context.Controller.TempData.Add("SplitterIsCollapsed", _userContext.LayoutInformation.SplitterIsCollapsed);
        }
    }
}
名称空间MyProject.Web.Infrastructure.Filters
{
公共类LayoutTempDataAttribute:ActionFilterAttribute
{
私有只读IUserContext\u userContext;
公共LayoutTempDataAttribute()
{
_userContext=DependencyResolver.Current.GetService();
}
public override void OnResultExecuting(ResultExecutingContext)
{
if(context.Controller.TempData.ContainsKey(“SplitterIsCollapsed”))
context.Controller.TempData[“SplitterIsCollapsed”]=\u userContext.LayoutInformation.SplitterIsCollapsed;
其他的
context.Controller.TempData.Add(“SplitterIsCollapsed”,_userContext.LayoutInformation.SplitterIsCollapsed);
}
}
}
\u Layout.cshtml的拆分器部分如下所示:

@{Html.Telerik().Splitter().Name("Splitter1")
    .Panes(panes =>
        {
            panes.Add()
                .Size("300px")
                .Collapsible(true)
                .Collapsed((bool)TempData["SplitterIsCollapsed"])
                .Content(<div>asdfasdf</div>);
            panes.Add()
                .Collapsible(false)
                .Scrollable(false)
                .Content(<div>content2</div>);
        })
     .Render();
 }
@{Html.Telerik().Splitter().Name(“Splitter1”)
.窗格(窗格=>
{
panes.Add()
.尺寸(“300px”)
.可折叠(真)
.Collapsed((bool)TempData[“SplitterIsCollapsed”])
.内容(asdfasdf);
panes.Add()
.可折叠(错误)
.可滚动(错误)
.内容(内容2);
})
.Render();
}

@AFinkelstien Initialize方法对我正在做的工作很有效,但我去掉了IsSummarySelected属性,而不是通过路由执行。。谢谢你的帮助!