ViewBag 未从基本控制器传递

nur*_*guy 5 c# asp.net-core-mvc asp.net-core

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

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

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

@{
    ViewBag.Title = ViewBag.Title + " - " + Model.PageTitle;
}
Run Code Online (Sandbox Code Playgroud)

但在视图中ViewBag.Title是空的。它不会导致错误,但我们最终只得到“ - MyPage”而不是“MySite - MyPage”作为浏览器标题。

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

这给我留下了两个问题:

  1. ASP.NET Core 中是否有一些新的/不同的东西改变了 ViewBag 的范围?
  2. 解决此问题的最佳方法是什么?(没有在一堆地方添加价值。)

编辑:我在基本控制器的第一行设置了一个调试器停止,并将ViewBag.Title设置作为我的观察变量逐步完成。当我逐步完成时,我可以看到值被设置,然后我从基本控制器移动到特定动作控制器的构造函数。当我逐步执行该构造函数时,ViewBag.Title仍然设置。只要我打的第一线Index()方法ViewBag.Title轮流null

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

nur*_*guy 7

我仍然不知道为什么会发生这种情况,但这是我找到的解决方法。创建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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

你会注意到var controller = context.Controller as Controller;有一个强制转换,因为控制器对象context是 anobject但它很容易修复。

如果我确切地找出导致问题开始的原因,我会在这里发帖。狩猎好!