Importieren von Schemas zum Generieren von Klassen

Verwenden Sie die XsdDataContractImporter-Klasse, um Klassen auf der Grundlage von Schemas zu generieren, die mit Windows Communication Foundation (WCF) verwendet werden können. In diesem Thema werden der Prozess und die Variationen beschrieben.

Der Importprozess

Der Schemaimportprozess beginnt mit XmlSchemaSet und erzeugt ein CodeCompileUnit-Element.

XmlSchemaSet ist Teil des Schemaobjektmodells (SOM) von .NET Framework, das eine Gruppe von XSD-Schemadokumenten (XML Schema Definition Language) darstellt. Um ein XmlSchemaSet-Objekt aus einer Gruppe von XSD-Dokumenten zu erstellen, deserialisieren Sie die einzelnen Dokumente in ein XmlSchema-Objekt (mithilfe von XmlSerializer) und fügen diese Objekte einem neuen XmlSchemaSet-Element hinzu.

CodeCompileUnit ist Teil des Code-Dokumentobjektmodells (CodeDOM) von .NET Framework, das den .NET Framework-Code abstrakt darstellt. Um den eigentlichen Code aus einer CodeCompileUnit zu generieren, verwenden Sie eine Unterklasse der CodeDomProvider-Klasse, zum Beispiel die CSharpCodeProvider- oder VBCodeProvider-Klasse.

So importieren Sie ein Schema

  1. Erstellen Sie eine Instanz der XsdDataContractImporter.

  2. Optional. Übergeben Sie im Konstruktor eine CodeCompileUnit. Die während des Schemaimports generierten Typen werden dieser CodeCompileUnit-Instanz hinzugefügt. Es wird keine leere CodeCompileUnit verwendet.

  3. Optional. Rufen Sie eine der CanImport-Methoden auf. Die Methode bestimmt, ob es sich beim jeweiligen Schema um ein gültiges Datenvertragsschema handelt und ob es importiert werden kann. Die CanImport-Methode verfügt über die gleichen Überladungen wie Import (der nächste Schritt).

  4. Rufen Sie eine der überladenen Import-Methoden auf, zum Beispiel die Import(XmlSchemaSet)-Methode.

    Bei der einfachsten Überladung wird ein XmlSchemaSet verwendet, und es werden alle Typen importiert, die im Schemasatz enthalten sind, einschließlich anonyme Typen. Bei anderen Überladungen können Sie den XSD-Typ oder eine Liste der Typen angeben, die importiert werden sollen (in Form eines XmlQualifiedName-Objekts oder einer Auflistung mit XmlQualifiedName-Objekten). In diesem Fall werden nur die angegebenen Typen importiert. Eine Überladung verwendet ein XmlSchemaElement, das ein bestimmtes Element aus dem XmlSchemaSet importiert, einschließlich des dazugehörigen Typs (anonym oder nicht anonym). Diese Überladung gibt einen XmlQualifiedName zurück, der für den Datenvertragsnamen des Typs steht, der für dieses Element generiert wurde.

    Mehrere Aufrufe der Import-Methode führen dazu, dass mehrere Elemente derselben CodeCompileUnit hinzugefügt werden. Ein Typ wird nicht für den CodeCompileUnit generiert, wenn er darin bereits vorhanden ist. Rufen Sie Import für einen XsdDataContractImporter mehrfach auf, anstatt mehrere XsdDataContractImporter-Objekte zu verwenden. Dies ist die empfohlene Möglichkeit, um die Generierung von doppelten Typen zu vermeiden.

    Hinweis

    Wenn beim Importieren ein Fehler auftritt, befindet sich die CodeCompileUnit in einem unvorhersehbaren Zustand. Wenn Sie eine CodeCompileUnit verwenden, die aus einem fehlgeschlagenen Import stammt, kann Sie dies ggf. anfällig für Sicherheitslücken machen.

  5. Greifen Sie auf die CodeCompileUnit mithilfe der CodeCompileUnit -Eigenschaft zu.

