将复杂对象存储在 TempData 中

问题描述 投票:0回答:4

我一直在尝试使用 TempData 在重定向后将数据传递给操作,如下所示:

if (!ModelState.IsValid)
{
    TempData["ErrorMessages"] = ModelState;
    return RedirectToAction("Product", "ProductDetails", new { code = model.ProductCode });
}

但不幸的是它失败并显示以下消息:

'

System.InvalidOperationException
Microsoft.AspNet.Mvc.SessionStateTempDataProvider'
无法序列化 类型为
'ModelStateDictionary'
的对象到会话状态。'

我在 Github 中的 MVC 项目中发现了一个问题,但是虽然它解释了为什么我收到此错误,但我看不出什么是可行的替代方案。

一种选择是将对象序列化为 json 字符串,然后将其反序列化回来并重建

ModelState
。这是最好的方法吗?我需要考虑任何潜在的性能问题吗?

最后,是否有任何替代方案可以序列化复杂对象或使用不涉及使用

TempData
的其他模式?

c# asp.net-core asp.net-core-mvc tempdata
4个回答
179
投票

您可以像这样创建扩展方法:

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
类型。您可以使用上述扩展方法将其添加到临时数据字典中,如下所示:

TempData.Put("key", objectA);

要检索它,您可以这样做:

var value = TempData.Get<ClassA>("key")
其中检索到的
value
类型为
ClassA


19
投票

在.Net core 3.1及以上版本中使用System.Text.Json

using System.Text.Json;

    public static class TempDataHelper
    {
        public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class
        {
            tempData[key] = JsonSerializer.Serialize(value);
        }

        public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class
        {
            tempData.TryGetValue(key, out object o);
            return o == null ? null : JsonSerializer.Deserialize<T>((string)o);
        }

        public static T Peek<T>(this ITempDataDictionary tempData, string key) where T : class
        {
            object o = tempData.Peek(key);
            return o == null ? null : JsonSerializer.Deserialize<T>((string)o);
        }
    }

18
投票

我无法发表评论,但我也添加了一个 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

0
投票

我在 Tempdata 中保存类对象,然后在控制器中的另一个操作方法中检索该数据时遇到问题,您可以做的是 将类对象数据保存在 Tempdata 中

Student ClsStudent= new Student 

ClsStudent =getstudent(Student_id):
Tempdata["Studentdata"]= ClsStudent;

之后在其他方法中使用该临时数据

Student clsStudent = null;
ClsStudent= (Student)Tempdata["Studentdata"]

现在你可以像以前一样使用这个类对象数据。这里我们为类对象提供Tempdata。

© www.soinside.com 2019 - 2024. All rights reserved.