2010-03-20 4 views
2

J'ai créé une application de répertoire et cela fonctionne bien après un moment j'ai aimé faire une mise à niveau pour mon application et j'ai commencé à partir de zéro je n'ai pas hérité de mon ancienne classe, et j'ai aussi « Je veux migrer mes contacts de l'ancienne application du nouveau » , donc je fait une classe d'adaptation pour cette raison dans ma nouvelle application avec le code suivantProblème de sérialisation

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"); 

     } 

    } 
} 

le problème est quand je tente pour lire le fichier traité par mon ancienne application je reçois une exception de sérialisation avec ce message "Unalel to find assembly 'PhoneBook, Version = 1. 0,0,0, Culture = neutre, PublicK eyToken = null "

et la source d'exception est mscorlib. Lorsque je lis le même fichier avec mon ancienne application (Quelle est l'origine du fichier), je n'ai aucun problème et je ne sais pas quoi faire pour que ma classe d'adaptateur fonctionne.

Répondre

2

Lorsque la classe est sérialisée, elle inclut les informations d'assemblage de la classe. Cela permet au désérialiseur de connaître le type de classe à créer avec les données sérialisées. Le problème est que si les deux classes peuvent sembler identiques, ce n'est pas parce qu'elles sont dans des assemblages différents.

La méthode recommandée pour ce faire consiste à toujours placer des classes sérialisables dans une bibliothèque de classes. Ensuite, dans votre situation, la version 2.0 de votre application peut faire référence à l'assembly V1.0, puis vous pouvez désérialiser les objets. Si vos classes V1.0 ne se trouvent pas dans une bibliothèque de classes (par exemple, elles sont intégrées dans un exécutable), vous pouvez créer vos classes V2.0 dans une bibliothèque de classes et ajouter des fonctionnalités à votre application V1.0. pour transformer les classes en classes V2.0.

Postez toutes les questions que vous pourriez avoir comme commentaires.

Espérons que cela aide.

0

Comme indiqué précédemment, le fichier contient le nom d'assembly complet de votre classe, qui a changé dans votre nouveau projet. Si vous votre assemblée, nom de classe et namespaces match, vous pouvez définir le format de l'Assemblée à simple sur le formatter:

BinaryFormatter.AssemblyFormat = FormatterAssemblyStyle.Simple; 

Cette utilisation LoadWithPartialName lorsque le formatter tente de charger ce type. Voir MSDN pour plus d'informations. Vous pouvez également écrire un serialization binder pour résoudre les différences. BinaryFormatter n'est pas très tolérant aux changements d'assemblage.

+0

merci pour tout de vous –

+0

je vais essayer la réponse 2 depuis h'm C# débutant –

1

Je suis arrivé à la conclusion qu'il est OK (à peu près) pour le transport, mais pas bon pour tout type de stockage - c'est just too brittle.

En bref, j'utiliser un autre sérialiseur - mais un contrat basé, fondée sur le type non (donc tout type avec le même cnotract peut partager les données):

  • dans de nombreux cas XmlSerializer fera; il a quelques limitations (types publics et membres), mais fonctionne généralement
  • avec .NET 3.0, DataContractSerializer est utile
  • ou si vous voulez quelque chose en dehors des libs de code, protobuf-net est très rapide et efficace

de ceux-ci, seulement DataContractSerializer sera en mode actuellement support « graphique » (plutôt que les arbres) .

Si vous avez des données existantes que vous combattez, je serais très tenté d'utiliser l'ancien code (ou quelque chose de très proche) pour réécrire les données dans un formulaire basé sur le contrat. Bien que vous disiez que vous venez juste de le créer, alors peut-être que ce n'est pas un problème.

Questions connexes