Importoptionen: Anpassen der generierten Typen

Sie können die Options-Eigenschaft von XsdDataContractImporter auf eine Instanz der ImportOptions-Klasse festlegen, um verschiedene Aspekte des Importprozesses zu steuern. Verschiedene Optionen wirken sich direkt auf die generierten Typen aus.

Steuern der Zugriffsebene (GenerateInternal oder der Schalter "/internal")

Dies entspricht dem Schalter /internal im ServiceModel Metadata Utility-Tool (Svcutil.exe).

Normalerweise werden öffentliche Typen aus Schemas generiert, indem private Felder und passende Eigenschaften öffentlicher Datenmember verwendet werden. Wenn Sie stattdessen interne Typen generieren möchten, legen Sie die GenerateInternal-Eigenschaft auf true fest.

Das folgende Beispiel zeigt ein Schema, das in eine interne Klasse umgewandelt wird, wenn die GenerateInternal-Eigenschaft auf true. festgelegt ist.

[DataContract]
internal partial class Vehicle : IExtensibleDataObject
{
    private int yearField;
    private string colorField;

    [DataMember]
    internal int year
    {
        get { return this.yearField; }
        set { this.yearField = value; }
    }
    [DataMember]
    internal string color
    {
        get { return this.colorField; }
        set { this.colorField = value; }
    }

    private ExtensionDataObject extensionDataField;
    public ExtensionDataObject ExtensionData
    {
        get { return this.extensionDataField; }
        set { this.extensionDataField = value; }
    }
}
Class Vehicle
    Implements IExtensibleDataObject
    Private yearField As Integer
    Private colorField As String

    <DataMember()> _
    Friend Property year() As Integer
        Get
            Return Me.yearField
        End Get
        Set
            Me.yearField = value
        End Set
    End Property

    <DataMember()> _
    Friend Property color() As String
        Get
            Return Me.colorField
        End Get
        Set
            Me.colorField = value
        End Set
    End Property
    Private extensionDataField As ExtensionDataObject

    Public Property ExtensionData() As ExtensionDataObject _
        Implements IExtensibleDataObject.ExtensionData
        Get
            Return Me.extensionDataField
        End Get
        Set(ByVal value As ExtensionDataObject)
            Me.extensionDataField = value
        End Set
    End Property
End Class

Steuern von Namespaces (Namespaces oder der Schalter "/namespace")

Dies entspricht dem Schalter /namespace im Tool Svcutil.exe.

Normalerweise werden auf der Grundlage von Schemas generierte Typen als .NET Framework-Namespaces generiert, und die XSD-Namespaces entsprechen jeweils einem bestimmten .NET Framework-Namespace. Diese Zuordnung ist in der Datenvertrags-Schemareferenz beschrieben. Sie können diese Zuordnung mithilfe der Namespaces-Eigenschaft eines Dictionary<TKey,TValue> anpassen. Wenn ein bestimmter XSD-Namespace im Wörterbuch enthalten ist, wird auch der entsprechende .NET Framework-Namespace aus Ihrem Wörterbuch verwendet.

Betrachten Sie zum Beispiel das folgende Schema:

<xs:schema targetNamespace="http://schemas.contoso.com/carSchema">
  <xs:complexType name="Vehicle">
    <!-- details omitted... -->
  </xs:complexType>
</xs:schema>

Im folgenden Beispiel wird die Namespaces-Eigenschaft verwendet, um den http://schemas.contoso.com/carSchema-Namespace „Contoso.Cars“ zuzuordnen.

XsdDataContractImporter importer = new XsdDataContractImporter();
importer.Options.Namespaces.Add(new KeyValuePair<string, string>("http://schemas.contoso.com/carSchema", "Contoso.Cars"));
Dim importer As New XsdDataContractImporter
importer.Options.Namespaces.Add(New KeyValuePair(Of String, String)("http://schemas.contoso.com/carSchema", "Contoso.Cars"))

