我正在尝试在Viewstate中存储一个复杂的对象,以避免每次在页面加载时调用它。我确实理解它需要序列化才能从Viewstate保存和重新审核,这意味着我的课程应该标记为[Serializable]
它是一个相当复杂的实体,基本上我希望避免将每个类标记为Serializable,因为它可能影响我用于映射的其他依赖项。
Class Article
{
Albums albumList { get; set; }
Authors authorList { get; set; }
...
}
它是否可能,是否有任何可能的方法来保存和检索视图状态对象而不进行序列化?
答案 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; }
...
}