Подтвердить что ты не робот

Хранить сложный объект в 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?

4b9b3361

Ответ 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