Hinzufügen von SerializableAttribute (GenerateSerializable oder der Schalter "/serializable")

Dies entspricht dem Schalter /serializable im Tool Svcutil.exe.

Manchmal müssen die auf der Grundlage des Schemas generierten Typen mit .NET Framework-Runtimeserialisierungs-Engines verwendbar sein. Dies ist hilfreich, wenn Sie Typen für das .NET Framework-Remoting nutzen. Um dies zu aktivieren, müssen Sie das SerializableAttribute-Attribut zusätzlich zum normalen DataContractAttribute-Attribut auf die generierten Typen anwenden. Das Attribut wird automatisch generiert, wenn die Importoption GenerateSerializable auf true festgelegt ist.

Das folgende Beispiel zeigt die Vehicle-Klasse, bei deren Generierung die Importoption GenerateSerializable auf true festgelegt ist.

[DataContract]
[Serializable]
public partial class Vehicle : IExtensibleDataObject
{
    // Code not shown.
    public ExtensionDataObject ExtensionData
    {
        get
        {
            throw new Exception("The method or operation is not implemented.");
        }
        set
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
}
<DataContract(), Serializable()> _
Partial Class Vehicle
    Implements IExtensibleDataObject
    Private extensionDataField As ExtensionDataObject

    ' Code not shown.

    Public Property ExtensionData() As ExtensionDataObject _
        Implements IExtensibleDataObject.ExtensionData
        Get
            Return Me.extensionDataField
        End Get
        Set(ByVal value As ExtensionDataObject)
            Me.extensionDataField = value
        End Set
    End Property

End Class

Hinzufügen von Datenbindungsunterstützung (EnableDataBinding oder der Schalter „/enableDataBinding“)

Dies entspricht dem Schalter /enableDataBinding im Tool „Svcutil.exe“.

In einigen Fällen kann es ratsam sein, die aus dem Schema generierten Typen an Komponenten der grafischen Benutzeroberfläche zu binden, damit die Aktualisierungen der Instanzen dieser Typen automatisch auf der Benutzeroberfläche widergespiegelt werden. Der XsdDataContractImporter kann Typen generieren, die die INotifyPropertyChanged-Schnittstelle so implementieren, dass alle Änderungen von Eigenschaften ein Ereignis auslösen. Wenn Sie Typen für die Verwendung mit einer Programmierumgebung für Clientbenutzeroberflächen generieren, die diese Schnittstelle unterstützt (zum Beispiel Windows Presentation Foundation (WPF)), legen Sie die EnableDataBinding-Eigenschaft auf true fest, um dieses Feature zu aktivieren.

Das folgende Beispiel zeigt die Vehicle-Klasse, bei deren Generierung EnableDataBinding auf true festgelegt ist.

[DataContract]
public partial class Vehicle : IExtensibleDataObject, INotifyPropertyChanged
{
    private int yearField;
    private string colorField;

    [DataMember]
    public int year
    {
        get { return this.yearField; }
        set
        {
            if (this.yearField.Equals(value) != true)
            {
                this.yearField = value;
                this.RaisePropertyChanged("year");
            }
        }
    }
    [DataMember]
    public string color
    {
        get { return this.colorField; }
        set
        {
            if (this.colorField.Equals(value) != true)
            {
                this.colorField = value;
                this.RaisePropertyChanged("color");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler propertyChanged =
this.PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this,
new PropertyChangedEventArgs(propertyName));
        }
    }

    private ExtensionDataObject extensionDataField;
    public ExtensionDataObject ExtensionData
    {
        get { return this.extensionDataField; }
        set { this.extensionDataField = value; }
    }
}
Partial Class Vehicle
    Implements IExtensibleDataObject, INotifyPropertyChanged
    Private yearField As Integer
    Private colorField As String

