2010-11-16 14 views
18

J'utilise BinaryFormatter pour sérialiser un tableau d'instances de classe dans un fichier. Je peux désérialiser cette amende dans la même application. Lorsque je tente la même désérialisation dans une autre application (qui tire dans un fichier commun qui fait le travail) je reçois l'erreur suivante:Comment faire pour déssérialiser BinaryFormatter dans une application différente

{"Could not load file or assembly 'pmlscan, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The module was expected to contain an assembly manifest."} 

où pmlscan est le nom de la demande initiale. Comment puis-je obtenir BinaryFormatter pour ne pas essayer de charger pmlscan?

Répondre

0

Vous ne pouvez pas!

La meilleure option consiste à publier vos classes sérialisables dans un assembly séparé et vous y référer dans le serveur (serializer) et le client (deserializer). De cette façon, vous ne publiez pas l'ensemble de votre code source dans le monde extérieur.

+3

Vous parlez de .Net ici. Tout est possible. (Bien que l'assemblage séparé soit le plus facile). – GvS

+0

Le problème n'essaie pas de charger et d'échouer. La question est "ne pas essayer et charger pmlscan". – Aliostad

+0

En utilisant assemblyRedirect vous n'essayez pas de charger pmlscan. Mais en disant "Vous ne pouvez pas!", Ce n'est pas correct. Puisque c'est une affaire complexe, je te pardonne et je ne t'ai pas déprécié pour cela ;-) – GvS

3

Le sérialiseur binaire code les informations de classe et d'assembly dans un tableau binaire. Lorsque vous désérialisez ce tableau, le désérialiseur utilise cette information pour localiser l'assembly dans lequel réside la classe et, si nécessaire, charge l'assembly dans votre domaine d'application. Si l'autre application n'a pas accès à l'assembly dans lequel réside le type de classe, l'erreur que vous obtenez s'affichera.

Comme mentionné par un autre poster, placez ces classes communes dans un assembly partagé et déployez-les dans l'application client/autre ainsi que dans l'application serveur.

+0

Mon +1, monsieur ... – Aliostad

+2

Eh bien, vous pouvez toujours résoudre à un autre ensemble et un type compatible pour la désérialisation. Cela fonctionne, mais pas pour les faibles de cœur. – leppie

2

Si les classes sont identiques et qu'il s'agit d'un autre assemblage, vous pouvez essayer d'ajouter une section assemblyBinding à votre fichier .config. Vous devez également lire l'article sur Resolving Assembly Loads et le TypeResolve event. En utilisant ces techniques, vous pouvez rediriger le système de types .Net vers un autre type tout en le désérialisant.

Remarque: La migration de vos classes partagées vers un fichier .dll partagé sera une solution plus simple.

1
sealed class PreMergeToMergedDeserializationBinder : SerializationBinder 
{ 
    public override Type BindToType(string assemblyName, string typeName) 
    { 
     return Type.GetType("BinarySerialization.YourClass"); 
    } 
} 
BinaryFormatter bfDeserialize = new BinaryFormatter(); 
bfDeserialize.Binder = new PreMergeToMergedDeserializationBinder(); 
while (fsRead.Position < fsRead.Length) 
{ 
    YourClass sibla = (YourClass)bfDeserialize.Deserialize(fsRead); 
} 

En supposant que vous avez un exe qui sérialise données dans votre « YourClass » et un autre exe de-sérialise les objets YourClass.