Приложение, с которым я работал, не работает, когда я пытаюсь сериализовать типы.
Заявление как
XmlSerializer lizer = new XmlSerializer(typeof(MyType));
производит:
System.IO.FileNotFoundException occurred
Message="Could not load file or assembly '[Containing Assembly of MyType].XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."
Source="mscorlib"
FileName="[Containing Assembly of MyType].XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
FusionLog=""
StackTrace:
at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
Я не определяю никаких специальных сериализаторов для своего класса.
Как я могу решить эту проблему?
c#
xml-serialization
Ирвин
источник
источник
Generate serialization assembly
раскрывающийся список на «Вкл» вместо «Авто».Ответы:
Верьте или нет, это нормальное поведение. Исключение выдается, но обрабатывается XmlSerializer, поэтому, если вы просто игнорируете его, все должно продолжаться в порядке.
Я нахожу это очень раздражающим, и было много жалоб по этому поводу, если вы будете немного искать, но из того, что я прочитал, Microsoft не планирует что-либо делать с этим.
Вы можете избежать появления всплывающих окон Исключения во время отладки, если отключите исключения первого шанса для этого конкретного исключения. В Visual Studio перейдите в « Отладка -> Исключения (или нажмите Ctrl+ Alt+ E)», « Исключения времени выполнения общего языка -> System.IO -> System.IO.FileNotFoundException» .
Информацию об этом можно найти в посте C # XmlSerializer FileNotFound исключение (где обсуждается инструмент Криса Селлса XmlSerializerPreCompiler ).
источник
Как сказал Мартин Шербурн, это нормальное поведение. Сначала конструктор XmlSerializer пытается найти сборку с именем [YourAssembly] .XmlSerializers.dll, которая должна содержать сгенерированный класс для сериализации вашего типа. Так как такая DLL еще не была сгенерирована (они не созданы по умолчанию), выдается исключение FileNotFoundException. Когда это происходит, конструктор XmlSerializer ловит это исключение, и DLL автоматически генерируется во время выполнения конструктором XmlSerializer (это делается путем генерации исходных файлов C # в каталоге% temp% вашего компьютера, а затем компиляции их с помощью компилятора C #). Дополнительные конструкции XmlSerializer для того же типа просто будут использовать уже сгенерированную DLL.
Исключение обрабатывается конструктором XmlSerializer. Вам не нужно ничего делать самостоятельно, вы можете просто нажать «Продолжить» (F5), чтобы продолжить выполнение вашей программы, и все будет хорошо. Если вас беспокоят исключения, останавливающие выполнение вашей программы и вызывающие помощника исключений, либо у вас отключено «Просто мой код», либо у вас установлено FileNotFoundException, чтобы прервать выполнение при вызове, а не когда «Пользователь- необработанное.
Чтобы включить «Просто мой код», выберите Инструменты >> Параметры >> Отладка >> Общие >> Включить только мой код. Чтобы отключить прерывание выполнения при возникновении FileNotFound, перейдите в раздел «Отладка» >> «Исключения» >> «Найти» >> введите «FileNotFoundException» >> снимите флажок «Брошено» в System.IO.FileNotFoundException.
источник
FileNotFoundException
будет выброшен. Разница заключается не в том, как проверяется наличие сборки, а в том, как ее сгенерировать, если определено, что она отсутствует. Раньше он использовал генерацию текстового кода C # с вызовом компилятора C # для создания IL. Начиная с .NET 4.5, он излучает IL напрямую, без использования компилятора.File.Exists()
может быть недостаточно. Поиск сборки не является простым делом, среда выполнения просматривает несколько мест, и я считаю, что поведение меняется в зависимости от среды (консольное приложение по сравнению с размещением в IIS и т. Д.). Я думаю, что должно было быть реализованоTryLoadAssembly()
или что-то подобное.В свойствах проекта Visual Studio (на странице «Сборка», если я правильно помню) есть опция «создать сборку сериализации». Попробуйте включить его для проекта, который генерирует [Содержащий сборку MyType] .
источник
Для этого есть обходной путь. Если вы используете
следует избегать этого исключения. Это сработало для меня.
ВНИМАНИЕ: не используйте несколько раз, иначе у вас будет утечка памяти
Вы потеряете память как сумасшедшую, если будете использовать этот метод для создания экземпляров одного и
XmlSerializer
того же типа более одного раза!Это связано с тем, что этот метод обходит встроенное кэширование, предоставляемое конструкторами
XmlSerializer(type)
andXmlSerializer(type, defaultNameSpace)
(все остальные конструкторы также обходят кэш).Если вы используете какой-либо метод для создания XmlSerializer, который не использует эти два конструктора, вы должны реализовать собственное кэширование, иначе у вас будет кровоизлияние в память.
источник
XmlSerializer
того же типа более одного раза! Это связано с тем, что этот метод обходит встроенное кэширование, предоставляемое конструкторамиXmlSerializer(type)
andXmlSerializer(type, defaultNameSpace)
(все остальные конструкторы также обходят кэш). Если вы используете какой-либо метод для создания объектаXmlSerializer
, не использующего эти два конструктора, вы должны реализовать собственное кэширование, иначе у вас будет кровоизлияние в память.FromTypes
похоже, что он заполняет кэш. Таким образом, это должен быть правильный способ разогреть пустойXmlSerializer
кеш в одном выражении (как предлагает статья), но очень плохой способ извлечь что-либо из него (должен быть сделан только через простейшие конструкторы). В любом случае, я не знал, что это ошибка, я всегда думал, что все утечки должны протекать (например, более продвинутыеXmlSerializer
конструкторы). Я бы даже не подумал об использовании,FromTypes()
так как вы можете просто сделатьtypes.Select(t => new XmlSerializer(t))
.FromTypes
имеет свою привлекательность - даже если все исключения выявляются, это дорогостоящая операция; подход «кэшируйте по-своему», кажется, является единственным обходным решением, поскольку единственное официально поддерживаемое исправление выглядит в неясной веб-сборке. (отредактируйте: откровенно говоря, я весь за то, чтоЯ столкнулся с этой проблемой и не мог обойти ее ни одним из упомянутых решений.
Тогда я наконец нашел решение. Похоже, что сериализатору нужен не только тип, но и вложенные типы. Меняем это:
К этому:
Исправлена проблема для меня. Нет больше исключений или что-нибудь.
источник
var xmlSerializer = new XmlSerializer(typeof(T), typeof(T).GetNestedTypes());
Мое решение состоит в том, чтобы перейти непосредственно к размышлению, чтобы создать сериализатор. Это обходит странную загрузку файла, которая вызывает исключение. Я упаковал это в вспомогательную функцию, которая также заботится о кэшировании сериализатора.
источник
Чтобы избежать исключения, вам нужно сделать две вещи:
Добавьте атрибут System.Xml.Serialization.XmlSerializerAssembly в свой класс. Замените «MyAssembly» на имя сборки, в которой находится MyClass.
Сгенерируйте файл сериализации с помощью утилиты sgen.exe и разверните его вместе со сборкой класса.
'sgen.exe MyAssembly.dll' сгенерирует файл MyAssembly.XmlSerializers.dll
Эти два изменения приведут к тому, что .net непосредственно найдет сборку. Я проверил это, и он работает на .NET Framework 3.5 с Visual Studio 2008
источник
Это исключение также может быть перехвачено помощником по управляемой отладке (MDA) с именем BindingFailure.
Этот MDA полезен, если ваше приложение предназначено для поставки с предварительно собранными сериализованными сборками. Мы делаем это для повышения производительности нашего приложения. Это позволяет нам убедиться в том, что предварительно собранные сборки сериализации правильно собираются нашим процессом сборки и загружаются приложением без повторной сборки на лету.
Это действительно бесполезно, за исключением этого сценария, потому что, как говорили другие авторы, когда ошибка связывания перехватывается конструктором Serializer, сборка сериализации перестраивается во время выполнения. Так что обычно вы можете выключить его.
источник
Функция XmlSerializer.FromTypes не выдает исключение, но она утечка памяти. Вот почему вам необходимо кэшировать такой сериализатор для каждого типа, чтобы избежать утечки памяти для каждого созданного экземпляра.
Создайте свою собственную фабрику XmlSerializer и используйте ее просто:
Фабрика выглядит так:
Более сложная версия без возможности утечки памяти (пожалуйста, ознакомьтесь с кодом):
источник
Устранение ошибок компиляции с другой стороны очень сложно. Эти проблемы проявляются в исключении FileNotFoundException с сообщением:
Вы можете задаться вопросом, какое исключение для файла не найдено связано с созданием объекта сериализатора, но помните: конструктор записывает файлы C # и пытается их скомпилировать. Стек вызовов этого исключения предоставляет некоторую полезную информацию, чтобы поддержать это подозрение. Исключительная ситуация произошла, когда XmlSerializer попытался загрузить сборку, созданную CodeDOM, вызвав метод System.Reflection.Assembly.Load. Исключение не дает объяснения, почему не присутствовала сборка, которую должен был создать XmlSerializer. Как правило, сборка отсутствует, поскольку компиляция не удалась, что может произойти из-за того, что в редких случаях атрибуты сериализации создают код, который компилятор C # не может скомпилировать.
Примечание. Эта ошибка также возникает, когда XmlSerializer работает под учетной записью или в среде безопасности, которая не может получить доступ к временному каталогу.
Источник : http://msdn.microsoft.com/en-us/library/aa302290.aspx
источник
В свойствах проекта Visual Studio есть опция «генерировать сборку сериализации». Попробуйте включить его для проекта, который генерирует [Содержащий сборку MyType].
источник
Пользовательский класс для сериализации:
Я приложил фрагмент кода. Может быть, это может помочь вам.
источник
У меня была похожая проблема, и игнорирование исключения не сработало для меня. Мой код вызывал конфигурацию NServiceBus
Configure.With(...).XmlSerializer()...
Для меня это было связано с изменением платформы для моего проекта.
источник
Просто как ссылка. Взяв из БД ответ и комментарии, я пришел с этим решением, которое близко к решению БД. Это работает отлично во всех моих случаях, и это потокобезопасно. Я не думаю, что использование ConcurrentDictionary было бы нормально.
Использование:
источник
Ваш тип может ссылаться на другие сборки, которые не могут быть найдены ни в GAC, ни в вашей локальной папке bin ==> ...
Можете ли вы привести пример типа, который вы хотите сериализовать?
Примечание: убедитесь, что ваш тип реализует Serializable.
источник
Я получал ту же ошибку, и это происходило из-за типа, который я пытался десериализовать, не имея конструктора по умолчанию без параметров . Я добавил конструктор, и он начал работать.
источник
У меня была та же проблема, пока я не использовал сторонний инструмент для генерации класса из XSD, и он работал! Я обнаружил, что инструмент добавляет некоторый дополнительный код в начало моего класса. Когда я добавил этот код в начало моего исходного класса, это сработало. Вот что я добавил ...
источник
Было много рекомендаций по использованию
ConcurrentDictionary
, но нет убедительных примеров, так что я собираюсь бросить свою шляпу в эту гонку решений. Я не многопоточный разработчик, поэтому, если этот код не является надежным, пожалуйста, говорите ради тех, кто последует за ним.Я видел другие посты, включающие
ConcurrentDictionary
иLazy
загружающие значение. Я не уверен, уместно ли это здесь или нет, но вот код для этого:источник