3

我编写的网站遇到了一个奇怪的问题,即在我对代码进行任何更新后,它突然无法立即识别会话中存储的项目。我搜索了 Stackoverflow / google / 等,可以看到其他一些人有同样的问题,但在任何地方都找不到解决方案。

大致是这样的:

如果我将一个项目添加到我的购物篮中,它List<BasketItem>会在会话中存储一个。如果我随后对某些代码(不是 BasketItem)进行更新,会话变量仍然存在,但 .NET 似乎并不认为它是一个List<BasketItem>,即使它肯定是。

当我在修改代码后尝试检索篮子项目列表时,它会抛出一个InvalidCastException没有任何意义的东西,因为它基本上是在试图说它正在转换的类型是不同的,即使它们不是。

例外是:

System.InvalidCastException:[A]System.Collections.Generic.List 1[BasketItem] cannot be cast to [B]System.Collections.Generic.List1[BasketItem]。类型 A 源自位置 'C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll' 的上下文 'LoadNeither' 中的 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' . 类型 B 源自 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 在上下文 'LoadNeither' 的位置 '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"];

目前我使用'as cast',所以我不会出错,但这确实意味着当代码更新时用户的购物篮会丢失。

任何建议将不胜感激!

干杯

蒂姆

4

1 回答 1

1

由于底层类型数据的存储方式,这种类型的问题非常常见BinaryFormatter,如果它们不能解决您所想的完全相同的问题,则可能会导致问题BasketItem。最常见的是,在更改应用程序/库的版本时,或者当不同的服务器具有不同的状态时,这会造成伤害。

我的强烈建议是:不要让它BinaryFormatter用来存储状态!在这方面和一个类型中的一些其他问题上,它不是非常友好版本。如果可能的话,我敦促您考虑使用强大的基于合约的数据(意思是:几乎除/之外的任何数据)。例子:BinaryFormatterNetDataContractSerializer

  • 您可以使用JavaScriptSerializer和存储基本string数据
  • 您可以使用XmlSerializer和存储基本string数据
  • 如果你想要二进制,你可以使用 protobuf-net 并存储byte[]数据

然后,您显然会使用辅助方法来存储/检索您的数据,通常使用通用的void Store<T>(string key, T object)and T Retreive<T>(string key),并typeof(T)根据需要在内部使用。这样做的好处是,存储的数据现在与任何特定实现无关,并且可以被您的应用程序的其他版本使用(因为没有任何东西与类型相关),如果需要,甚至可以被其他平台(Java、php 等)使用.

我很欣赏这是绕过问题而不是直接解决方案 - 但是:它有效。

于 2011-12-07T10:18:46.340 回答