【问题标题】:"System.Collections.Generic.List`1" SerializationBinder BindToType"System.Collections.Generic.List`1" SerializationBinder BindToType
【发布时间】:2012-07-31 17:52:44
【问题描述】:

我有一个网络服务,它将以下内容作为字节数组序列化并返回给客户端:

[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

我正在使用以下两个类来绑定反序列化:

[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));

但它没有工作:(

【问题讨论】:

  • ]] 括号放错了位置。
  • 假设您的意思是 typeToDeserialize = Type.GetType(String.Format("{0}, {1}]]", "System.Collections.Generic.List`1[[NorwayTax.NorwayTaxService.StreamingService .Streaming+MyFile,NorwayTax", assemblyName)); ?我试过了,它会抛出一个错误..请详细说明。
  • 我对@9​​87654321@问题的回答会对您有所帮助。

标签: c# serializationbinder


【解决方案1】:

我尝试反序列化的对象类型在客户端应用程序/程序集中不存在。 我认为通过使用 SerializationBinder 我可以将其转换为类似的对象。

这是对象,它是一个序列化的列表/集合:

using System;

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

也许可以将它放入一个类似的集合中,但在我的一生中,我无法实现它。

我最终所做的是将上述内容隔离到它自己的 DLL 中,我的 Web 服务和客户端都引用了该 DLL,它可以完美运行,并且不需要 SerializationBinder

最后,本练习的重点是使用框架工具一次性从 Web 服务传递多个文件。有趣的是,我传递的文件已经使用 7z 进行了压缩,但根据业务要求将其拆分为一个存档集(.001、.002 等)。

我的解决方案的灵感来自这个答案:You should really define a class library with in it and reference that same assembly

【讨论】:

    猜你喜欢
    • 2022-01-07
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多