2011-05-24 127 views
1

升级到NHibernate 3.1和.Net 4后,我在我们的Web应用程序中看到一个奇怪的异常。错误消息可能很多人都很熟悉:NHibernate/ASP.Net状态服务器异常(无法序列化会话状态)

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

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

现在,错误只发生一次。然后消失,直到应用程序重新部署或重新启动。

下面是一个完整的堆栈跟踪,因为它出现在日志中。请注意以下几点有趣的地方:

  • PersistentGenericBag`1 [DAL.DTO.Cargo]可能表明调查时,这是关系到延迟加载
  • 串行器试图将其转换为Int32
  • 会话内容,我可以找到绝对没有DTO对象,或任何引用。如果我清除()会话,异常消失,但我们的应用程序中断。

[InvalidCastException的:无法转换类型的对象 'NHibernate.Collection.Generic.PersistentGenericBag`1 [DAL.DTO.Cargo]' 为类型 'System.IConvertible'] System.Convert.ToInt32 (对象值,IFormatProvider提供程序)+21 System.Runtime.Serialization.Formatters.Binary._ BinaryWriter.WriteValue(InternalPrimitiveTypeE code,Object value)+62 System.Runtime.Serialization.Formatters.Binary。 _BinaryWriter.WriteMember(NameInfo memberNameInfo,NameInfo typeNameInfo,对象的值)76 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(NameInfo memberNameInfo,NameInfo typeNameInfo,对象数据)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 memberNameInf o,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 []头文件,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.OutOfProcSessionStateS tore.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步骤,布尔& completedSynchronously)75

回答

1

事实证明,这是一个相当讨厌的问题。确实存在对会话状态中存储的DTO对象的引用,但它们被深度隐藏得足够深,以至于仅仅手动检查会话内容就没有揭示它们。

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