繁体   English   中英

编译后的序列化异常 dll

[英]Serialization Exception in compiled dll

我继承了电子商务 ASP.NET(c# 代码隐藏)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]添加到受影响的 class 声明中,但这是在我没有 csproj 的已编译 dll 中。 代码在以前的服务器上运行良好,我认为没有对代码进行任何更改,仅更改为 web.config - 我该怎么办?

web.config 的会话状态部分读取<sessionState mode="StateServer" />

UPDATE1 :使用 Reflector,我导出了上面的 class,使其可序列化,重新编译并替换了 dll。订购过程更进了一步,因此我遇到了另一个 dll 编译的 class 的相同错误。我再次能够使用 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 :哈,好吧,我随后发现它正在正确处理付款,但是在用户收到交易之前抛出上面的Unable to serialize the session state error on System.Runtime.Remoting.Messaging.AsyncResult 不好。 现在不确定如何前进......

更新 3:我尝试创建System.Runtime.Remoting.Messaging.AsyncResult class的副本,并使其可序列化,但这会导致不一致的可访问性问题。

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 是一个内部 class。但我肯定无法更改它的可访问性级别,因为它是 System.Runtime 命名空间的一部分。 制作副本并重命名它肯定会再次引发同样的问题,对吗?
现在有人可以帮我吗?

最终更新看起来,毕竟,它是 SSL 证书(见下面我的回答)

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

您需要查明新服务器的版本是否比旧服务器的版本更高,或者是否更旧。 如果它是旧版本,则将其升级到较新版本,一切都应该有效。

如果它较新,那么将这些不可序列化对象放入 session state 的代码(您有源代码)是吗? If so, then you can maybe create your own class to mirror the properties of the old class. Make your class serializable and put an instance of your class into session state. Make an instance of the old class when you take yours out of session state .

我现在相信这个问题是在我们安装新的 SSL 证书时出现的。

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

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

如果代码之前仅使用内存中的 state 提供程序,那么这可能……很棘手。 序列化过程(通过数据库 state 提供程序使用的BinaryFormatter )需要[Serializable]属性,而默认提供程序不需要,这是一个痛点。

您可以编辑多少代码? 任何一个? 例如,您可以更改将东西放入/取出 state 的代码吗? 您也许可以使用具有必要属性的单独(可序列化)DTO,并使用您自己的代码在它们之间进行转换。

其他选项:

  • go 回到内存中的提供者(并向集群挥手告别)
  • 编写一个不使用BinaryFormatter的提供者

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

如果问题只是如何使应用程序运行而不出现此错误,那么快速的解决方案是将 sessionState 元素的模式属性设置为“InProc”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM