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

时间:2015-11-19 12:23:38

标签: c# asp.net serialization viewstate

我正在尝试在Viewstate中存储一个复杂的对象,以避免每次在页面加载时调用它。我确实理解它需要序列化才能从Viewstate保存和重新审核,这意味着我的课程应该标记为[Serializable]

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

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

它是否可能,是否有任何可能的方法来保存和检索视图状态对象而不进行序列化?

4 个答案:

答案 0 :(得分:2)

在我看来,从你的用例“避免每次在页面加载时调用它”为缓存尖叫。我想如果你希望它过期可能会设置一些依赖项,它might work better than session(我们不知道所有细节)。

现在,您可以使用json.net来帮助您序列化信息,而无需更改对象。只是不要滥用viewstate,如果你让它成长,它会变得非常讨厌。使用会话或缓存(如果它符合您的需要)是可以长期更好地扩展的东西。

如果这是显示内容,请查看Output cache,因为您可以在用户控件或其他内容中分离重复的内容。

总而言之,我想添加一个使用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);

警告,编写代码而不编译它。

答案 1 :(得分:1)

您可以使用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

    }
}

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

另一种可能的解决方案是您可以将所有非必需的属性映射为[NonSerialized],以便仅使用一次必需的属性。我遇到了类似的问题,并选择了该选项。

因此,假设在上面的示例中您想要专辑而不是艺术家,那么您的班级将变为以下

[Serializable]
Class Article
{
    Albums albumList { get; set; }

    [NonSerialized]
    Authors authorList { get; set; }
    ...
}