399 Stimmen

XmlSerializer gibt FileNotFoundException beim Konstruktor

Eine Anwendung, mit der ich gearbeitet habe, schlägt fehl, wenn ich versuche, Typen zu serialisieren.

Eine Aussage wie

XmlSerializer lizer = new XmlSerializer(typeof(MyType));

produziert:

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)

Ich definiere keine speziellen Serialisierer für meine Klasse.

Wie kann ich dieses Problem beheben?

456voto

Martin Sherburn Punkte 5660

Ob Sie es glauben oder nicht, das ist ein normales Verhalten. Eine Ausnahme wird ausgelöst, aber vom XmlSerializer behandelt, so dass, wenn Sie einfach ignorieren es sollte alles auf gut weiter.

Ich finde das sehr ärgerlich, und es gibt viele Beschwerden darüber, wenn man sich ein wenig umsieht, aber nach dem, was ich gelesen habe, plant Microsoft nicht, etwas dagegen zu unternehmen.

Sie können vermeiden, dass beim Debuggen ständig Ausnahme-Popups angezeigt werden, wenn Sie die Ausnahmen der ersten Chance für diese spezielle Ausnahme ausschalten. Gehen Sie in Visual Studio zu Debuggen -> Ausnahmen (oder drücken Sie Ctrl + Alt + E ), Common Language Runtime-Ausnahmen -> System.IO -> System.IO.FileNotFoundException .

Informationen zu einer anderen Möglichkeit finden Sie in diesem Blogbeitrag C# XmlSerializer FileNotFound Ausnahme (in dem das Werkzeug von Chris Sells besprochen wird XmlSerializerPreCompiler ).

116voto

Allon Guralnek Punkte 15401

Wie Martin Sherburn sagte, ist dies ein normales Verhalten. Der Konstruktor des XmlSerializers versucht zunächst, eine Assembly namens [YourAssembly].XmlSerializers.dll zu finden, die die generierte Klasse für die Serialisierung Ihres Typs enthalten sollte. Da eine solche DLL noch nicht generiert wurde (standardmäßig nicht), wird eine FileNotFoundException geworfen. Wenn das passiert, fängt der XmlSerializer-Konstruktor diese Ausnahme ab, und die DLL wird automatisch zur Laufzeit durch den XmlSerializer-Konstruktor generiert (dies geschieht durch die Generierung von C#-Quelldateien im %temp%-Verzeichnis Ihres Computers, die dann mit dem C#-Compiler kompiliert werden). Weitere Konstruktionen eines XmlSerializers für denselben Typ verwenden einfach die bereits generierte DLL.

UPDATE: Beginnend mit .NET 4.5, XmlSerializer führt keine Code-Generierung mehr durch und kompiliert auch nicht mehr mit dem C#-Compiler, um eine Serializer-Assembly zur Laufzeit zu erstellen, es sei denn, dies wird explizit durch eine Einstellung in der Konfigurationsdatei ( useLegacySerializerGeneration ). Diese Änderung beseitigt die Abhängigkeit von csc.exe und verbessert die Leistung beim Start. _Quelle: .NET Framework 4.5 Readme Abschnitt 1.3.8.1._

Die Ausnahme wird vom Konstruktor von XmlSerializer behandelt. Sie brauchen selbst nichts zu tun, Sie können einfach auf "Weiter" (F5) klicken, um Ihr Programm fortzusetzen, und alles ist in Ordnung. Wenn Sie sich daran stören, dass die Ausnahmen die Ausführung Ihres Programms unterbrechen und eine Ausnahmehilfe anzeigen, haben Sie entweder 'Just My Code' ausgeschaltet oder die FileNotFoundException so eingestellt, dass sie die Ausführung unterbricht, wenn sie ausgelöst wird, anstatt wenn sie 'User-unhandled' ist.

Um 'Just My Code' zu aktivieren, gehen Sie zu Extras >> Optionen >> Debugging >> Allgemein >> Just My Code aktivieren. Um die Unterbrechung der Ausführung zu deaktivieren, wenn FileNotFound ausgelöst wird, gehen Sie zu Debug >> Exceptions >> Find >> geben Sie 'FileNotFoundException' ein >> deaktivieren Sie das Kontrollkästchen 'Thrown' von System.IO.FileNotFoundException.

72voto

VladV Punkte 9703

In den Projekteigenschaften von Visual Studio (Seite "Build", wenn ich mich richtig erinnere) gibt es die Option "generate serialization assembly". Versuchen Sie, diese Option für ein Projekt zu aktivieren, das Folgendes erzeugt [Enthält Assembly of MyType] .

67voto

quadfinity Punkte 877

Dafür gibt es eine Abhilfe. Wenn Sie

XmlSerializer lizer = XmlSerializer.FromTypes(new[] { typeof(MyType) })[0];

sollte sie diese Ausnahme vermeiden. Das hat bei mir funktioniert.

WARNUNG: Verwenden Sie die Funktion nicht mehrfach, sonst haben Sie eine Speicherleck

Sie werden wie verrückt Speicherplatz verlieren, wenn Sie diese Methode verwenden, um Instanzen von XmlSerializer für denselben Typ mehr als einmal!

Der Grund dafür ist, dass diese Methode die integrierte Zwischenspeicherung umgeht, die die XmlSerializer(type) y XmlSerializer(type, defaultNameSpace) Konstruktoren (alle anderen Konstruktoren umgehen den Cache ebenfalls).

Wenn Sie eine beliebige Methode zur Erstellung eines XmlSerializer verwenden, die nicht über diese beiden Konstruktoren erfolgt, müssen Sie Ihre eigene Zwischenspeicherung implementieren, da sonst der Speicherplatz knapp wird.

31voto

Frosty Punkte 301

Ich bin auf genau dieses Problem gestoßen und konnte es mit keiner der genannten Lösungen umgehen.

Dann habe ich endlich eine Lösung gefunden. Es scheint, dass der Serialisierer nicht nur den Typ, sondern auch die verschachtelten Typen benötigt. Ändern Sie dies:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

Zu diesem:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(T).GetNestedTypes());

Das Problem wurde für mich behoben. Keine Ausnahmen mehr oder so.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X