将TempData与Post Redirect Get模式一起使用

时间:2018-12-20 20:14:35

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

许多人主张将TempData与.NET Core 2.2.x中的PRG模式一起使用。

据我了解,以下代码存储数据:

 TempData["foo"] = JsonConvert.SerializeObject(model);

以下内容将重新构成模型,然后将其从TempData构造中删除:

string s = (string)TempData["Model"];
var model = JsonConvert.DeserializeObject<ModelType>(s);

因此,鉴于TempData的这种瞬态性质,请想象以下PRG构造。用户发布到UserInfo操作,该操作将模型打包到TempData中并重定向到UserInfo GET。 GET UserInfo重构模型并显示视图。

[HttpPost]
public IActionResult UserInfo(DataCollectionModel model) {
    TempData["Model"] = JsonConvert.SerializeObject(model);
    return RedirectToAction("UserInfo");
}

[HttpGet]
public IActionResult UserInfo() {
    string s = (string)TempData["Model"];
    DataCollectionModel model = JsonConvert.DeserializeObject<DataCollectionModel>(s);
    return View(model);
}

用户现在位于/ Controller / UserInfo页面上。如果用户按F5刷新页面,则TempData [“ Model”]将不再存在,并且UserInfo上的GET将失败。解决方法可能是在读取模型后将模型存储在TempData中,但这不会导致内存泄漏吗?

我想念什么吗?

1 个答案:

答案 0 :(得分:1)

TempData可用于存储瞬态数据。当一个以上的请求需要数据时,它对于重定向非常有用。当读取TempDataDictionary中的对象时,该对象将在该请求结束时被标记为删除。

这意味着如果您在TempData上放一些东西,例如

TempData["value"] = "someValueForNextRequest";

根据另一个请求,您将访问该值,但是一旦您将其读取,该值将被标记为删除:

//second request, read value and is marked for deletion
object value = TempData["value"];

//third request, value is not there as it was deleted at the end of the second request
TempData["value"] == null

Peek和Keep方法使您可以读取值而无需将其标记为删除。假设我们回到第一个将值保存到TempData的请求。

使用Peek,您可以获取值,而无需通过一次调用将其标记为删除,请参见msdn

//second request, PEEK value so it is not deleted at the end of the request
object value = TempData.Peek("value");

//third request, read value and mark it for deletion
object value = TempData["value"];

使用Keep,您可以指定一个标记为要保留的删除键。检索对象并随后保存以将其删除,这是两个不同的调用。参见msdn

//second request, get value marking it from deletion
object value = TempData["value"];
//later on decide to keep it
TempData.Keep("value");

//third request, read value and mark it for deletion
object value = TempData["value"];

当您始终希望保留另一个请求的值时,可以使用Peek。保留值时使用Keep取决于其他逻辑。

在“获取操作”中进行以下更改

public IActionResult UserInfo()
    {
        //The First method ,
        string s = (string)TempData.Peek("Model");

        //The Second method
        string s = (string)TempData["Model"]; 
        TempData.Keep("Model");

        if(s==null)
        {
            return View();
        }
        else
        {
            User model = JsonConvert.DeserializeObject<User>(s);
            return View(model);
        }
    }