【问题标题】:Problem populating the ViewBag using TempData & Redirect使用 TempData & Redirect 填充 ViewBag 时出现问题
【发布时间】:2019-04-12 02:48:30
【问题描述】:

我继承了一个 MVC 项目,但我遇到了一些麻烦,因为我对 MVC 和 Web 开发非常陌生。

该项目包含一个生成视图的控制器操作方法。此方法可以在用户直接通过 UI 访问视图时调用,也可以在用户单击视图上的按钮执行操作后重新生成视图。如果执行操作后重新生成视图,则需要在页面上显示验证消息。

在 cshtml 文件中,我们在 MainWindow.cshtml 中有以下内容,它仅在 ViewBag 中存在名为“SavedMessage”的字符串且不为 null 或空的情况下以条件渲染表格:

@{ string actionResult = ViewBag.SavedMessage; }
@if (!string.IsNullOrEmpty(actionResult))
{
    <tr>
         <td>
             @actionResult
         </td>
    </tr>
}

在 Action 方法中,我尝试使用 TempData 对象将字符串值传输到生成视图的 Action:

public partial class ApproveController : Controller
{
    const string IDX_ACTIONRESULT = @"ActionResult";

    public ActionResult MyAction(FormCollection collection)
     {
         try
         {
             string result_success = @"Action completed successfully";
             //Do stuff
             TempData[IDX_ACTIONRESULT] = result_success;
             return RedirectToAction("MainWindow");
         }
         catch (Exception e)
         {
             Logger.reportException(e);
             throw e;
         }
     }
 }

在生成视图的Action中,我们将存储在TempData中的值加载到一个变量中,然后测试该变量是否包含任何内容。如果变量不为空,我会尝试将它包含的任何内容加载到 ViewBag 中。

创建视图操作:

public partial class ApproveController : Controller
{
    public ActionResult MainWindow()
    {
        //Do Stuff
        var actionResult = TempData[IDX_ACTIONRESULT];
        if (actionResult != null)
        {
            Log.info("Action Result Message: " + actionResult);
            ViewBag.SavedMessage = actionResult;  
        }
        else
            Log.info("Action Result Message is NULL");


        return View();
    }
}

可能的线索: 当 MainWindow() 方法是通过 UI 而不是 MyAction() 的 Redirect 调用时,我的日志显示 actionResult 为 null,但是,当它通过 MyAction() 的 Redirect 调用时,actionResult 是一个 空字符串。这让我相信 MyAction() 正在用 something 填充 TempData,但我不明白为什么它不包含我在 MyAction() 中分配的字符串。

有人在这里看到确凿证据吗?

【问题讨论】:

  • 有什么问题?您预计会发生什么以及会发生什么?
  • @Jasen - 我需要在 MyAction() 中添加到 TempData 的字符串在 MyAction() 重定向到 MainWindow() 时保留,以便我可以将其添加到 ViewBag。
  • 我不知道这是否是一个错字,但在您看来,您检查的是savedMessage 而不是actionResult。有没有调试过控制器,确认TempData[IDX_ACTIONRESULT]确实是一个空字符串?
  • @Jasen - 谢谢你的收获;我已经解决了这个问题。这是在混淆我的代码时引入的一个错字;真实的代码是准确的。至于你的第二个问题,当我们从 MyAction 重定向时,我相当确定 TempData[IDX_ACTIONRESULT] 是一个空字符串。当我们从 UI 生成视图时,TempData[IDX_ACTIONRESULT] 肯定是 NULL。

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


【解决方案1】:

我需要结合使用 TempData 和 ViewBag 来实现我的目标。这是我所做的:

工人行动 在这里,我们只是根据操作是否成功为 TempData[IDX_ACTIONRESULT] 分配一个字符串值。我们不会抛出异常,而是记录异常,然后使用此 TempData 属性报告失败

public partial class ApproveController : Controller
{
    const string IDX_ACTIONRESULT = @"ActionResult";

    public ActionResult MyAction(FormCollection collection)
     {
         try
         {
             //Do stuff
             TempData[IDX_ACTIONRESULT] = @"Action completed successfully";
             return RedirectToAction("MainWindow");
         }
         catch (Exception e)
         {
             Logger.reportException(e);
             TempData[IDX_ACTIONRESULT] = @"The Action failed. Please contact your system administrator for assistance";
         }
     }
}

创建视图操作 当我们构建视图时,我们将检查属性 TempData[IDX_ACTIONRESULT] 是否具有指定值。如果是这样,我们将读取该值并将其分配给 ViewBag.SavedMessage。

public partial class ApproveController : Controller
{
    public ActionResult MainWindow()
    {   
        if (TempData[IDX_ACTIONRESULT] != null)
            ViewBag.SavedMessage = TempData[IDX_ACTIONRESULT].ToString();

        //Build the rest of the view

        return View();
    }
}

我在问题的 Possible Lead 部分中引用的空字符串归因于之前开发人员的代码。他只是将来自 RESTful API 调用的 HTTP 响应消息读取到方法的返回值中。碰巧的是,该特定 API 在成功时返回一条空消息。所以,看来我这几天一直在追我的尾巴:)

【讨论】:

    【解决方案2】:

    TempData 使用 Session 存储来持久化数据。我的猜测是您没有启用会话,因为它不再默认出现,我不相信。

    您需要在启动代码中添加services.AddSession();app.AddSession(); 才能启用它。

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-2.1#installing-and-configuring-session

    【讨论】:

    • 谢谢。我看了这篇文章。虽然这是一个 MVC 项目,但它构建为类库而不是 Web 应用程序(我不知道开发人员为什么选择这样做)。我在项目中搜索了 ConfigureServices() 方法的调用,但没有找到。你能推荐任何其他方式来完成我在这里尝试做的事情吗?我只需要一个字符串来在动作和视图之间持续存在。我不敢相信这这么难……
    • 如果您只需要保留一个字符串,您可以使用隐藏输入并从模型/视图包中分配值,然后将其包含在回发中
    • 谢谢,但由于我不是网络开发人员,这对我来说几乎没有任何意义。我至少需要查看部分代码示例。如果我失礼了,我深表歉意,但我已经做了一个多星期了,关于网络开发的一切似乎都是故意不直观的
    猜你喜欢
    • 2019-04-06
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多