    <DataMember()> _
    Public Property year() As Integer
        Get
            Return Me.yearField
        End Get
        Set
            If Me.yearField.Equals(value) <> True Then
                Me.yearField = value
                Me.RaisePropertyChanged("year")
            End If
        End Set
    End Property

    <DataMember()> _
    Public Property color() As String
        Get
            Return Me.colorField
        End Get
        Set
            If Me.colorField.Equals(value) <> True Then
                Me.colorField = value
                Me.RaisePropertyChanged("color")
            End If
        End Set
    End Property

    Public Event PropertyChanged As PropertyChangedEventHandler _
      Implements INotifyPropertyChanged.PropertyChanged

    Private Sub RaisePropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, _
         New PropertyChangedEventArgs(propertyName))
    End Sub

    Private extensionDataField As ExtensionDataObject

    Public Property ExtensionData() As ExtensionDataObject _
        Implements IExtensibleDataObject.ExtensionData
        Get
            Return Me.extensionDataField
        End Get
        Set(ByVal value As ExtensionDataObject)
            Me.extensionDataField = value
        End Set
    End Property

End Class

Importoptionen: Wählen von Auflistungstypen

Zwei spezielle XML-Muster stellen Auflistungen von Elementen dar: Listen mit Elementen und Zuordnungen zwischen einem Element und einem anderen. Unten ist ein Beispiel für eine Liste mit Zeichenfolgen angegeben.

<People>
  <person>Alice</person>
  <person>Bob</person>
  <person>Charlie</person>
</People>

Das folgende Beispiel zeigt eine Zuordnung zwischen einer Zeichenfolge und einer Ganzzahl (city name und population).

<Cities>
  <city>
    <name>Auburn</name>
    <population>40000</population>
  </city>
  <city>
    <name>Bellevue</name>
    <population>80000</population>
  </city>
  <city>
    <name>Cedar Creek</name>
    <population>10000</population>
  </city>
</Cities>

Hinweis

Jede Zuordnung kann auch als Liste angesehen werden. Sie können die oben angegebene Zuordnung zum Beispiel als Liste mit komplexen city-Objekten ansehen, die zwei Felder aufweisen (ein Zeichenfolgenfeld und ein Ganzzahlfeld). Beide Muster verfügen im XSD-Schema über eine Darstellung. Es ist nicht möglich, zwischen einer Liste und einer Zuordnung zu unterscheiden. Aus diesem Grund werden Muster dieser Art immer wie Listen behandelt, es sei denn, das Schema enthält eine bestimmte WCF-spezifische Anmerkung. Die Anmerkung gibt an, dass ein bestimmtes Muster eine Zuordnung darstellt. Weitere Informationen finden Sie in der Datenvertrags-Schemareferenz.

In der Regel wird eine Liste als Auflistungsdatenvertrag importiert, der von einer generischen Liste oder einem .NET Framework-Array abgeleitet ist. Das hängt davon ab, ob das Schema das Standardnamensmuster für Sammlungen verwendet. Dies wird ausführlicher unter Sammlungstypen in Datenverträgen beschrieben. Zuordnungen werden normalerweise entweder als Dictionary<TKey,TValue> oder als Auflistungsdatenvertrag importiert, der vom Wörterbuchobjekt abgeleitet ist. Betrachten Sie zum Beispiel das folgende Schema:

<xs:complexType name="Vehicle">
  <xs:sequence>
    <xs:element name="year" type="xs:int"/>
    <xs:element name="color" type="xs:string"/>
    <xs:element name="passengers" type="people"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="people">
  <xs:sequence>
    <xs:element name="person" type="xs:string" maxOccurs="unbounded" />
  </xs:sequence>
</xs:complexType>

Der Import wird hierbei wie folgt durchgeführt (aus Gründen der besseren Lesbarkeit werden anstelle von Eigenschaften Felder angezeigt).

[DataContract]
public partial class Vehicle : IExtensibleDataObject
{
    [DataMember] public int yearField;
    [DataMember] public string colorField;
    [DataMember] public people passengers;

