views:

105

answers:

3

I have created a phonebook application and it works fine after a awhile i liked to make an upgrade for my application and i started from scratch i didn't inherit it from my old class,and i successes too ,my request "I want to migrate my contacts from the old application to the new one" ,so i made an adapter class for this reason in my new application with the following code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace PhoneBook
{
    class Adapter
    {
        PhoneRecord PhRecord;   //the new application object
        CTeleRecord TelRecord; //the old application object
        string fileName;

    public Adapter(string filename)
    {
        fileName = filename;
    }

    public void convert()
    {

        PhRecord = new PhoneRecord(); 
        TelRecord = new CTeleRecord();

        FileStream OpFileSt = new FileStream(fileName, FileMode.Open,FileAccess.Read);


        BinaryFormatter readBin = new BinaryFormatter();



        for (; ; )
        {
            try
            {
                TelRecord.ResetTheObject();

                TelRecord = (CTeleRecord)readBin.Deserialize(OpFileSt);

                PhRecord.SetName = TelRecord.GetName;
                PhRecord.SetHomeNumber = TelRecord.GetHomeNumber;
                PhRecord.SetMobileNumber = TelRecord.GetMobileNumber;
                PhRecord.SetWorkNumber = TelRecord.GetWorkNumber;
                PhRecord.SetSpecialNumber = TelRecord.GetSpecialNumber;
                PhRecord.SetEmail = TelRecord.GetEmail;
                PhRecord.SetNotes = TelRecord.GetNotes;
                PhBookContainer.phBookItems.Add(PhRecord);


            }
            catch (IOException xxx)
            {
                MessageBox.Show(xxx.Message);


            }
            catch (ArgumentException tt)
            {
                MessageBox.Show(tt.Message);
            }
            //if end of file is reached
            catch (SerializationException x)
            {
                MessageBox.Show(x.Message + x.Source);
                break;
            }

        }
        OpFileSt.Close();

        PhBookContainer.Save(@"d:\MyPhBook.pbf");

         }

    }
}

the problem is when i try to read the file ctreated by my old application i receive serialization exception with this message "Unalel to find assembly 'PhoneBook,Version=1.0.0.0,Culture=neutral,PublicK eyToken=null"

and the source of exception is mscorlib.

when i read the same file with my old application (Which is the origin of the file) i have no problem and i don't know what to do to make my adapter class work.

+2  A: 

When the class is serialised, it includes the assembly information of the class. It does this so the deserializer knows what type of class to create with the serialised data.

The problem is that while the two classes may seem to be identical, they are not because they are in different assemblies.

The recommended way to do this is to always put serializable classes in a class library. Then in your situation V2.0 of your application can reference the V1.0 assembly, and then you can deserialize the objects.

If your V1.0 classes aren't in a class library (e.g. they're embedded in an executable), you can build your V2.0 classes in a class library, and add functionality to your V1.0 app to transform classes to V2.0 classes.

Post any questions you might have as comments.

Hope this helps.

Binary Worrier
A: 

As previously stated the file contains the fully qualified assembly name of your class, which has changed in your new project. If you your assembly, class name and namespaces match, you can set the Assembly format to simple on the formatter:

BinaryFormatter.AssemblyFormat = FormatterAssemblyStyle.Simple;

This use LoadWithPartialName when the formatter tries to load this type. See MSDN for more info.

You could also write a serialization binder to resolve the differences.

Todd
thanks for all of you
Falcon eyes
i will try answer 2 since h'm C# beginner
Falcon eyes
+1  A: 

BinaryFormatter is not very tolerant to assembly changes. I long ago reached the conclusion that it is OK (just about) for transport, but not good for any kind of storage - it is just too brittle.

In short, I would use another serializer - but contract-based, not type-based (so any type with the same cnotract can share the data):

  • in many cases XmlSerializer will do; it has some limitations (public types and members), but it works generally
  • with .NET 3.0, DataContractSerializer is useful
  • or if you want something outside of the code libs, protobuf-net is very fast and efficient

Of those, only DataContractSerializer will currently support "graph" mode (rather than trees).

If you have existing data that you're fighting, I would be sorely tempted to use the old code (or something very close to it) to re-write the data in a contract-based form. Although you say you've only just created it, so maybe this isn't a problem.

Marc Gravell