NHibernate / ASP.Net状态服务器异常(无法序列化会话状态)

时间:2011-05-24 16:45:50

标签: c# asp.net nhibernate session state

升级到NHibernate 3.1和.Net 4后,我在Web应用程序中看到一个奇怪的异常。许多人可能都熟悉错误消息:

  

无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET将序列化会话状态对象,因此不允许使用不可序列化的对象或MarshalByRef对象。如果自定义会话状态存储在“自定义”模式下完成类似的序列化,则适用相同的限制。

切换到“inProc”模式,一切正常。但我们不能在生产中使用inProc模式。

现在,错误只发生在ONCE上。然后离开,直到重新部署或重新启动应用程序。

下面是日志中显示的完整堆栈跟踪。请注意以下有趣的观点:

  • PersistentGenericBag`1 [DAL.DTO.Cargo]可能表示这与延迟加载有关
  • 序列化程序正在尝试将其转换为Int32
  • 在调查会话内容时,我绝对找不到DTO对象或对任何对象的引用。如果我清除()会话,则异常消失,但我们的应用程序会中断。
  

[InvalidCastException:无法将类型为'NHibernate.Collection.Generic.PersistentGenericBag`1 [DAL.DTO.Cargo]'的对象强制转换为'System.IConvertible'。]      System.Convert.ToInt32(Object value,IFormatProvider provider)+21      System.Runtime.Serialization.Formatters.Binary ._ BinaryWriter.WriteValue(InternalPrimitiveTypeE code,Object value)+62      System.Runtime.Serialization.Formatters.Binary。 _BinaryWriter.WriteMember(NameInfo memberNameInfo,NameInfo typeNameInfo,Object value)+76      System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(NameInfo memberNameInfo,NameInfo typeNameInfo,Object data)+75      System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMembers(NameInfo memberNameInfo,NameInfo memberTypeNameInfo,Object memberData,WriteObjectInfo objectInfo,NameInfo typeNameInfo,WriteObjectInfo memberObjectInfo)+198      System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMemberSetup(WriteObjectInfo objectInfo,NameInfo memberNameInfo,NameInfo typeNameInfo,String memberName,Type memberType,Object memberData,WriteObjectInfo memberObjectInfo)+139      System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo,NameInfo memberNameInfo,NameInfo typeNameInfo,String [] memberNames,Type [] memberTypes,Object [] memberData,WriteObjectInfo [] memberObjectInfos)+186      System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo,NameInfo memberNameInfo,NameInfo typeNameInfo)+480      System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph,Header [] inHeaders,__BinaryWriter serWriter,Boolean fCheck)+444      System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,Object graph,Header [] headers,Boolean fCheck)+133      System.Web.Util.AltSerialization.WriteValueToStream(Object value,BinaryWriter writer)+1708   <

     

[HttpException(0x80004005):无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET将序列化会话状态对象,因此不允许使用不可序列化的对象或MarshalByRef对象。如果自定义会话状态存储在“自定义”模式下完成类似的序列化,则适用相同的限制。      System.Web.Util.AltSerialization.WriteValueToStream(Object value,BinaryWriter writer)+1793      System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value,BinaryWriter writer)+34      System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer)+638      System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item,Stream stream)+244      System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item,Int32 initialStreamSize,Byte []& buf,Int32& length,Boolean compressionEnabled)+67      System.Web.SessionState.OutOfProcSessionStateStore.SetAndReleaseItemExclusive(HttpContext context,String id,SessionStateStoreData item,Object lockId,Boolean newItem)+114      System.Web.SessionState.SessionStateModule.OnReleaseState(Object source,EventArgs eventArgs)+807      System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+148      System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean& completedSynchronously)+75

1 个答案:

答案 0 :(得分:1)

这结果是一个非常讨厌的问题。确实存在对会话状态中存储的DTO对象的引用,但是它们被隐藏得足够深,以便仅手动检查会话内容不会泄露它们。

如果升级到NHib 3和.Net 4之后有其他人遇到此问题;找到可重现的案例并仔细检查您的代码或使用代码分析工具。如果没有运气,请尝试识别在会话中存储数据的所有代码,并在发现有问题的数据之前使用暴力。祝你好运!