    // Other code not shown.

    public ExtensionDataObject ExtensionData
    {
        get
        {
            throw new Exception("The method or operation is not implemented.");
        }
        set
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
}
[CollectionDataContract(ItemName = "person")]
public class people : List<string> { }
Public Partial Class Vehicle
    Implements IExtensibleDataObject

    <DataMember()> _
    Public yearField As Integer
    <DataMember()> _
    Public colorField As String
    <DataMember()> _
    Public passengers As people

    ' Other code not shown.

    Public Property ExtensionData() As ExtensionDataObject _
    Implements IExtensibleDataObject.ExtensionData
        Get
            Throw New Exception("The method or operation is not implemented.")
        End Get
        Set
            Throw New Exception("The method or operation is not implemented.")
        End Set
    End Property
End Class

<CollectionDataContract(ItemName:="person")> _
Public Class people
    Inherits List(Of String)
End Class

Es ist möglich, die Auflistungstypen anzupassen, die für Schemamuster dieser Art generiert werden. Es kann beispielsweise sein, dass Sie Auflistungen generieren, die von BindingList<T> abgeleitet sind, anstatt von der List<T>-Klasse, um den Typ an ein Listenfeld zu binden und automatisch aktualisieren zu lassen, wenn sich der Inhalt der Auflistung ändert. Legen Sie dazu die ReferencedCollectionTypes-Eigenschaft der ImportOptions-Klasse auf eine Liste mit zu verwendenden Auflistungstypen (im Weiteren als referenzierte Typen bezeichnet) fest. Beim Importieren von Auflistungen wird diese Liste mit Verweisen zu Auflistungstypen durchsucht und die Auflistung mit der höchsten Übereinstimmung verwendet, falls vorhanden. Es ergeben sich bei Zuordnungen nur für Typen Übereinstimmungen, die entweder die generische oder die nicht generische IDictionary-Schnittstelle implementieren, während sich bei Listen für alle unterstützten Auflistungstypen Übereinstimmungen ergeben können.

Wenn die ReferencedCollectionTypes-Eigenschaft zum Beispiel auf eine BindingList<T> festgelegt ist, wird der people-Typ aus dem vorherigen Beispiel wie folgt generiert.

[CollectionDataContract(ItemName = "person")]
public class people : BindingList<string> { }
<CollectionDataContract(ItemName:="person")> _
Public Class people
    Inherits BindingList(Of String)

Ein geschlossener generischer Typ wird als beste Übereinstimmung betrachtet. Wenn beispielsweise die Typen BindingList(Of Integer) und ArrayList an die Auflistung der referenzierten Typen übergeben werden, werden alle Listen mit Ganzzahlen, die im Schema enthalten sind, als BindingList(Of Integer) importiert. Alle anderen Listen, zum Beispiel List(Of String), werden als ArrayList importiert.

Wenn ein Typ, der die generische IDictionary-Schnittstelle implementiert, der Auflistung der referenzierten Typen hinzugefügt wird, müssen ihre Typparameter entweder vollständig offen oder vollständig geschlossen sein.

Duplikate sind nicht zulässig. Zum Beispiel können Sie den referenzierten Typen nicht sowohl eine List(Of Integer) als auch eine Collection(Of Integer) hinzufügen. In diesem Fall wäre es unmöglich zu bestimmen, welches Element verwendet werden soll, wenn im Schema eine Liste mit Ganzzahlen gefunden wird. Duplikate werden nur erkannt, wenn es einen Typ im Schema gibt, der das Duplikatproblem offenlegt. Wenn das importierte Schema zum Beispiel keine Listen mit Ganzzahlen enthält, ist es zulässig, sowohl die List(Of Integer) als auch die Collection(Of Integer) in der Auflistung mit den referenzierten Typen zu verwenden, aber beide haben keine Auswirkung.

Der Mechanismus mit den referenzierten Auflistungstypen funktioniert ebenso gut für Auflistungen mit komplexen Typen (einschließlich Auflistungen anderer Auflistungen), nicht nur für Auflistungen von primitiven Typen.

Die ReferencedCollectionTypes-Eigenschaft entspricht dem Schalter /collectionType im Tool „SvcUtil.exe“. Beachten Sie, dass der Schalter /collectionType mehrmals angegeben werden muss, um auf mehrere Sammlungstypen verweisen zu können. Wenn der Typ nicht in der Datei „MsCorLib.dll“ enthalten ist, muss auf die dazugehörige Assembly ebenfalls mithilfe des Schalters /reference verwiesen werden.

Importoptionen: Verweisen auf vorhandene Typen

In einigen Fällen entsprechen Typen im Schema vorhandenen .NET Framework-Typen, und es ist nicht erforderlich, diese Typen ganz neu zu generieren. (Dieser Abschnitt gilt nur für sammlungsfremde Typen. Informationen zu Sammlungstypen finden Sie im vorherigen Abschnitt.)

Es kann zum Beispiel sein, dass Sie über einen standardmäßigen unternehmensweiten Datenvertragstyp "Person" verfügen, der beim Darstellen einer Person immer verwendet werden soll. Jedes Mal, wenn ein Dienst diesen Typ verwendet und das dazugehörige Schema in den Dienstmetadaten erscheint, sollten Sie den vorhandenen Person-Typ beim Importieren des Schemas wiederverwenden, anstatt für jeden Dienst ein neues Schema zu erstellen.

Übergeben Sie dazu eine Liste mit .NET Framework-Typen, die Sie wiederverwenden möchten, an die Sammlung, die die ReferencedTypes-Eigenschaft für die ImportOptions-Klasse zurückgibt. Falls einige dieser Typen einen Datenvertragsnamen und Namespace aufweisen, der mit dem Namen und Namespace eines Schematyps übereinstimmt, wird ein Strukturvergleich durchgeführt. Wenn ermittelt wird, dass die Typen über übereinstimmende Namen und Strukturen verfügen, wird der vorhandene .NET Framework-Typ wiederverwendet und kein neuer Typ generiert. Wenn nur der Name übereinstimmt, aber nicht die Struktur, wird eine Ausnahme ausgelöst. Beachten Sie, dass beim Verweisen auf Typen (zum Beispiel beim Hinzufügen von neuen optionalen Datenmembern) kein Spielraum für unterschiedliche Versionen besteht. Die Strukturen müssen genau übereinstimmen.

Es ist zulässig, der Auflistung der referenzierten Typen mehrere Typen mit demselben Datenvertragsnamen und Namespace hinzuzufügen, solange keine Schematypen mit diesem Namen und Namespace importiert werden. So können Sie der Auflistung alle in einer Assembly enthaltenen Typen auf einfache Weise hinzufügen, ohne sich um Duplikate von Typen kümmern zu müssen, die im Schema eigentlich nicht vorkommen.

Die ReferencedTypes-Eigenschaft entspricht bei bestimmten Verwendungsarten des Tools „Svcutil.exe“ dem Schalter /reference.

Hinweis

Bei Verwendung von „Svcutil.exe“ oder Dienstverweis hinzufügen (in Visual Studio) sind alle Typen der Datei „MsCorLib.dll“ automatisch referenziert.

Importoptionen: Importieren von Nicht-DataContract-Schemas als IXmlSerializable-Typen

Der XsdDataContractImporter unterstützt eine beschränkte Teilmenge des Schemas. Wenn nicht unterstützte Schemakonstrukte vorhanden sind (zum Beispiel XML-Attribute), schlägt der Importversuch mit einer Ausnahme fehl. Das Festlegen der ImportXmlType-Eigenschaft auf true erweitert jedoch den unterstützten Schemabereich. Wenn true festgelegt ist, generiert der XsdDataContractImporter Typen, die die IXmlSerializable-Schnittstelle implementieren. Auf diese Weise wird der Direktzugriff auf die XML-Darstellung dieser Typen aktiviert.

Entwurfsaspekte
  • Es kann schwierig sein, direkt mit der schwach typisierten XML-Darstellung zu arbeiten. Sie sollten erwägen, eine alternative Serialisierungs-Engine zu verwenden, beispielsweise XmlSerializer, um mit Schemas arbeiten zu können, die mit stark typisierten Datenverträgen nicht kompatibel sind. Weitere Informationen finden Sie unter Verwenden der XmlSerializer-Klasse.

