Serialization problem

We save and read files by (de) serializing a class named "DocumentClass". Everything worked well until we added 2 more fields to the document class. (We think the problem is)

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

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

The method that generates the error is the "Read" method. (DocumentClass.d () is a confusing name)

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

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

Why are all values ​​null in debug mode? And where does the runtime error come 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;
     }
}

      

+2


source to share


3 answers


I assume you are using BinaryFormatter

? This serializer is known to be fragile because it (by default) includes the field name in the stream; this affects obfuscation especially badly . Presumably the obfuscator is now picking a new name for the fields (perhaps by accident, perhaps due to the new fields) and therefore it cannot deserialize correctly.

Several variants:



  • do not obfuscate DTOs
  • implement ISerializable

    , so the field names don't matter.
  • use a serializer that doesn't care about field names

I would choose the latter, but I'm a little biased; -p I know people using protobuf-net with obfuscated classes; the data only includes numeric tokens, so the value is not displayed (except of course for data validation - postal codes, etc., but that's an encryption task).

0


source


.Net has something called "Version Tolerant Serialization" which most likely solves this problem;)

You should check out this easy to understand example of object serialization:



http://programming.flashadventures.com/c-sharp/writing-objects-to-files-serialization/

+1


source


I think you need to use Custom Serialization

0


source







All Articles