使用TempData和重定向填充ViewBag时出现问题

时间:2018-11-08 15:00:01

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

我继承了一个MVC项目,但是由于遇到MVC和Web开发的新手,我遇到了一些麻烦。

项目包含一个生成视图的Controller Action方法。当用户直接通过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中的值加载到变量中,然后进行测试以查看该变量是否包含任何内容。如果变量不为null,则尝试将其包含的内容加载到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();
    }
}

可能的线索: 当通过UI而不是从MyAction()重定向调用MainWindow()方法时,我的日志表明actionResult为 null ,但是,当通过MyAction()重定向调用该方法时,actionResult是< strong>空字符串。这使我相信MyAction()正在用某物填充TempData,但是我看不到为什么它不包含我在MyAction()中分配的字符串。

有人在这里看到吸烟枪吗?

2 个答案:

答案 0 :(得分:0)

TempData使用会话存储来保留数据。我的猜测是您尚未启用会话,因为我不相信它不会再默认出现。

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

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

答案 1 :(得分:0)

我需要结合使用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成功返回一个空消息。所以,看来我已经追了几天尾巴:)