ViewBag没有从基本控制器传递

时间:2017-01-23 18:57:46

标签: asp.net-core asp.net-core-mvc

我们已将我们的应用程序转换为ASP.NET Core但我遇到了正确填充ViewBag的问题。我们有以下基本控制器

public abstract class ControllerBase : Controller
{
    public ControllerBase()
    {
        ViewBag.Title = "MySite";
    }
  ...// lots of other stuff here also
}

我们所有其他控制器都继承自ControllerBase但是当我们到达视图并使用以下

@{
    ViewBag.Title = ViewBag.Title + " - " + Model.PageTitle;
}

但在视图中ViewBag.Title为空。它不会导致错误,但我们最终只是" - MyPage"而不是" MySite - MyPage"对于浏览器标题。

这一切都在以前版本的.net中正常工作,现在只在ASP.NET Core中工作。当我逐步调试调试器时,我看到正在调用ControllerBase构造函数,但ViewBag数据不会持久存在。

这给我留下了两个问题:

  1. ASP.NET Core中是否有新的/不同的东西改变了ViewBag的范围?
  2. 解决此问题的最佳方法是什么? (不在一堆地方添加价值。)
  3. 编辑: 我在基本控制器的第一行设置了一个调试器停止,然后将ViewBag.Title设置为我的监视变量。当我单步执行时,我可以看到值设置,然后我从基本控制器移动到特定动作控制器的构造函数。当我逐步完成该构造函数时,仍然会设置ViewBag.Title。只要我点击Index()方法的第一行,ViewBag.Title就会转到null

    EDIT2: 这是一个简单的foo项目,说明了这个问题 https://github.com/nurdyguy/ViewBagIssue

1 个答案:

答案 0 :(得分:3)

我仍然不知道为什么会这样,但这是我找到的解决方法。创建OnActionExecuting过滤器:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace MyProj.Filters
{
    public class ViewBagFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            // do something before the action executes
            var controller = context.Controller as Controller;
            controller.ViewBag.Title = "MyPage";
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            // do something after the action executes
        }
    }
}

并将以下内容添加到ConfigureServices中的Startup.cs方法:

services.AddMvc(options =>
{
    options.Filters.Add(typeof(ViewBagFilter));
    ... // you may have more here...
});

您会注意到var controller = context.Controller as Controller;有投射,因为context上的控制器对象是object,但很容易修复。

如果我确切地知道导致问题的原因,我会在这里回复。好狩猎!