【问题标题】:TempData[] is not working after redirectTempData[] 重定向后不起作用
【发布时间】:2014-10-22 13:34:05
【问题描述】:

我正在尝试使用 mvc TempData[] 通过重定向向另一个控制器发送错误消息:

控制器 1:

    TempData["Message"] = "A password reset email has been sent to " + user.Email +
                                     ". This link in only valid for 24 hours.";
                    return RedirectToAction("Edit", "Users", new { id = userId });

然后,我在 Controller 2 的构造函数中有以下帮助类:

public UsersController()
    {            
        NotificationHelper.GetViewDataNotifications(this);
    }

这里是辅助类:

 public static void GetViewDataNotifications(ControllerBase controller)
    {
         var message =controller.TempData["Message"] ?? "";
        controller.ViewBag.Message = message;

         var errorMessage = controller.TempData["ErrorMessage"] ?? "";
        controller.ViewBag.ErrorMessage = errorMessage;

         var infoMessage= controller.TempData["InfoMessage"] ?? "";
        controller.ViewBag.InfoMessage = infoMessage;

        var warningMessage = controller.TempData["WarningMessage"] ?? "";
        controller.ViewBag.WarningMessage = warningMessage;
    }

然后我希望在我到达 Edit Action 时填充 ViewBag 项目:

public async Task<ActionResult> Edit(int? id)
    {
     ...
     return View();
    }

但是,在我的助手类中,TempData 似乎总是为空。我在这里错过了什么?

TempData[] 是否有一些我不知道的因素,例如它仅在同一控制器中有效或仅对单个操作有效?

【问题讨论】:

  • 不要调用构造函数中的方法。那时,控制器甚至还没有完全构建。 TempData 等属性尚未加载。
  • 那么我应该在需要的操作中调用我的助手吗?
  • @Zapnologica 是的,没错。
  • 好的,我会尝试,我这样做是为了不必在每个操作方法中复制代码。
  • 无论如何都不需要这个助手。只需在您的视图中直接访问TempData。无需先设置ViewBag 中的值。您所做的只是将数据从一个动态存储位置移动到另一个位置。

标签: c# asp.net-mvc asp.net-mvc-5 viewbag tempdata


【解决方案1】:

当控制器的构造函数仍然为空时,您正试图访问 TempData。此时控制器还没有完全构建,更不用说初始化了。

您应该在您的操作中提取 TempData 值。 TempData 至少在控制器构建后、授权和模型绑定之前的三个步骤被初始化。

document 详细描述了控制器的生命周期。虽然您可以覆盖 TempData 初始化 (CreateTempDataProvider) 和实际操作之间的步骤之一,但这并没有多大意义。

【讨论】:

  • 是的,我花了一段时间才知道,在 MVC 决定之前,甚至控制器都不会被实例化。我曾“认为”一旦它们被实例化,它们就会停留在服务器端。将全局变量放在控制器中对我个人来说效果不太好,我建议任何人反对这种做法。将控制器视为路由的最终结果,该路由实例化模型并将正确的视图发送回。不多也不少。
  • 控制器被实例化并随每个请求处理:非常简单。全局变量和静态变量是不行的,因为它们不是线程安全的。
  • @ChrisPratt 你这么说很有趣。 mvc 5 中的默认脚手架使用您的 EF db context 作为全局生成控制器,并在控制器中实例化。然后在每个动作中使用。这也是不正确的吗?
  • 这不是全球性的。它是一个实例变量。每次实例化 Controller 时都会实例化一个新的上下文并存储在其中,因此它是线程安全的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 2021-10-06
  • 1970-01-01
  • 2012-04-23
  • 2013-07-05
  • 2015-09-15
相关资源
最近更新 更多