2009-06-16 77 views
4

我已經繼承了一個電子商務ASP.NET(後面的c#代碼)web應用程序。我們最近移動了服務器,這證明有些麻煩。我對IIS服務器配置和處理這樣的大型項目的經驗很少。現在大部分問題已經得到解決,但我們遇到了關鍵部分的問題,因爲客戶試圖進行支付。
隨着客戶確認付款後,應用程序可能會遇到以下錯誤:已編譯的DLL中的序列化異常

Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET 
will serialize the session state objects, and as a result non-serializable objects or 
MarshalByRef objects are not permitted. The same restriction applies if similar 
serialization is done by the custom session state store in 'Custom' mode. 

堆棧跟蹤:

[SerializationException: Type 'PayerAuthentication.PayerAuthenticationServicePost' in Assembly 'PayerAuthentication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.] 
    System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +7733643 
    System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +258 
    System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +111 
    System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) +161 
    System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) +51 
    System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +410 
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +134 
    System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1577 

谷歌搜索結果表明我要補充[Serializable]受影響的類聲明,但這是一個編譯的DLL,我沒有csproj。 代碼在以前的服務器上工作正常,我不相信已對代碼進行了任何更改,僅限於web.config - 我該怎麼辦?

的web.config將sessionState部讀取<sessionState mode="StateServer" />

UPDATE1:使用反射器,我導出類的上方,使得它可序列化,重新編譯並替換該DLL。訂單過程更進一步,因此我遇到了另一個DLL編譯類相同的錯誤。我再次能夠使用Reflector查看代碼,然後將其導出,編輯和重新編譯。
現在我有中出現同樣的錯誤:

SerializationException: Type 'System.Runtime.Remoting.Messaging.AsyncResult' in Assembly 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.] 

我不知道我能做到這事,因爲這必須是.NET系統文件的一部分!還有什麼想法?

UPDATE2:哈,嗯,我後來發現它是正確處理費,但隨後投擲System.Runtime.Remoting.Messaging.AsyncResult上述Unable to serialize the session state錯誤用戶得到交易的收據之前。不好。不確定現在該怎麼往前走......

UPDATE3:我試圖創建System.Runtime.Remoting.Messaging.AsyncResult類的副本,並使其可序列化,但隨後這是導致不一致的可訪問性問題。

using System; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Security.Permissions; 
using System.Runtime.Remoting.Messaging; 

    [Serializable, ComVisible(true)] 
    public class myAsyncResult : IAsyncResult, IMessageSink 
    { 
     // Fields 
     private AsyncCallback _acbd; 
     private Delegate _asyncDelegate; 
     private object _asyncState; 
     private ManualResetEvent _AsyncWaitHandle; 
     private bool _endInvokeCalled; 
     private bool _isCompleted; 
     private IMessageCtrl _mc; 
     private IMessage _replyMsg; 

     // Methods 
     internal myAsyncResult(Message m); 
     //[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] 
     public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink); 
     private void FaultInWaitHandle(); 
     public virtual IMessage GetReplyMessage(); 
     public virtual void SetMessageCtrl(IMessageCtrl mc); 
     //[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] 
     public virtual IMessage SyncProcessMessage(IMessage msg); 

     // Properties 
     public virtual object AsyncDelegate { get; } 
     public virtual object AsyncState { get; } 
     public virtual WaitHandle AsyncWaitHandle { get; } 
     public virtual bool CompletedSynchronously { get; } 
     public bool EndInvokeCalled { get; set; } 
     public virtual bool IsCompleted { get; } 
     public IMessageSink NextSink { [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] get; } 
    } 

具體而言,即error CS0122: 'System.Runtime.Remoting.Messaging.Message' is inaccessible due to its protection level。我可以看到這是因爲Message是一個內部類。但是當然,我無法更改它的可訪問性級別,因爲它是System.Runtime命名空間的一部分。並且複製並重命名它會再次導致同樣的問題,當然?
現在任何人都可以幫我嗎?

最後更新 看起來,這一切後,這是SSL證書(見我的回答如下)

+0

web.config中的部分是什麼樣的? – bperreault 2009-06-16 14:08:15

回答

1

我現在認爲,當我們安裝新的SSL證書時,就會出現這個問題。

新證書有我們的支付商HSBC不接受通過它的CPI支付網關的Postcode擴展名。

獲取正確的SSL證書似乎終於解決了這個問題。

1

你需要找出如果新的服務器版本比舊,或者更舊的。如果它是舊版本,則將其升級到較新的版本,並且應該可以正常工作。

如果它更新,那麼它是否會將這些不可序列化的對象置於會話狀態的代碼(您有源代碼)?如果是這樣,那麼你可以創建自己的類來反映舊類的屬性。讓你的類可串行化,並將你的類的一個實例放入會話狀態。當你離開會話狀態時,創建一箇舊類的實例。

+0

服務器版本相同:2.0.50727.3082 – fearoffours 2009-06-23 12:12:57

0

如果代碼以前只使用內存中的狀態提供程序,那麼這可能會很棘手。序列化過程(通過數據庫狀態提供程序使用的BinaryFormatter)需要[Serializable]屬性時,缺省提供程序不需要這是一個痛點。

您可以編輯多少代碼?任何一個?例如,你可以改變把事物置入/離開狀態的代碼嗎?您也許可以使用具有必要屬性的單獨(可序列化)的DTO,並使用您自己的代碼在它們之間進行轉換。

其他選項:

  • 回去的內存供應商(和揮手告別集羣)
  • 寫不使用供應商BinaryFormatter

我有一些對後者的想法,但我懷疑這將是微不足道的

2

如果你真的想要的代碼,你可以嘗試使用反射器的類視圖。至少,它可以幫助您驗證[Serializable]是否是問題類定義的一部分。

+0

這已經很輝煌了。我已經使用Reflector導出代碼,將`[Serializable]`添加到類中,編譯它,覆蓋現有的dll,並解決了即時問題,儘管另一個類現在觸發相同的錯誤。我會重複這個課程的程序(以及任何suseuent的)。 – fearoffours 2009-06-17 21:55:43

+0

很高興幫助。這正是我認爲如果缺失屬性是問題所能做的。 – 2009-06-18 11:48:41

0

如果問題是如何讓應用程序在沒有此錯誤的情況下運行,快速解決方案是將sessionState元素的mode屬性設置爲「InProc」。