2010-02-14 6 views
5

Ich versuche XML-Serialisierung zu einer ziemlich trivialen Klassenstruktur in C# hinzuzufügen. Im Wesentlichen gibt es eine einzelne Instanz einer Wurzelklasse (nennen wir es AClass), die eine Liste von mehreren Instanzen einer anderen Klasse hält (nennen wir es Andere):Serialize List <> von Klassen, die mit internem Modifikator deklariert wurden?

[XmlRoot("RootNode")] 
public class AClass { 
    [XmlElement("ListNode")] 
    internal List otherObjects { get; set; } 
} 

public class AnotherClass { 
    [XmlAttribute("Name")] 
    internal string name { get; set; } 
}

Wenn die Serialisierung, die ich für diese beiden möchten Klassen, die zusammen serialisiert werden sollen - das heißt, wenn ich AClass serialisiere, wird seine Liste von AnotherClass ebenfalls serialisiert (siehe this question).

Ich habe dies meistens funktioniert, aber das Problem ist, dass bei der Serialisierung, XmlSerializer nur mit public Eigenschaften der Klasse beschäftigen scheint zu wollen - es ist nicht Andereüberhaupt nicht serialisiert werden, wenn die Liste internal deklariert wird.

Ich habe versucht, die Interna sichtbar für die Serializer Versammlung machen:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.Xml")]

, die nichts zu tun schien. Gibt es eine Möglichkeit, XmlSerializer zu erhalten, Listen von Objekten, die intern deklariert werden, rekursiv zu serialisieren?

+0

+1 für die Frage, weil die Annahme ist, dass die Eigenschaften öffentlich sein müssen *, denn das ist, was uns gesagt wurde *. Manchmal denke ich, dass viele von uns an dem Punkt anhalten, an dem uns gesagt wird, dass wir nichts tun können, ohne nach Alternativen zu fragen. – IAbstract

Antwort

6

Sie sind auf dem richtigen Weg ... mit der Ausnahme, dass die eigentliche Serialisierung nicht von System.Xml ausgeführt wird, sondern von einer dynamisch generierten Assembly. Sie können den Namen dieser Assembly nicht vorhersagen (sie wird zufällig generiert), sodass Sie sie nicht im Attribut InternalsVisibleTo verwenden können.

Die einzige Lösung besteht darin, die XML-Serialisierungsassemblierung vorab zu generieren. Sie können das mit der XML Serializer Generator Tool (Sgen.exe) tun. Der Name der generierten Assembly lautet "YourAssembly.XmlSerializers"; Das ist der Name, den Sie im Attribut InternalsVisibleTo verwenden müssen.

+0

Ich kannte das Werkzeug nicht! +1 von mir. –

+0

+1 @Thomas: das ist gut zu wissen. Hast du das noch selbst ausprobiert? – IAbstract

+0

Und, btw ... großartige Erklärung, warum das 'InternalsVisibleTo' Attribut in diesem Fall nicht funktioniert !!! – IAbstract

1

Die Idee, das Attribut InternalsVisibleTo hinzuzufügen, ist ein guter, aber ich denke, dass das Problem darin besteht, dass der XML-Serialisierungscode nur nach den öffentlichen Typen in der Assembly sucht.
Meiner Kenntnis nach gibt es keine Möglichkeit, XmlSerializer interne Typen zu serialisieren oder zu deserialisieren, und Sie müssen entweder die Typen als public deklarieren oder Ihren eigenen Serialisierungscode schreiben.
Darüber hinaus gibt die XmlSerializer class documentation explizit an, dass nur öffentliche Eigenschaften des Objekts serialisiert werden: "XML-Serialisierung ist der Prozess der öffentlichen Eigenschaften und Felder eines Objekts in ein serielles Format (in diesem Fall XML) für Lagerung oder Transport konvertieren", Es sieht wirklich so aus, als wäre es eine Designentscheidung.

+0

Eigentlich serialisieren interne Mitglieder funktioniert gut ... (siehe meine Antwort) –

+0

Es ist möglich, interne Typen mit dem XmlSerializer zu serialisieren, aber in diesem Fall müssen Sie Ihren eigenen benutzerdefinierten Typ Serializer schreiben, indem Sie IXmlSerializable für diesen speziellen Typ (und der Typ selbst muss öffentlich sein). – Steven