我编写的网站遇到一个奇怪的问题,即在我对代码进行任何更新后,它突然无法立即识别出会话中存储的项目。我搜索了Stackoverflow / google / etc,可以看到其他一些人也遇到了同样的问题,但是在任何地方都找不到解决方案。
大致情况如下:
如果我将商品添加到购物篮中,它将在会话中存储List<BasketItem>
。如果然后我对某些代码(不是BasketItem)进行更新,则会话变量仍然存在,但是.NET似乎并不确定它是List<BasketItem>
,即使它确实存在。
当我在修改代码后尝试检索购物篮项目列表时,它抛出InvalidCastException
,这根本没有任何意义,因为它基本上是在说要转换的类型是不同的,即使它们不是。
例外是:
System.InvalidCastException:
[A] System.Collections.Generic.List 1[BasketItem] cannot be cast to [B]System.Collections.Generic.List
1 [BasketItem]。 A型起源
来自'mscorlib,版本= 2.0.0.0,文化=中性,
PublicKeyToken = b77a5c561934e089”,位于“
地点
'C:\ Windows \ assembly \ GAC_64 \ mscorlib \ 2.0.0.0__b77a5c561934e089 \ mscorlib.dll'。
类型B源自“ mscorlib,版本= 2.0.0.0,文化=中性,
PublicKeyToken = b77a5c561934e089”,位于“
地点
'C:\ Windows \ assembly \ 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"];
目前,我正在使用“强制转换”,因此我不会出错,但这确实意味着更新代码时用户的篮子已经丢失了。
任何建议将不胜感激!
干杯
提姆
最佳答案
由于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等)使用。
我很欣赏这是解决问题的一个替代方法,而不是直接的解决方案-但是:它有效。
关于c# - StateServer session 中的InvalidCastException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8413510/