来自StateServer会话的InvalidCastException
本文关键字:InvalidCastException 会话 StateServer 来自 | 更新日期: 2023-09-27 18:16:56
我写的一个网站遇到了一个奇怪的问题,即在我对代码进行任何更新后,它突然不能识别会话中存储的项目。我搜索了Stackoverflow/google/等,可以看到其他人也有同样的问题,但在任何地方都找不到解决方案。
大致是这样的:
如果我添加一个项目到我的篮子,它在会话中存储一个List<BasketItem>
。如果我然后更新一些代码(不是BasketItem)会话变量仍然存在,但。net似乎不认为它是一个List<BasketItem>
,即使它肯定是。
当我尝试在修改代码后检索篮项目列表时,它抛出一个InvalidCastException
,这没有任何意义,因为它基本上试图说它正在转换的类型是不同的,即使它们不是。
例外是:
系统。InvalidCastException:[一]System.Collections.Generic。列出
1[BasketItem] cannot be cast to [B]System.Collections.Generic.List
1[BasketItem]。A型的起源from 'mscorlib, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089'在上下文'LoadNeither' at位置"C: ' Windows '会议' GAC_64 ' mscorlib ' 2.0.0.0__b77a5c561934e089 ' mscorlib.dll"。类型B源自'mscorlib, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089'在上下文'LoadNeither' at位置"C: ' Windows '会议' GAC_64 ' mscorlib ' 2.0.0.0__b77a5c561934e089 ' mscorlib.dll"。
我正在使用StateServer作为会话状态并运行ASP。. NET 3.5 SP1
我使用的代码如下:
// for setting the basket
List<BasketItem> basketItems = new List<BasketItem>();
Session["basket"] = basketItems;
// for getting the basket
List<BasketItem> basketItems = (List<BasketItem>)Session["basket"];
目前我使用'as casting',所以我不会出错,但它确实意味着用户的篮子在代码更新时丢失。
任何建议将不胜感激!
欢呼蒂姆这个类型的问题很常见,因为BinaryFormatter
存储底层类型数据的方式,如果它们不能解析为与您所想到的BasketItem
完全相同,这可能会导致问题。最常见的情况是,当更改应用程序/库的版本时,或者当有不同的服务器具有不同的状态时,这会造成伤害。
我的强烈建议是:不要让它使用BinaryFormatter
来存储状态!不是非常版本友好,在这方面和类型中的其他一些问题上都是如此。如果可能的话,我建议您考虑使用基于强合约的数据(意思是:除了BinaryFormatter
/NetDataContractSerializer
之外的任何数据)。例子:
- 您可以使用
JavaScriptSerializer
并存储数据的基本string
- 您可以使用
XmlSerializer
并存储数据的基本string
- 如果你想要二进制,你可以使用protobuf-net并存储一个
byte[]
的数据
显然,您将使用辅助方法来存储/检索您的数据,通常使用通用的void Store<T>(string key, T object)
和T Retreive<T>(string key)
,必要时在内部使用typeof(T)
。这样做的好处是,存储的数据现在与任何特定的实现无关,并且可以由应用程序的其他版本使用(因为没有任何类型依赖),甚至在必要时可以由其他平台(Java, php等)使用。
我明白这是一个绕过问题的步骤而不是一个直接的解决方案-但是:它有效。