【问题标题】:ViewBag not passing from base controllerViewBag 未从基本控制器传递
【发布时间】:2020-12-31 22:34:44
【问题描述】:

我们已将我们的应用程序转换为 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. 解决此问题的最佳方法是什么? (没有在一堆地方添加价值。)

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

编辑2: 这是一个说明问题的简单 foo 项目 https://github.com/nurdyguy/ViewBagIssue

【问题讨论】:

  • 您如何单步调试您的代码并查看ViewBag.Title 被覆盖的位置?
  • 我没有看到它在任何地方被覆盖。在我所在的任何地方(除了基本控制器),值都是空的。
  • 您确定您正在调试的控制器实际上继承了ControllerBase? viewbag 没有什么特别之处,它只是一个普通的属性。继承不应破坏这一点。
  • 我想说请发布所有相关代码。
  • 我很肯定所有有问题的控制器都继承自 ControllerBase。

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


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 你有没有弄清楚是什么原因造成的?我现在遇到了同样的问题...我可以使用IActionFilter 路由,但更愿意在基本控制器的构造函数中设置它,因为我有几个不同的基本控制器会添加不同的行为。
  • 据我所知,这是一个错误。我们最终只使用了上面的解决方法。有一次我打算在 github 上提交一个错误,但我想我从来没有这样做过。
  • 啊。看起来它有一个错误。按设计说明:github.com/aspnet/Mvc/issues/1422#issuecomment-59997202。我正在使用您的过滤器解决方案。奇迹般有效。谢谢!
  • github问题的好发现,之前一定错过了。
  • 核心 2.2 中仍然存在此问题。感谢过滤器解决方案,它帮助了我。
猜你喜欢
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-06
  • 2013-12-20
  • 2020-10-18
  • 2013-04-08
相关资源
最近更新 更多