ASP.NET-在Viewstate中保存而不进行序列化

本文关键字:序列化 保存 NET- Viewstate ASP | 更新日期: 2023-09-27 18:22:43

我试图在Viewstate中存储一个复杂的对象,以避免每次加载页面时都调用它。我知道它需要序列化才能从Viewstate中保存和检索,这意味着我的类应该标记为[Serializable]

这是一个相当复杂的实体,基本上我希望避免将每个类标记为Serializable,因为这可能会影响我用于映射的其他依赖项。

Class Article
{
    Albums albumList { get; set; }
    Authors authorList { get; set; }
    ...
}

在不序列化的情况下保存和检索视图状态对象是否可能?是否有任何可能的方法?

ASP.NET-在Viewstate中保存而不进行序列化

在我看来,从您的用例来看,"避免每次在页面加载时调用它"要求缓存。我认为,如果你想让它过期,也许可以设置一些依赖项,它可能比会话更有效(我们不知道所有细节)。

现在,您可能可以使用json.net,它可以帮助您在不更改对象的情况下序列化信息。只是不要滥用视图状态,如果你让它增长,它会很快变得很糟糕。从长远来看,使用会话或缓存(如果它符合您的需求)可以更好地扩展。

如果这是一个显示内容,也可以查看输出缓存,因为您可以在用户控件或其他控件中分离重复的内容。

话虽如此,我想添加一个小例子,说明您使用JSON.net实际询问的内容(从他们那里偷来的例子):

//Doesnt need to be marked as serializable
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
//Use this string to save into view state
string json = JsonConvert.SerializeObject(product);
ViewState["something"]=json;

之后,从ViewState〔something〕获取字符串并对其进行反序列化

string json = (string)ViewState["something"];
Product m = JsonConvert.DeserializeObject<Product>(json);

警告,在未编译的情况下编写的代码。

您可以使用ASP.NET Session对象(这避免了序列化路由,因为Session中的所有内容都存储为Object),如下所示:

var theArticle = new Article();
Session["MyArticle"] = theArticle;

Session中的所有内容都存储为一个对象,因此当您检索Article对象时,需要将其强制转换为Article,如下所示:

var myArticleFromSession = Session["MyArticle"] as Article;

注意:在尝试访问值之前,建议检查Session密钥是否真的存在,如下所示:

if(Session["MyArticle"] != null)
{
    // The key MyArticle exists, so it is safe to attempt to get the object value
    var myArticleFromSession = Session["MyArticle"] as Article;
    // Since we used as to attempt the cast, 
    // then myArticleFromSession will be null if the cast failed 
    // so check for null before using myArticleFromSession
    if(myArticleFromSession != null)
    {
        // Use myArticleFromSession here
    }
}

如果可能的话,应该避免序列化,因为它相对较慢(不能很好地扩展)。

如果希望在回发之间或跨页缓存特定对象,请使用ASP.NET Session对象进行特定于会话的缓存,使用Application对象进行站点范围的缓存,或者使用System.Web.Caching.Cache进行自己的自定义缓存行为。您还可以缓存ASP.NET页面或部分页面的输出。此处提供更多信息:ASP.NET缓存

但是,如果您希望缓存整个页面的视图状态,则可以选择服务器端视图状态持久化。在这种情况下,您需要创建一个新的BasePage。例如,当浏览器限制非常大的视图状态的大小时,这非常有用。您可以在这里获得有关此方法的更多信息:服务器端视图状态

另一个可能的解决方案是,您可以将所有非必需属性映射为[NonSerialized],这样只使用一次必需属性。我也有类似的问题,选择了这个选项。

所以假设在上面的例子中,你想要的是专辑,而不是艺术家,那么你的课程将变成下面的

[Serializable]
Class Article
{
    Albums albumList { get; set; }
    [NonSerialized]
    Authors authorList { get; set; }
    ...
}