Я получаю исключение FileLoadException при попытке десериализации типа с помощью NetDataContractSerializer :
Указанное имя сборки или кодовая база недопустимы.(Исключение из HRESULT: 0x80131047)
Эта ошибка не относится конкретно к сериализатору;попытка загрузить тип во время выполнения по его квалифицированному имени сборки приводит к той же ошибке.
Я подключил слушатель к событию AssemblyResolve , чтобы увидеть, что происходит:
ResolveEventHandler reh = (o, e) =>
{
var tryGet = AppDomain.CurrentDomain.GetAssemblies()
.Where(x => x.FullName == e.Name).FirstOrDefault();
if (tryGet != null)
return tryGet;
//EDIT: Crap, the following line is a stupid bug STUPID! Ignore!
return Type.GetType(e.Name).Assembly;
};
using (var stream = System.IO.File.OpenRead(serializedObjectFilename))
{
try
{
AppDomain.CurrentDomain.AssemblyResolve += reh;
var ser = new NetDataContractSerializer();
return ser.Deserialize(stream) as MyType;
}
finally
{
AppDomain.CurrentDomain.AssemblyResolve -= reh;
}
}
Заглавное «странное поведение» можно увидеть отладкой через обработчик.Хотя tryGet
никогда не является null
(требуемая сборка, в данном случае, всегда загружается в домен приложений), операция всегда завершается ошибкой , если оставить ее себе. Другими словами, вызов Type.GetType(e.Name).Assembly
приведет к созданию исключения FileLoadException. Редактировать: Я совмещал строгое имя сборки с именем, определенным сборкой, типа;пожалуйста, игнорируйте эту ошибку.По иронии судьбы, это не выдает другую ошибку, поэтому я не уловил этого, прежде чем задавать этот вопрос.
Еще один бит информации: Assembly.Load(e.Name)
всегда возвращает действительную сборку.Я не уверен, почему это работает, в то время как метод, используемый за кулисами во время десериализации, терпит неудачу.
Fusion Log сообщает, что загрузчик пытается загрузить правильную сборку, но так как сборка не найдена в приватнойпуть к исполняемому файлу, он завершается ошибкой.
Почему выполняется попытка загрузить сборку, когда сборка уже загружена в домен приложений ??
Подробнее о ведении журнала Fusion ...
Я собрал всю загрузку сборки до и во время вызова метода, который вызывает исключение.Вот соответствующие журналы, в порядке создания:
- Частичное связывание СБОЙ
- Попытка загрузить сборку только по имени
- Только проверка базы приложения
- Частичное связывание через LoadFrom SUCCEEDED
- Where-ref bind.Расположение указывает на то, где находится ссылка на файл
- Я полагаю, что VS использует LoadFrom при загрузке ссылок в решении
- Привязка строгого имени FAILED
- Неизвестно, что вызвало эту попытку загрузки
- Только проверял базу приложения
AFAICT, Visual Studio загружает сборку в домен приложения решения (ffs, я желаю Fusion Logзахватил домен приложения, в котором была предпринята попытка загрузки, в конце концов, он записывает вызывающую сборку).
После этого я звоню по десериализации.Результатом является один журнал в Fusion:
Результат привязки: hr = 0x80070002.Системе не удается найти указанный файл.
Снова Fusion пытается загрузить из базы приложения исполняемого файла его строгое имя.Одна хорошая вещь;он пытается загрузить из GAC, поэтому после развертывания I может не иметь такой же проблемы.Но я все еще не понимаю, почему сборка не может быть расположена в домене приложения.
Другие интересные вещи ...
Это вызывает вызов десериализации:
MyType test = new MyType ();
var serialized = Serializer.ToXml(test);
// the following line fails with a FileLoadException
var deserialized = Serializer.FromXml<MyType>(serialized);
, где ToXml и FromXml оба используют NetDataContractSerializer и Write / ReadObject.Сборка загружается на раннем этапе выполнения из каталога установки пакета, но NDCS по какой-то причине не хочет использовать сборку, как она обнаружена в AppDomain.Этот тест показывает, что не может быть проблем с управлением версиями.