.NET 4.5 中的序列化中断 [英] Serialization breaks in .NET 4.5

查看:19
本文介绍了.NET 4.5 中的序列化中断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个仅在 .NET 4.5 中发生的序列化问题 - 相同的代码在 .NET 4 中工作正常.我们正在尝试序列化具有几个字段的继承类型,基类和继承类都标有 Serializable 属性.我们在Web服务的客户端得到一个异常,说服务端出现了MethodAccessException,服务端本身没有抛出任何异常,似乎是客户端序列化过程中的问题.需要注意的是,我们是在 .NET 4 中编译的,而不是 .4.5

We have a serialization issue which only happens in .NET 4.5 - same code works fine in .NET 4. we're trying to serialize an inherited type with a few fields, both base and inherited class are marked with SerializableAttribute. We get an exception on the client side of Web service saying that there was a MethodAccessException in the server , the server itself does not throw any exceptions , it seems to be a problem in the client serialization process. It is important to note that we are compiling in .NET 4- not .4.5

更新:在实施ISerailize并忽略Value"属性后,程序确实运行正确,但这意味着我们不得不放弃序列化这个字段.

Update: After implementing the ISerailize and ignoring the "Value" property the program did run correctly, but it means we had to give up on serializing this field.

任何帮助将不胜感激.谢谢,欧玛

any help would be most appreciated. Thanks, Omer

异常详情:

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:IOSIGHTCommonIOSight.BLLWeb ReferenceslocalhostReference.cs:line 25019
       at IOSIGHT.BLL.TypeBankBLL.GetSiteTypes() in C:IOSIGHTCommonIOSight.BLLEntitiesTypeBanksBLL.cs:line 477
  InnerException: 

附上基类和继承类的代码:基础:

Attached is the base and inherited classes code: 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

}

遗传:

[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

   /// <summary>
   /// Called on serialization
   /// </summary>
   /// <param name="info">serialiation info</param>
   /// <param name="context">context</param>
    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 文件中,看看是否能解决问题?

In 4.5, the implementation of XmlSerializer was replaced with one that isn't dependent on the C# compiler. While it provides better startup performance and stability, you might be running into a compatibility issue between the implementations. Can you try adding the following to your app.config file and see if that fixes the issue?

<configuration>
  <system.xml.serialization>
    <xmlSerializer useLegacySerializerGeneration="true"/>
  </system.xml.serialization>
</configuration>

如果您担心在 4.0 上进行这项工作,您可以尝试在运行时检测框架的版本,如果运行时为 4.5 或更高,则动态更改配置.不久前我写了一篇博文解释了如何做到这一点:

If you're concerned about having this work on 4.0, you could try detecting the version of the framework at runtime, and dynamically change the configuration if the runtime is 4.5 or higher. I wrote a blog post a while back explaining how to do that:

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

这篇关于.NET 4.5 中的序列化中断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