15

.NET 4.5 でのみ発生するシリアライゼーションの問題があります。同じコードが .NET 4 でも正常に動作します。継承された型をいくつかのフィールドでシリアライズしようとしています。基本クラスと継承されたクラスの両方がSerializableAttributeでマークされています。Web サービスのクライアント側で、サーバーにMethodAccessExceptionがあったという例外が発生します。サーバー自体は例外をスローしません。クライアントのシリアル化プロセスに問題があるようです。.4.5 ではなく .NET 4 でコンパイルしていることに注意することが重要です。

更新: 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: 

基本クラスと継承クラスのコードが添付されています: 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 に答える 5

16

4.5 では、XmlSerializer の実装が、C# コンパイラに依存しないものに置き換えられました。起動時のパフォーマンスと安定性は向上しますが、実装間の互換性の問題が発生する可能性があります。以下を app.config ファイルに追加してみて、問題が解決するかどうかを確認できますか?

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

これが 4.0 で動作するか心配な場合は、実行時にフレームワークのバージョンを検出し、ランタイムが 4.5 以降の場合は構成を動的に変更してみてください。しばらく前に、その方法を説明するブログ投稿を書きました。

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

于 2013-02-05T03:16:16.757 に答える
5

今後の .NET Framework 4.5 Update でこの問題に対処する予定です。アップデートがリリースされ次第、ダウンロード リンクを使用して投稿を更新します。影響を受けるミッション クリティカルなアプリがあり、早急に修正が必要な場合は、Microsoft ドットコムの netfx45compat にお問い合わせください。お客様のリクエストに対応できる Microsoft サポートをご案内いたします。

于 2013-04-14T23:44:49.653 に答える
1

私はあなたのタイプをより詳しく調べました、そして問題はおそらく以下の間の衝突によって引き起こされます:

public virtual object @Value
{
}

ベースと:

private new object Value
{
}

派生クラスで。これが私が試みる2つのことです:

  1. 「新しいオブジェクトの値」を公開してみてください。メンバーアクセスに問題がある可能性があります。
  2. Baseの「@Value」の名前を「BaseValue」またはその他の適切な名前に変更してみてください。「@」記号の使用に問題がある可能性があります。
于 2013-02-05T17:00:07.690 に答える