views:

109

answers:

2

We save and read files by (de) serializing a class named "DocumentClass". All was working well, untill we added 2 more fields to the documentclass. (We think that's the problem)

When we now try to open files that were serialized by the previous edition, we get an error.

System.ArgumentException: Object of type 'System.Int32' cannot be converted to type 'System.String'. at SoftwareProject.Componenten.Bestand.DocumentClass.d(String A_0) at de..ctor(String A_0) at g.a(String A_0)

The method generating the error is the method "Read". (DocumentClass.d() is the obfuscated name )

But things get weirder: when we open the file in VS debug mode, no error is generated, but all fields in the documentclass are 0 or null ???

We are lost here ... please help ... We've added the [OptionalField] attribute to the new fields, but that doesn't help ..

Why are all values null in debug mode ?? And where is the runtime error coming from ? How can we debug it ?

Thanks in advance!!

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;
  }
}
A: 

I assume you are using BinaryFormatter? This serializer is notoriously brittle, since it (by default) includes the field-name in the stream; this impacts obfuscation particularly badly. Presumably the obfuscator is now choosing new named for the fields (perhaps at random, perhaps due to the new fields), and so it can't deserialize correctly.

A few options:

  • don't obfuscate the DTO
  • implement ISerializable so the field names don't matter
  • use a serializer that doesn't care about field names

I'd personally opt for the latter, but I'm a bit biased ;-p I know of people using protobuf-net with obfuscated classes; the data only includes numeric markers, so the meaning isn't really exposed (except of course, by inspection of the data - post codes etc, but that is the job of encryption).

Marc Gravell
A: 

I think you need to use Custom Serialization

bruno conde