2011-05-24 122 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後遇到此問題,找到可重複使用的案例並仔細檢查您的代碼或使用代碼分析工具。如果沒有運氣,嘗試識別會話中存儲數據的所有代碼,然後直接使用強力直到找到有問題的數據。祝你好運!