Предоставление XmlSerializer FileNotFoundException в конструкторе

Попробуйте этот фильтр поиска jquery

$('[data-search]').on('keyup', function() {
	var searchVal = $(this).val();
	var filterItems = $('[data-filter-item]');

	if ( searchVal != '' ) {
		filterItems.addClass('hidden');
		$('[data-filter-item][data-filter-name*="' + searchVal.toLowerCase() + '"]').removeClass('hidden');
	} else {
		filterItems.removeClass('hidden');
	}
});
.container {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 50%;
}

.search {
	margin-bottom: 30px;
}

.items {
	
}

[data-filter-item] {
	padding: 15px;
	background-color: #ccc;
	border: 1px solid #fff;
}

.hidden {
	display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<div class="container">
	<div class="search">
		<input type="text" placeholder="search" data-search />
	</div>
	<div class="items">
		<div data-filter-item data-filter-name="apple">Apple</div>
		<div data-filter-item data-filter-name="google">Google</div>
		<div data-filter-item data-filter-name="microsoft">Microsoft</div>
		<div data-filter-item data-filter-name="hp">HP</div>
		<div data-filter-item data-filter-name="dell">Dell</div>
		<div data-filter-item data-filter-name="samsung">Samsung</div>
	</div>
</div>

340
задан Peter Mortensen 13 November 2013 в 07:16
поделиться

10 ответов

Вы не поверите, но это нормальное поведение. Выдается исключение, но обрабатывается XmlSerializer, поэтому, если вы просто проигнорируете его, все должно продолжаться нормально.

Я нашел это очень раздражающим, и было много жалоб на это, если вы немного поищете, но из чего Я читал, что Microsoft не планирует что-либо с этим делать.

Вы можете избежать появления всплывающих окон исключений все время во время отладки, если отключите исключения первого шанса для этого конкретного исключения. В Visual Studio перейдите в Отладка -> Исключения (или нажмите Ctrl + Alt + E )), Исключения среды CLR -> System.IO -> System.IO.FileNotFoundException .

375
ответ дан 23 November 2019 в 00:36
поделиться

Замеченный много рекомендаций использовать ConcurrentDictionary, но никакие твердые примеры его, таким образом, я собираюсь бросить свою шляпу в эту гонку решения. Я не ориентированный на многопотоковое исполнение разработчик, поэтому если этот код не является основательным, говорите ради тех, кто следует после.

public static class XmlSerializerHelper
{
    private static readonly ConcurrentDictionary<Type, XmlSerializer> TypeSerializers = new ConcurrentDictionary<Type, XmlSerializer>();

    public static XmlSerializer GetSerializer(Type type)
    {
        return TypeSerializers.GetOrAdd(type,
        t =>
        {
            var importer = new XmlReflectionImporter();
            var mapping = importer.ImportTypeMapping(t, null, null);
            return new XmlSerializer(mapping);
        });
    }
}

я видел, что другие сообщения включают ConcurrentDictionary и Lazy загрузка значения. Я не уверен, релевантно ли это здесь или нет, но здесь является кодом для этого:

private static readonly ConcurrentDictionary<Type, Lazy<XmlSerializer>> TypeSerializers = new ConcurrentDictionary<Type, Lazy<XmlSerializer>>();

public static XmlSerializer GetSerializer(Type type)
{
    return TypeSerializers.GetOrAdd(type,
    t =>
    {
        var importer = new XmlReflectionImporter();
        var mapping = importer.ImportTypeMapping(t, null, null);
        var lazyResult = new Lazy<XmlSerializer>(() => new XmlSerializer(mapping), LazyThreadSafetyMode.ExecutionAndPublication);
        return lazyResult;
    }).Value;
}
0
ответ дан 23 November 2019 в 00:36
поделиться

С другой стороны, устранение ошибок компиляции очень сложно. Эти проблемы проявляются в FileNotFoundException с сообщением:

File or assembly name abcdef.dll, or one of its dependencies, was not found. File name: "abcdef.dll"
   at System.Reflection.Assembly.nLoad( ... )
   at System.Reflection.Assembly.InternalLoad( ... )
   at System.Reflection.Assembly.Load(...)
   at System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly() 

Вы можете задаться вопросом, какое отношение имеет исключение «файл не найден» к созданию экземпляра объекта сериализатора, но помните: конструктор записывает файлы C # и пытается их скомпилировать. Стек вызовов этого исключения предоставляет некоторую полезную информацию, подтверждающую это подозрение. Исключение произошло, когда XmlSerializer пытался загрузить сборку, созданную CodeDOM, вызывая метод System.Reflection.Assembly.Load. Исключение не дает объяснения, почему сборка, которую должен был создать XmlSerializer, отсутствовала. Как правило, сборка отсутствует из-за сбоя компиляции, что может произойти из-за того, что в редких случаях This error also occurs when the XmlSerializer runs under an account or a security environment that is not able to access the temp directory.

Source: http://msdn.microsoft.com/en-us/library/aa302290.aspx

3
ответ дан 23 November 2019 в 00:36
поделиться

В свойствах проекта Visual Studio (страница «Сборка», если я правильно помню) есть опция «сгенерировать сборку сериализации». Попробуйте включить его для проекта, который генерирует [Содержит сборку MyType] .

63
ответ дан 23 November 2019 в 00:36
поделиться

