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

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

问题描述

我们有一个序列化问题,仅在.NET 4.5中会发生-相同的代码在.NET 4中可以正常工作。我们正在尝试对具有几个字段的继承类型进行序列化,基类和继承类都标记为 SerializableAttribute 。我们在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.

任何帮助将不胜感激。谢谢,
Omer

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:\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: 

附加的是基类和继承的类代码:
Base

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

}

已安装

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

   /// <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 /如何在运行时更改网络配置文件,包括for-wcf.aspx

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

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