我继承了电子商务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证书(请参阅下面的答案)
答案 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”。