Хранить сложный объект в TempData в MVC 6
Я пытаюсь передать данные в действие после перенаправления с помощью TempData, например:
if (!ModelState.IsValid)
{
TempData["ErrorMessages"] = ModelState;
return RedirectToAction("Product", "ProductDetails", new { code = model.ProductCode });
}
но, к сожалению, он не выполнил следующее сообщение:
'System.InvalidOperationException
The Microsoft.AspNet.Mvc.SessionStateTempDataProvider' cannot serialize an object of type 'ModelStateDictionary' to session state.'
Я нашел проблему в проекте MVC в Github, но пока он объясняет, почему я получаю эту ошибку, я не вижу, что будет жизнеспособной альтернативой.
Одним из вариантов было бы сериализовать объект в строку json, а затем десериализовать его и восстановить ModelState
. Это лучший подход? Существуют ли какие-либо потенциальные проблемы с производительностью, которые я должен учитывать?
И, наконец, существуют ли какие-либо альтернативы для сериализации сложного объекта или использования другого шаблона, который не включает использование TempData
?
Ответы
Ответ 1
Вы можете создать методы расширения следующим образом:
public static class TempDataExtensions
{
public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class
{
tempData[key] = JsonConvert.SerializeObject(value);
}
public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class
{
object o;
tempData.TryGetValue(key, out o);
return o == null ? null : JsonConvert.DeserializeObject<T>((string)o);
}
}
И вы можете использовать их следующим образом:
Скажите objectA
имеет тип ClassA
. Вы можете добавить это в словарь данных temp, используя вышеупомянутый метод расширения, например:
TempData.Put("key", objectA);
И чтобы получить его, вы можете сделать это:
var value = TempData.Get<ClassA>("key")
где value
извлечено будет типа ClassA
Ответ 2
Я не могу прокомментировать, но я добавил PEEK, который хорошо проверяет, есть ли там или читать, а не удалять для следующего GET.
public static T Peek<T>(this ITempDataDictionary tempData, string key) where T : class
{
object o = tempData.Peek(key);
return o == null ? null : JsonConvert.DeserializeObject<T>((string)o);
}
Пример
var value = TempData.Peek<ClassA>("key") where value retrieved will be of type ClassA