Ваш тип может ссылаться на другие сборки, которые нельзя найти ни в GAC , ни в вашей локальной папке bin ==> ...

"или одной из ее зависимости. Система не удается найти указанный файл »

Вы можете привести пример типа, который хотите сериализовать?

Примечание: убедитесь, что ваш тип реализует Serializable.

0
ответ дан 23 November 2019 в 00:36
поделиться

Пользовательский класс для сериализации:

[Serializable]
public class TestClass
{
    int x = 2;
    int y = 4;
    public TestClass(){}
    public TestClass(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int TestFunction()
    {
        return x + y;
    }
}

Я прикрепил фрагмент кода. Может быть, это поможет вам.

static void Main(string[] args)
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(TestClass));

    MemoryStream memoryStream = new MemoryStream();
    XmlTextWriter xmlWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

    TestClass domain = new TestClass(10, 3);
    xmlSerializer.Serialize(xmlWriter, domain);
    memoryStream = (MemoryStream)xmlWriter.BaseStream;
    string xmlSerializedString = ConvertByteArray2Str(memoryStream.ToArray());

    TestClass xmlDomain = (TestClass)DeserializeObject(xmlSerializedString);

    Console.WriteLine(xmlDomain.TestFunction().ToString());
    Console.ReadLine();
}
1
ответ дан 23 November 2019 в 00:36
поделиться

Как сказал Мартин Шерберн, это нормальное поведение. Конструктор XmlSerializer сначала пытается найти сборку с именем [YourAssembly] .XmlSerializers.dll, которая должна содержать сгенерированный класс для сериализации вашего типа. Поскольку такая DLL еще не создана (по умолчанию они не созданы), генерируется исключение FileNotFoundException. Когда это происходит, конструктор XmlSerializer перехватывает это исключение, и DLL автоматически создается во время выполнения конструктором XmlSerializer (это делается путем создания исходных файлов C # в каталоге% temp% вашего компьютера, а затем их компиляции с помощью компилятора C #). Дополнительные конструкции XmlSerializer для того же типа будут просто использовать уже сгенерированную DLL.

ОБНОВЛЕНИЕ: Начиная с .NET 4.5, XmlSerializer больше не выполняет генерацию кода и не выполняет компиляцию с помощью компилятора C # для создания сборки сериализатора во время выполнения, если это явно не принудительно путем установки параметра файла конфигурации ( useLegacySerializerGeneration ) . Это изменение устраняет зависимость от csc.exe и улучшает производительность при запуске. Источник: Файл Readme для .NET Framework 4.5 , раздел 1.3.8.1.

Исключение обрабатывается конструктором XmlSerializer. Нет необходимости делать что-либо самостоятельно, вы можете просто нажать «Продолжить» (F5), чтобы продолжить выполнение вашей программы, и все будет в порядке. Если вас беспокоят исключения, останавливающие выполнение вашей программы и вызывающие помощник по исключениям, у вас либо отключен параметр «Только мой код», либо или у вас есть FileNotFoundException, настроенное для прерывания выполнения при возникновении, а не в случае «Необработанный пользователем».

Чтобы включить «Только мой код», перейдите в Инструменты >> Параметры >> Отладка >> Общие >> Включить только мой код . Чтобы отключить прерывание выполнения при вызове FileNotFound, перейдите в Debug >> Exceptions >> Find >> введите FileNotFoundException >> снимите флажок Thrown в System.IO.FileNotFoundException.

104
ответ дан 23 November 2019 в 00:36
поделиться

Это исключение также может быть перехвачено управляемым ассистентом отладки (MDA) под названием BindingFailure.

Этот MDA полезен, если ваше приложение разработано для поставки с предварительно созданными сборками сериализации. Мы делаем это для повышения производительности нашего приложения. Это позволяет нам убедиться, что предварительно созданные сборки сериализации правильно собираются нашим процессом сборки и загружаются приложением без повторной сборки на лету.

Это действительно бесполезно, кроме этого сценария, потому что как другие плакаты говорили, что когда ошибка привязки улавливается конструктором сериализатора, сборка сериализации перестраивается во время выполнения. Так что обычно его можно выключить.

6
ответ дан 23 November 2019 в 00:36
поделиться

Чтобы избежать исключения, вам нужно сделать две вещи:

  1. Добавить атрибут к сериализованному классу (надеюсь, у вас есть доступ)
  2. Сгенерировать файл сериализации с помощью sgen.exe

Добавьте атрибут System.Xml.Serialization.XmlSerializerAssembly в свой класс. Замените MyAssembly именем сборки, в которой находится MyClass.

[Serializable]
[XmlSerializerAssembly("MyAssembly.XmlSerializers")]
public class MyClass
{
…
}

Создайте файл сериализации с помощью утилиты sgen.exe и разверните его вместе со сборкой класса.

sgen.exe MyAssembly.dll создаст файл файл MyAssembly.XmlSerializers.dll

Эти два изменения заставят .net найти сборку напрямую. Я проверил, и он работает на .NET framework 3.5 с Visual Studio 2008

7
ответ дан 23 November 2019 в 00:36
поделиться

В свойствах проекта Visual Studio есть опция «создать сборку сериализации». Попробуйте включить его для проекта, который генерирует [Содержит сборку MyType].

2
ответ дан 23 November 2019 в 00:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: