2012-07-31 70 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

相關問題