1

私は、以下をバイトの配列としてクライアントにシリアル化して返すWebサービスを持っています。

[Serializable]
public class MyFile
{
  public byte[] Data;
  public string FileName;
}

つまり、List(Of MyFile)をクライアントに返します。

次のTYPENAMEを持つクライアントによって消費されます

System.Collections.Generic.List`1[[NorwayTaxService.Streaming+MyFile, NorwayTaxService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

アセンブリ名は次のとおりです。

mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

次の2つのクラスを使用して、逆シリアル化にバインドしています。

[Serializable]
public class MyFileLocal : ISerializable
{
  public byte[] Data;
  public string FileName;

  // The security attribute demands that code that calls 
  // this method have permission to perform serialization.
  [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
  void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
  {
    info.AddValue("Data", Data);
    info.AddValue("FileName", FileName);
  }

  // The security attribute demands that code that calls   
  // this method have permission to perform serialization.
  [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
  private MyFileLocal(SerializationInfo info, StreamingContext context)
  {
    Data = (byte[])info.GetValue("Data", Data.GetType());
    FileName = info.GetString("FileName");
  }
}

sealed class MyFileWebToLocalVersionBinder : SerializationBinder
{
  public override Type BindToType(string assemblyName, string typeName)
  {
    Type typeToDeserialize = null;

    // For each assemblyName/typeName that you want to deserialize to 
    // a different type, set typeToDeserialize to the desired type.
    String assemVer1 = Assembly.GetExecutingAssembly().FullName;
    String typeVer1 = "NorwayTax.Streaming+MyFile";

    if (assemblyName == assemVer1 && typeName == typeVer1)
    {
      // To use a type from a different assembly version,  
      // change the version number. 
      // To do this, uncomment the following line of code. 
      // assemblyName = assemblyName.Replace("1.0.0.0", "2.0.0.0");

      // To use a different type from the same assembly,  
      // change the type name.
      typeName = "MyFileLocal";
    }


    typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));

    return typeToDeserialize;
  }
}

しかし、私の人生の間、そしてGETTYPEステートメントで多くのバリエーションを試している間、私のTYPEは常にNULLです。

たとえば、STACKOVERFLOWの投稿ごとに、次のことを試しました。

typeToDeserialize = Type.GetType(String.Format("{0}, {1}", "System.Collections.Generic.List`1[[NorwayTax.Streaming+MyFile, NorwayTax]]", assemblyName));

しかし、それは機能しませんでした:(

4

1 に答える 1

0

デシリアライズしようとしたオブジェクトタイプは、クライアントアプリケーション/アセンブリ内に存在しませんでした。使うSerializationBinderことで似たようなものにキャストできると思いました。

シリアル化されたリスト/コレクションであるオブジェクトは次のとおりです。

using System;

namespace NorwayTax
{
  public class NorwayTaxFiles
  {
    [Serializable]
    public class NorwayFile
    {
      public string FileName { set; get; }
      public byte[] Data { set; get; }
    }
  }
}

おそらくそれを同様のコレクションにキャストすることは可能ですが、私の一生の間、それを実現することはできませんでした。

私が最終的に行ったことは、上記を独自のDLLに分離することでした。これは、私のWebサービスとクライアントの両方が参照し、完璧に機能し、を必要としませんでしたSerializationBinder

最後に、この演習の要点は、フレームワークツールを使用して、Webサービスから1回のパスで複数のファイルを渡すことでした。興味深いことに、私が渡したファイルはすでに7zを使用して圧縮されていますが、ビジネス要件に従って、アーカイブセット(.001、.002など)に分割されています。

私のソリューションのインスピレーションは、この回答から得られました。クラスライブラリを実際に定義し、同じアセンブリを参照する必要があります

于 2012-08-01T17:41:41.723 に答える