Как заставить BinaryFormatter десериализоваться в другом приложении - PullRequest
18 голосов
/ 16 ноября 2010

Я использую BinaryFormatter для сериализации массива экземпляров классов в файл. Я могу десериализовать этот штраф в одном приложении. Когда я пытаюсь выполнить ту же десериализацию в другом приложении (которое извлекает общий файл, который выполняет работу), я получаю следующую ошибку:

{"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."}

где pmlscan - имя исходного приложения. Как заставить BinaryFormatter не пытаться загрузить pmlscan?

Ответы [ 5 ]

18 голосов
/ 24 сентября 2011
3 голосов
/ 16 ноября 2010

Бинарный сериализатор кодирует информацию о классе и сборке в двоичный массив.Когда вы десериализуете этот массив, десериализатор использует эту информацию, чтобы найти сборку, в которой находится класс, и (при необходимости) загружает сборку в домен вашего приложения.Если у другого приложения нет доступа к сборке, в которой находится тип класса, вы увидите ошибку, которую вы получаете.

Как упоминалось другим автором, поместите эти общие классы в общую сборку.и разверните их на клиентском / другом приложении, а также на серверном приложении.

2 голосов
/ 16 ноября 2010

Если классы одинаковые и это просто еще одна сборка, вы можете попробовать добавить раздел assemblyBinding в ваш файл .config.

Также следует прочесть статью о разрешении сборочных нагрузок и событии TypeResolve .

Используя эти методы, вы можете перенаправить систему типов .Net на другой тип при десериализации.

Примечание: Перенос общих классов в общий .dll будет более простым решением.

1 голос
/ 01 сентября 2014
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);
}

Предполагается, что у вас есть исполняемый файл, который сериализует данные в вашем "YourClass", и другой исполняемый файл, который десериализует объекты YourClass.

0 голосов
/ 16 ноября 2010

Вы не можете!

Лучший вариант - опубликовать ваши сериализуемые классы в отдельной сборке, и вы ссылаетесь на них на сервере (сериализатор) и клиенте (десериализатор). Таким образом, вы не публикуете весь свой исходный код во внешнем мире.

...