来自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',所以我不会出错,但它确实意味着用户的篮子在代码更新时丢失。

任何建议将不胜感激!

欢呼蒂姆

来自StateServer会话的InvalidCastException

这个类型的问题很常见,因为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等)使用。

我明白这是一个绕过问题的步骤而不是一个直接的解决方案-但是:它有效。

相关文章:
  • 没有找到相关文章