2009-04-09 11 views
1

.NET 2.0 introduit VTS (version Tolerant sérialisation, http://msdn.microsoft.com/en-us/library/ms229752(VS.80).aspx)Comment gérer les changements de sérialisation dans .NET 2.0

Un projet de test simple révèle que le comportement par défaut dans la version 2.0 est de ne pas jeter une exception sérialisation si un champ est ajouté à une classe, puis une tentative est faite pour désérialiser une instance de cette classe à partir d'une sérialisation binaire d'une instance de classe qui n'a pas le nouveau champ.

Le comportement par défaut dans 1.1 est de lancer une exception de sérialisation si un champ présent dans la classe est manquant dans les bits sérialisés binaires.

Outre la rétrocompatibilité (le code reposant sur les exceptions levées ne fonctionne plus), il y a un problème plus important: il n'y a pas de moyen évident d'émuler le comportement 1.1 dans 2.0. Comment est-ce que je émule le comportement de «jeter l'exception sur les champs manquants/supplémentaires» 1.1 dans 2.0?

Un grand merci, Miron

Répondre

2

Seuls les champs auxquels l'attribut OptionalFieldAttribute est appliqué doivent ignorer les informations manquantes lors de la désérialisation. Le simple fait de supprimer cet attribut devrait générer une exception et aboutir au même comportement que dans .NET Framework 1.1.

Mise à jour:

Le coupable doit être la propriété AssemblyFormat de la classe BinaryFormatter, qui est FormatterAssemblyStyle.Full par défaut dans 1.1, mais qui est FormatterAssemblyStyle.Simple par défaut dans la version 2.0. En fait, la définition de FormatterAssemblyStyle.Simple dans 1.1 donnera le même comportement que dans 2.0: aucune exception n'est levée. Enfin, dans .NET 2.0, vous avez le OptionalFieldAttribute pour être plus précis.

Définissez cette propriété sur FormatterAssemblyStyle.Full et voyez ce qu'elle fait.

Voir aussi here.

+0

C'est ce que je pensais aussi. Mais un test simple avec une classe avec quelques champs (sans OptionalFieldAttribute, même code sur 1.1 et 2.0) lève une exception de sérialisation sur 1.1 et utilise silencieusement les valeurs par défaut sur 2.0. –

+0

J'ai mis à jour l'entrée pour clarifier. –

+0

Merci! Définir AssemblyProperty fait ce dont j'ai besoin. –

2

En général, les gens veulent être en mesure d'au moins désérialiser les anciennes données, indépendamment des changements à la conception de classe. Malheureusement, BinaryFormatter (basé sur un champ) est très fragile ici - même en passant aux propriétés automatiquement implémentées can break things.

Personnellement, je concevront autour de contrats de données ou des structures similaires qui sont pas mise en œuvre spécifique, et sont extensible. Pour binaire, protobuf-net a beaucoup d'utilisations dans ce domaine.

Si vous voulez vraiment émuler le comportement 1.1 - implémentez ISerializable à la main et lancez l'exception (ou non) vous-même.

+0

Merci, protobuf-net semble une bibliothèque intéressante. Je vais envisager de l'utiliser à l'avenir. –

Questions connexes