编译后的DLL中的序列化异常

时间:2009-06-16 14:03:51

标签: c# asp.net web-applications serialization dll

我继承了电子商务ASP.NET(c#code behind)Web应用程序。我们最近搬了服务器,这有点麻烦。我对IIS服务器配置和处理这样的大型项目的经验很少。大多数问题现在已经解决,但是当客户试图付款时,我们遇到了关键部分的问题。
当客户确认付款时,应用程序遇到以下错误:

    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

Google搜索结果表明我应该将[Serializable]添加到受影响的类声明中,但这是在我没有csproj的已编译的dll中。 代码在以前的服务器上工作正常,我不相信对代码进行了任何更改,只对web.config进行了更改 - 我该怎么办?

web.config的sessionstate部分读取<sessionState mode="StateServer" />

UPDATE1 :使用Reflector,我导出了上面的类,使其可序列化,重新编译并替换了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 :哈,我后来发现它正在正确处理付款,但是在用户收到“{1}”之前,会在Unable to serialize the session state上抛出上述System.Runtime.Remoting.Messaging.AsyncResult错误交易。不好。不确定如何向前迈进...

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证书(请参阅下面的答案)

5 个答案:

答案 0 :(得分:2)

如果您真的想要代码,可以尝试使用Reflector的Class View。至少,它可以帮助您验证[Serializable]是否是问题类定义的一部分。

答案 1 :(得分:1)

您需要了解新服务器是旧版本还是较旧版本的版本。如果它是旧版本,则将其升级到较新版本,事情应该有效。

如果它更新,那么你的代码(你有源代码)是否将这些不可序列化的对象置于会话状态?如果是这样,那么你可以创建自己的类来镜像旧类的属性。使您的类可序列化并将您的类的实例放入会话状态。当你离开会话状态时,创建一个旧类的实例。

答案 2 :(得分:1)

我现在认为,当我们安装新的SSL证书时出现了这个问题。

新证书有邮政编码扩展,我们的支付商HSBC不接受它的CPI支付网关。

安装正确的SSL证书似乎终于解决了这个问题。

答案 3 :(得分:0)

如果代码以前只使用内存状态提供程序,那么这可能会很棘手。令人痛苦的是,当默认提供程序没有时,序列化过程(通过BinaryFormatter,数据库状态提供程序使用)需要[Serializable]属性。

您可以编辑多少代码?任何一个?例如,您是否可以更改将事物置于/退出状态的代码?您也许可以使用具有必要属性的单独(可序列化)DTO,并使用您自己的代码在它们之间进行转换。

其他选择:

  • 返回内存提供商(并向群集挥手告别)
  • 编写不使用BinaryFormatter
  • 的提供程序

我对后者有一些想法,但我怀疑它会是微不足道的

答案 4 :(得分:0)

如果问题是如何在没有此错误的情况下运行应用程序,则快速解决方案是将sessionState元素的mode属性设置为“InProc”。