2009-09-11 130 views
2

我们通过(de)序列化一个名为“DocumentClass”的类来保存和读取文件。 一切正常,直到我们添加了2个字段到文档类。 (我们认为这是问题)序列化问题

当我们现在尝试打开由以前版本序列化的文件时,我们得到一个错误。

System.ArgumentException:System.Int32类型的对象无法转换为类型'System.String'。 在SoftwareProject.Componenten.Bestand.DocumentClass.d(字符串A_0) 在de..ctor(字符串A_0) 在G.A(字符串A_0)

的方法,产生所述误差是方法 “读取”。 (DocumentClass.d()是混淆的名称)

但事情变得更加怪异:当我们在VS调试模式下打开文件时,没有错误产生,但文档类中的所有字段都是0或空?

我们在这里输了...请帮助... 我们已经添加了[OptionalField]属性到新的领域,但这并不能帮助..

为什么在调试空的所有值模式?? 运行时错误来自哪里?我们如何调试它?

在此先感谢!

public static DocumentClass Read(string fullFilePath) 
{ 

    DocumentClass c = new DocumentClass(); 
    Stream s = File.OpenRead(fullFilePath); 
    BinaryFormatter b = new BinaryFormatter(); 
    //b.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; 
    b.Binder = new MyCustomBinder(); 

    try 
    { 
     c = (DocumentClass)b.Deserialize(s); 
    } 
    catch(Exception exc) 
    { 
     s.Close(); 
     throw exc; 
    } 
    finally 
    { 
     s.Close(); 
    } 
    return c; 
     } 


     public class MyCustomBinder : SerializationBinder { 

    public override Type BindToType(string assemblyName, string typeName) { 
     Type tyType = null; 
     string sShortAssemblyName = assemblyName.Split(',')[0]; 
     Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies(); 
     if (sShortAssemblyName.ToLower() == "debugAssemblyName") 
     { 
     sShortAssemblyName = "AppAssemblyName"; 
     } 
     foreach (Assembly ayAssembly in ayAssemblies) { 
     if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0]) { 
     tyType = ayAssembly.GetType(typeName); 
     break; 
     } 
     } 
     return tyType; 
    } 
} 

回答

0

我假定您使用的是BinaryFormatter?这个序列化器非常脆弱,因为它(默认情况下)在流中包含字段名称;这会影响混淆particularly badly。据推测,混淆器现在选择新的字段(可能是随机的,也许是由于新字段),所以它不能正确地反序列化。

有几个选项:

  • 不要混淆DTO
  • 实施ISerializable等等领域名字没有关系
  • 使用不关心字段名称串行

我会亲自选择后者,但我有点偏向; -p我知道使用protobuf-net与混淆类的人;数据只包含数字标记,所以其含义并不真正暴露(当然,除了检查数据 - 邮政编码等,但这是加密的工作)。