  • Einige Schemakonstrukte können über XsdDataContractImporter nicht importiert werden. Dies ist auch dann nicht möglich, wenn die ImportXmlType-Eigenschaft auf true festgelegt ist. Sie sollten auch hierfür erwägen, XmlSerializer zu verwenden.

  • Die genauen Schemakonstrukte, die unterstützt werden, wenn ImportXmlType den Wert true oder false hat, sind in der Datenvertrags-Schemareferenz beschrieben.

  • Schemas für generierte IXmlSerializable-Typen behalten beim Importieren und Exportieren ihre Originaltreue nicht bei. Wenn Sie das Schema also aus den generierten Typen exportieren und jeweils als Klasse importieren, wird nicht das Originalschema zurückgegeben.

Es ist möglich, die ImportXmlType-Option mit der oben beschriebenen ReferencedTypes-Option zu kombinieren. Für Typen, die als IXmlSerializable-Implementierungen generiert werden müssen, wird beim Verwenden der ReferencedTypes-Funktion die Strukturprüfung übersprungen.

Die ImportXmlType-Option entspricht dem Schalter /importXmlTypes im Tool „Svcutil.exe“.

Arbeiten mit generierten IXmlSerializable-Typen

Die generierten IXmlSerializable-Typen enthalten ein privates Feld mit der Bezeichnung "nodesField", das ein Array mit XmlNode-Objekten zurückgibt. Beim Deserialisieren der Instanz eines Typs dieser Art können Sie auf die XML-Daten direkt über dieses Feld zugreifen, indem Sie das XML-Dokumentobjektmodell verwenden. Beim Serialisieren einer Instanz dieses Typs können Sie dieses Feld auf die gewünschten XML-Daten festlegen. Es wird dann serialisiert.

Dies wird mithilfe der IXmlSerializable-Implementierung erreicht. Im generierten IXmlSerializable-Typ ruft die ReadXml-Implementierung die ReadNodes-Methode der XmlSerializableServices-Klasse auf. Bei der Methode handelt es sich um eine Hilfsmethode, die XML-Daten konvertiert, die über einen XmlReader für ein Array mit XmlNode-Objekten bereitgestellt werden. Die WriteXml-Implementierung bewirkt das Gegenteil und konvertiert das Array mit den XmlNode-Objekten in eine Folge von XmlWriter-Aufrufen. Dies wird durch die Verwendung der WriteNodes-Methode erreicht.

Es ist möglich, den Schemaexportprozess über die generierten IXmlSerializable-Klassen auszuführen. Wie bereits erwähnt, erhalten Sie nicht das ursprüngliche Schema zurück. Stattdessen erhalten Sie den standardmäßigen XSD-Standardtyp „anyType“. Hierbei handelt es sich um einen Platzhalter für einen beliebigen XSD-Typ.

Dies wird erreicht, indem das XmlSchemaProviderAttribute-Attribut auf die generierten IXmlSerializable-Klassen angewendet und eine Methode angegeben wird, die die AddDefaultSchema-Methode aufruft, um den Typ „anyType“ zu generieren.

Hinweis

Der XmlSerializableServices-Typ ist nur vorhanden, um diese Funktion zu unterstützen. Es ist nicht ratsam, den Typ zu einem anderen Zweck zu verwenden.

Importoptionen: Erweiterte Optionen

Bei den folgenden Optionen handelt es sich um erweiterte Importoptionen:

Siehe auch