.NET 4.5中的序列化中断

我们有一个只在.NET 4.5中发生的序列化问题 – 相同的代码在.NET 4中工作正常。我们试图用几个字段序列化一个inheritance的类型,基类和inheritance类都用SerializableAttribute标记。 我们在Web服务的客户端获得一个exception,说服务器中有一个MethodAccessException ,服务器本身不会抛出任何exception,这似乎是客户端序列化过程中的一个问题。 重要的是要注意我们在.NET 4-而不是.4.5中进行编译

更新:实现ISerailize并忽略“Value”属性后,程序运行正常,但这意味着我们不得不放弃序列化此字段。

非常感激任何的帮助。 谢谢,奥梅尔

例外细节:

System.Web.Services.Protocols.SoapException occurred HResult=-2146233087 Message=System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.InvalidOperationException: There was an error generating the XML document. ---> System.MethodAccessException: Attempt by method 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write88_DeviceSiteTypeInfo(System.String, System.String, IOSIGHT.Info.DeviceSiteTypeInfo, Boolean, Boolean)' to access method 'IOSIGHT.Info.DeviceSiteTypeInfo.get_Value()' failed. at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write88_DeviceSiteTypeInfo(String n, String ns, DeviceSiteTypeInfo o, Boolean isNullable, Boolean needType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1310_GetSiteTypesResponse(Object[] p) at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer2089.Serialize(Object objectToSerialize, XmlSerializationWriter writer) at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) --- End of inner exception stack trace --- at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) at System.Web.Services.Protocols.SoapServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream) at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues) at System.Web.Services.Protocols.WebServiceHandler.Invoke() --- End of inner exception stack trace --- Source=System.Web.Services Actor="" Lang="" Node="" Role="" StackTrace: at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at IOSIGHT.BLL.localhost.IOSightWS.GetSiteTypes() in C:\IOSIGHT\Common\IOSight.BLL\Web References\localhost\Reference.cs:line 25019 at IOSIGHT.BLL.TypeBankBLL.GetSiteTypes() in C:\IOSIGHT\Common\IOSight.BLL\Entities\TypeBanksBLL.cs:line 477 InnerException: 

附件是基类和inheritance类代码: Base

 [Serializable()] public class TypeBankInfo { #region "Fields" private int _id = 0; private string _Name = string.Empty; private string _description = string.Empty; private object _value = null; #endregion #region "Constructors" public TypeBankInfo() { } public TypeBankInfo(int ID, string name) : this() { this._id = ID; this.Name = name; } public TypeBankInfo(int ID, string name, string description) : this(ID, name) { this._description = description; this._value = Value; } public TypeBankInfo(int ID, string name, string description, object value) : this(ID, name, description) { this._value = value; } #endregion #region "Properties" public virtual string Name { get { return this._Name; } set { this._Name = value; } } public virtual string Description { get { return _description; } set { _description = value; } } public virtual int ID { get { return _id; } set { _id = int.Parse(value.ToString()); } } public virtual object @Value { get { return this._value; } set { this._value = value; } } #endregion } 

Intheried

 [Serializable()] public class DeviceSiteTypeInfo : TypeBankInfo, ISerializable { #region "Fields" private EntityTypeEnum _entitytype = EntityTypeEnum.Site; private DeviceIOTemplateInfo[] _IOTemplates; private CaptionInfo[] _Captions; private int _parentClassID; #endregion #region "Constructors" public DeviceSiteTypeInfo() { } public DeviceSiteTypeInfo(int id, string name) : base(id, name) { } public DeviceSiteTypeInfo(int id, string name, string description) : base(id, name, description) { } // The special constructor is used to deserialize values. public DeviceSiteTypeInfo(SerializationInfo info, StreamingContext context) { //parent fields ID = (int)info.GetValue("_id", typeof(int)); Name = (string)info.GetValue("_Name", typeof(string)); Description = (string)info.GetValue("_description", typeof(string)); //my fields _entitytype = (EntityTypeEnum)info.GetValue("_entitytype", typeof(EntityTypeEnum)); _IOTemplates = (DeviceIOTemplateInfo[])info.GetValue("_IOTemplates", typeof(DeviceIOTemplateInfo[])); _Captions = (CaptionInfo[])info.GetValue("_Captions", typeof(CaptionInfo[])); _parentClassID = (int)info.GetValue("_parentClassID", typeof(int)); } #endregion #region "Properties" public EntityTypeEnum EntityTypeID { get { return this._entitytype; } set { this._entitytype = value; } } [EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] private new object Value { get { return base.Value; } set { base.Value = value; } } public CaptionInfo[] Captions { get { return this._Captions; } set { this._Captions = value; } } public DeviceIOTemplateInfo[] IOTemplates { get { return this._IOTemplates; } set { this._IOTemplates = value; } } public int ParentClassID { get { return this._parentClassID; } set { this._parentClassID = value; } } #endregion #region Methods ///  /// Called on serialization ///  /// serialiation info /// context public void GetObjectData(SerializationInfo info, StreamingContext context) { // parent fields info.AddValue("_id", ID, typeof(int)); info.AddValue("_Name", Name, typeof(string)); info.AddValue("_description", Description, typeof(string)); //my fields info.AddValue("_entitytype", _entitytype, typeof(EntityTypeEnum)); info.AddValue("_IOTemplates", _IOTemplates, typeof(DeviceIOTemplateInfo[])); info.AddValue("_Captions", _Captions, typeof(CaptionInfo[])); info.AddValue("_parentClassID", _parentClassID, typeof(int)); } #endregion } 

在4.5中,XmlSerializer的实现被替换为不依赖于C#编译器的实现。 虽然它提供了更好的启动性能和稳定性,但您可能会遇到实现之间的兼容性问题。 您可以尝试将以下内容添加到app.config文件中,看看是否可以解决问题吗?

      

如果您担心在4.0上运行此工作,则可以尝试在运行时检测框架的版本,并在运行时为4.5或更高时动态更改配置。 我写了一篇博客文章,后来解释了如何做到这一点:

http://blogs.msdn.com/b/youssefm/archive/2010/01/21/how-to-change-net-configuration-files-at-runtime-including-for-wcf.aspx

我们希望在即将推出的.NET Framework 4.5更新中解决此问题。 一旦更新发布,我将使用下载链接更新post。 如果您的任务关键型应用程序受到影响,请联系Microsoft dot com的netfx45compat,并急需修复。 我可以帮助您找到可以帮助您的请求的Microsoft支持。

我更仔细地查看了你的类型,问题可能是由以下方面的冲突引起的:

 public virtual object @Value { } 

在基地和:

 private new object Value { } 

在派生类上。 以下是我要尝试的两件事:

  1. 尝试公开“新对象价值”。 可能存在成员访问问题。
  2. 尝试将Base的“@Value”重命名为“BaseValue”或其他适当的名称。 使用“@”符号时可能会出现问题。

我也有这样的序列化失败。 在我的情况下,它是由[DefaultValue(..)]属性的类型不匹配引起的。 对于decimal类型的属性,我有一个附加的默认值"1.0d" (双"1.0d" )。 似乎XmlSerializer的新实现不能再转换这些值,但旧的可以。 还可以通过在“App.config”中添加属性来切换回旧版本的XmlSerializer,但Microsoft(和我)不建议这样做。 希望这有助于某人。