Использование TempData с Post Redirect Получить шаблон - PullRequest
0 голосов
/ 20 декабря 2018

Есть ряд людей, которые рекомендуют использовать TempData с шаблоном PRG в .NET Core 2.2.x.

Насколько я понимаю, в этой строке кода хранятся данные:

 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"] больше не будет там, и GET на UserInfo завершится ошибкой.Решением может быть сохранение модели в TempData после ее чтения, но не приведет ли это к утечке памяти?

Я что-то упустил?

1 Ответ

0 голосов
/ 21 декабря 2018

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, когда сохранение значения зависит от дополнительной логики.

Внесите следующие изменения в действие Get

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);
        }
    }
...