在后续的HTTP请求之后,TempData是否仍然可用?

时间:2019-07-31 05:09:44

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

我的教科书说“ TempData在随后的HTTP请求中使用后立即被销毁”,所以我编写了一个简单的测试来验证

下面是我的代码:

// SimpleForm.cshtml is just a simple view that uses a form to send post request to ReceiveForm action method
//Result.cshtml is just a simple view that products an output

public class HomeController : Controller
{
   public ViewResult Index() => View("SimpleForm");

   [HttpPost]
   public RedirectToActionResult ReceiveForm(string name, string city)
   {
      TempData["name"] = name;
      TempData["city"] = city;
      return RedirectToAction(nameof(Transfer));
   }

   public RedirectToActionResult Transfer()
   {
       string name = TempData["name"] as string;
       string city = TempData["city"] as string;
       return RedirectToAction(nameof(Data));
   }

   public ViewResult Data()
   {
      string name = TempData["name"] as string;
      string city = TempData["city"] as string;
      return View("Result", $"{name} lives in {city}");
   } 
}

因此,当应用程序运行时,它首先进入Index()操作方法,我用名称和城市填写表单,然后按Submit按钮,然后进入ReceiveForm()操作方法,该方法设置TempData并重定向到Transfer()操作方法。

在Transfer()动作方法中,我读取了TempData,因此根据教科书,TempData应该被破坏并且无法在下一个http请求中读取。

但是在Data()中,我仍然可以读取TempData,请参见下面的屏幕截图:

enter image description here

然后我检查了chrome dev工具,有一个post请求和两个get请求,都很好而且是正确的。 那么TempData真正何时被销毁?

其他代码:

SimpleForm.cshtml:

@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Controllers and Actions</title>
    <link rel="stylesheet" asp-href-include="lib/bootstrap/dist/css/*.min.css" />
</head>
<body class="m-1 p-1">
    <form method="post" asp-action="ReceiveForm">
        <div class="form-group">
            <label for="name">Name:</label>
            <input class="form-control" name="name" />
        </div>
        <div class="form-group">
            <label for="name">City:</label>
            <input class="form-control" name="city" />
        </div>
        <button class="btn btn-primary center-block" type="submit">Submit</button>
    </form>
</body>
</html>

Result.cshtml:

@model string
@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Controllers and Actions</title>
    <link rel="stylesheet" asp-href-include="lib/bootstrap/dist/css/*.min.css" />
</head>
<body class="m-1 p-1">
    Model Data: @Model
</body>
</html>

1 个答案:

答案 0 :(得分:0)

对于您的情况,这是由RedirectToActionResult引起的。对于RedirectToActionResult,即IKeepTempDataResult

public class RedirectToActionResult : ActionResult, IKeepTempDataResult

SaveTempDataFilter是用于保存临时数据的过滤器。它将调用SaveTempData

private static void SaveTempData(
    IActionResult result,
    ITempDataDictionaryFactory factory,
    IList<IFilterMetadata> filters,
    HttpContext httpContext)
{
    var tempData = factory.GetTempData(httpContext);

    for (var i = 0; i < filters.Count; i++)
    {
        if (filters[i] is ISaveTempDataCallback callback)
        {
            callback.OnTempDataSaving(tempData);
        }
    }

    if (result is IKeepTempDataResult)
    {
        tempData.Keep();
    }

    tempData.Save();
}

对于SaveTempData,它将检查IActionResult result是否为IKeepTempDataResult。如果是这样,它将保留tempData。

如果要避免在两次请求之间保留tempData,可以将

RedirectToAction更改为LocalRedirect
public IActionResult Transfer()
{
    string name = TempData["name"] as string;
    string city = TempData["city"] as string;
    return LocalRedirect("~/Home/Data");
    //return RedirectToAction(nameof(Data));
}