2012-07-31 91 views
0

我有searializes并返回一个web服务下面给客户端作为字节数组:“System.Collections.Generic.List`1” SerializationBinder BindToType

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

即,我返回一个列出(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语句上尝试了许多变体,我的T YPE始终为NULL。

例如,每StackOverflow上一个帖子,我想:

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

但它没有工作:(

+0

]括号错误放置。 – 2012-07-31 18:21:42

+0

假设你的意思是 typeToDeserialize = Type.GetType(String.Format(“{0},{1}]]”,“System.Collections.Generic.List'1 [[NorwayTax.NorwayTaxService.StreamingService.Streaming + MyFile,NorwayTax “,assemblyName)); ? 我试过了,它会引发错误..请详细说明。 – flaZer 2012-07-31 18:32:56

+0

我认为解锁这个的关键是,而不是专注于System.Collections.Generic.List,因为实际上,这种类型不存在于我的客户端组装:NorwayTaxService.Streaming + MyFile。 – flaZer 2012-08-01 13:48:49

回答

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服务一次传递多个文件。有趣的是,我传递的文件已经使用7z进行了压缩,但是按照业务需求分解为档案集(.001,0.002等)。

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

相关问题