我编写的网站遇到一个奇怪的问题,即在我对代码进行任何更新后,它突然无法立即识别出会话中存储的项目。我搜索了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/

10-11 04:34