Delen via


XML- en ADO.NET-typen in gegevenscontracten

Het WCF-gegevenscontractmodel (Windows Communication Foundation) ondersteunt bepaalde typen die XML rechtstreeks vertegenwoordigen. Wanneer deze typen worden geserialiseerd naar XML, schrijft de serialisatiefunctie de XML-inhoud van deze typen uit zonder verdere verwerking. Ondersteunde typen zijn XmlElement, matrices van XmlNode (maar niet het XmlNode type zelf), evenals typen die worden geïmplementeerd IXmlSerializable. Het DataSet en DataTable type, evenals getypte gegevenssets, worden vaak gebruikt in databaseprogrammering. Deze typen implementeren de IXmlSerializable interface en zijn daarom serialiseerbaar in het gegevenscontractmodel. Aan het einde van dit onderwerp worden enkele speciale overwegingen voor deze typen vermeld.

XML-typen

Xml-element

Het XmlElement type wordt geserialiseerd met behulp van de XML-inhoud. Gebruik bijvoorbeeld het volgende type.

[DataContract(Namespace=@"http://schemas.contoso.com")]
public class MyDataContract
{
    [DataMember]
    public XmlElement myDataMember;
    public void TestClass()
    {
        XmlDocument xd = new XmlDocument();
        myDataMember = xd.CreateElement("myElement");
        myDataMember.InnerText = "myContents";
        myDataMember.SetAttribute
         ("myAttribute","myValue");
    }
}
<DataContract([Namespace]:="http://schemas.contoso.com")> _
Public Class MyDataContract
    <DataMember()> _
    Public myDataMember As XmlElement

    Public Sub TestClass()
        Dim xd As New XmlDocument()
        myDataMember = xd.CreateElement("myElement")
        myDataMember.InnerText = "myContents"
        myDataMember.SetAttribute("myAttribute", "myValue")

    End Sub
End Class

Dit wordt als volgt naar XML geserialiseerd:

<MyDataContract xmlns="http://schemas.contoso.com">  
    <myDataMember>  
        <myElement xmlns="" myAttribute="myValue">  
            myContents  
        </myElement>  
    </myDataMember>  
</MyDataContract>  

U ziet dat er nog steeds een wrapper-gegevenslidelement <myDataMember> aanwezig is. Er is geen manier om dit element in het gegevenscontractmodel te verwijderen. De serializers die dit model verwerken (de DataContractSerializer en NetDataContractSerializer) kunnen speciale kenmerken in dit wrapper-element verzenden. Deze kenmerken omvatten het standaard kenmerk nil van het XML-schema-exemplaar (zodat het XmlElement kan worden null) en het kenmerk 'type' (waardoor XmlElement polymorf kan worden gebruikt). Daarnaast zijn de volgende XML-kenmerken specifiek voor WCF: 'Id', 'Verw', 'Type' en 'Assembly'. Deze kenmerken kunnen worden verzonden ter ondersteuning van het gebruik van de XmlElement opslagmodus voor objectgrafieken ingeschakeld, of met de NetDataContractSerializer. (Zie voor meer informatie over de opslagmodus voor objectgrafiekSerialisatie en deserialisatie.)

Matrices of verzamelingen van XmlElement zijn toegestaan en worden verwerkt als een andere matrix of verzameling. Dat wil gezegd, er is een wrapper-element voor de hele verzameling en een afzonderlijk wrapper-element (vergelijkbaar met <myDataMember> in het vorige voorbeeld) voor elk XmlElement element in de matrix.

Bij deserialisatie wordt er een XmlElement gemaakt door deserializer van de binnenkomende XML. Een geldig bovenliggend element XmlDocument wordt geleverd door de deserializer.

Zorg ervoor dat het XML-fragment dat wordt gedeserialiseerd voor een XmlElement fragment alle voorvoegsels definieert die worden gebruikt en niet afhankelijk is van voorvoegselsdefinities van bovenliggende elementen. Dit is alleen een probleem wanneer u toegang DataContractSerializer krijgt tot XML vanuit een andere (niet-DataContractSerializer) bron.

Wanneer deze wordt gebruikt met de DataContractSerializer, kan het XmlElement polymorf worden toegewezen, maar alleen aan een gegevenslid van het type Object. Hoewel het wordt geïmplementeerd IEnumerable, kan een XmlElement niet worden gebruikt als een verzamelingstype en kan deze niet worden toegewezen aan een IEnumerable gegevenslid. Net als bij alle polymorfe toewijzingen wordt de naam van het gegevenscontract verzonden DataContractSerializer in de resulterende XML. In dit geval is het 'XmlElement' in de http://schemas.datacontract.org/2004/07/System.Xml naamruimte.

Met de NetDataContractSerializer, elke geldige polymorf toewijzing van XmlElement (aan Object of IEnumerable) wordt ondersteund.

Probeer geen van de serializers te gebruiken met typen die zijn afgeleid XmlElementvan , ongeacht of ze polymorf zijn toegewezen of niet.

Matrix van XmlNode

Het gebruik van matrices is XmlNode vergelijkbaar met het gebruik van XmlElement. Het gebruik van matrices van XmlNode geeft u meer flexibiliteit dan het gebruik van XmlElement. U kunt meerdere elementen in het terugloopelement van het gegevenslid schrijven. U kunt ook andere inhoud dan elementen in het terugloopelement van het gegevenslid invoegen, zoals XML-opmerkingen. Ten slotte kunt u kenmerken in het element gegevenslidterugloop plaatsen. Dit alles kan worden bereikt door de matrix te XmlNode vullen met specifieke afgeleide klassen, XmlNode zoals XmlAttribute, XmlElement of XmlComment. Gebruik bijvoorbeeld het volgende type.

[DataContract(Namespace="http://schemas.contoso.com")]
public class MyDataContract
{
    [DataMember]
    public XmlNode[] myDataMember = new XmlNode[4];
    public void TestClass()
    {
        XmlDocument xd = new XmlDocument();
        XmlElement xe = xd.CreateElement("myElement");
        xe.InnerText = "myContents";
        xe.SetAttribute
         ("myAttribute","myValue");
    
        XmlAttribute atr = xe.Attributes[0];
        XmlComment cmnt = xd.CreateComment("myComment");
        
      myDataMember[0] = atr;
      myDataMember[1] = cmnt;
      myDataMember[2] = xe;
      myDataMember[3] = xe;
    }
}
<DataContract([Namespace]:="http://schemas.contoso.com")> _
Public Class MyDataContract
    <DataMember()> _
    Public myDataMember(3) As XmlNode

    Public Sub TestClass()
        Dim xd As New XmlDocument()
        Dim xe As XmlElement = xd.CreateElement("myElement")
        xe.InnerText = "myContents"
        xe.SetAttribute("myAttribute", "myValue")

        Dim atr As XmlAttribute = xe.Attributes(0)
        Dim cmnt As XmlComment = xd.CreateComment("myComment")

        myDataMember(0) = atr
        myDataMember(1) = cmnt
        myDataMember(2) = xe
        myDataMember(3) = xe

    End Sub

End Class

Bij het serialiseren is de resulterende XML vergelijkbaar met de volgende code.

<MyDataContract xmlns="http://schemas.contoso.com">  
  <myDataMember myAttribute="myValue">  
     <!--myComment-->  
     <myElement xmlns="" myAttribute="myValue">  
 myContents  
     </myElement>  
     <myElement xmlns="" myAttribute="myValue">  
       myContents  
     </myElement>  
  </myDataMember>  
</MyDataContract>  

Houd er rekening mee dat het wrapper-element <myDataMember> van het gegevenslid een kenmerk, een opmerking en twee elementen bevat. Dit zijn de vier XmlNode exemplaren die zijn geserialiseerd.

Een matrix van XmlNode die resulteert in ongeldige XML kan niet worden geserialiseerd. Een matrix van twee XmlNode exemplaren waarin de eerste een XmlElement is en de tweede is een XmlAttribute ongeldige, omdat deze reeks niet overeenkomt met een geldig XML-exemplaar (er is geen plaats om het kenmerk aan te koppelen).

Bij de deserialisatie van een matrix van XmlNodeworden knooppunten gemaakt en ingevuld met informatie uit de binnenkomende XML. Een geldig bovenliggend element XmlDocument wordt geleverd door de deserializer. Alle knooppunten worden gedeserialiseerd, inclusief eventuele kenmerken in het element van het gegevenslid van de wrapper, maar exclusief de kenmerken die daar door de WCF-serializers worden geplaatst (zoals de kenmerken die worden gebruikt om polymorfe toewijzing aan te geven). Het voorbehoud over het definiëren van alle naamruimtevoorvoegsels in het XML-fragment is van toepassing op de deserialisatie van matrices, XmlNode net zoals bij het deserialiseren XmlElement.

Wanneer u de serializers gebruikt met behoud van objectgrafieken ingeschakeld, blijft object gelijkheid alleen behouden op het niveau van XmlNode matrices, niet op afzonderlijke XmlNode exemplaren.

Probeer geen matrix te serialiseren waarvan XmlNode een of meer van de knooppunten is ingesteld null. Het is toegestaan dat het hele matrixlid mag zijn null, maar niet voor een persoon XmlNode in de matrix. Als het hele matrixlid null is, bevat het gegevenslidelement van de wrapper een speciaal kenmerk dat aangeeft dat het null is. Bij deserialisatie wordt het hele matrixlid ook null.

Alleen reguliere matrices worden XmlNode speciaal behandeld door de serializer. Gegevensleden die als andere verzamelingstypen zijn gedeclareerd, of gegevensleden die XmlNodezijn gedeclareerd als matrices van typen die zijn afgeleid XmlNodevan, worden niet speciaal behandeld. Ze zijn dus normaal gesproken niet serialiseerbaar, tenzij ze ook voldoen aan een van de andere criteria voor serialisatie.

Matrices of verzamelingen van matrices van XmlNode zijn toegestaan. Er is een wrapper-element voor de hele verzameling en een afzonderlijk wrapper-element (vergelijkbaar met <myDataMember> in het voorgaande voorbeeld) voor elke matrix van XmlNode de buitenste matrix of verzameling.

Het invullen van een gegevenslid van het type ArrayObject of Array van IEnumerable met XmlNode exemplaren leidt er niet toe dat het gegevenslid wordt behandeld als een Array van XmlNode de exemplaren. Elk matrixlid wordt afzonderlijk geserialiseerd.

Bij gebruik met de DataContractSerializermatrix kunnen matrices XmlNode van het type polymorf worden toegewezen, maar alleen aan een gegevenslid van het type Object. Hoewel het wordt geïmplementeerd IEnumerable, kan een matrix van XmlNode niet worden gebruikt als een verzamelingstype en worden toegewezen aan een IEnumerable gegevenslid. Net als bij alle polymorfe toewijzingen wordt de naam van het gegevenscontract verzonden DataContractSerializer in de resulterende XML. In dit geval is het 'ArrayOfXmlNode' in de http://schemas.datacontract.org/2004/07/System.Xml naamruimte. Bij gebruik met de NetDataContractSerializermatrix wordt elke geldige toewijzing van een XmlNode matrix ondersteund.

Overwegingen voor schema's

Zie Data Contract Schema Reference voor meer informatie over de schematoewijzing van XML-typen. Deze sectie bevat een overzicht van de belangrijke punten.

Een gegevenslid van het type XmlElement wordt toegewezen aan een element dat is gedefinieerd met behulp van het volgende anonieme type.

<xsd:complexType>  
   <xsd:sequence>  
      <xsd:any minOccurs="0" processContents="lax" />  
   </xsd:sequence>  
</xsd:complexType>  

Een gegevenslid van het type Matrix van XmlNode wordt toegewezen aan een element dat is gedefinieerd met behulp van het volgende anonieme type.

<xsd:complexType mixed="true">  
   <xsd:sequence>  
      <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />  
   </xsd:sequence>  
   <xsd:anyAttribute/>  
</xsd:complexType>  

Typen die de IXmlSerializable Interface implementeren

Typen die de IXmlSerializable interface implementeren, worden volledig ondersteund door de DataContractSerializer. Het XmlSchemaProviderAttribute kenmerk moet altijd worden toegepast op deze typen om hun schema te beheren.

Er zijn drie soorten typen die implementeren IXmlSerializable: typen die willekeurige inhoud vertegenwoordigen, typen die één element vertegenwoordigen en verouderde DataSet typen.

  • Inhoudstypen gebruiken een schemaprovidermethode die is opgegeven door het XmlSchemaProviderAttribute kenmerk. De methode retourneert nullniet en de IsAny eigenschap op het kenmerk blijft staan op de standaardwaarde van false. Dit is het meest voorkomende gebruik van IXmlSerializable typen.

  • Elementtypen worden gebruikt wanneer een IXmlSerializable type de naam van een eigen hoofdelement moet beheren. Als u een type als elementtype wilt markeren, stelt u de IsAny eigenschap van het XmlSchemaProviderAttribute kenmerk true in op null of retourneert u null uit de methode van de schemaprovider. Een schemaprovidermethode is optioneel voor elementtypen. U kunt null opgeven in plaats van de methodenaam in de XmlSchemaProviderAttribute. Als IsAny dat het zo is true en er een schemaprovidermethode is opgegeven, moet de methode null retourneren.

  • Verouderde DataSet typen zijn IXmlSerializable typen die niet zijn gemarkeerd met het XmlSchemaProviderAttribute kenmerk. In plaats daarvan zijn ze afhankelijk van de GetSchema methode voor het genereren van schema's. Dit patroon wordt gebruikt voor het DataSet type en de getypte gegevensset leidt een klasse af in eerdere versies van .NET Framework, maar is nu verouderd en wordt alleen ondersteund om verouderde redenen. Vertrouw niet op dit patroon en pas altijd de XmlSchemaProviderAttribute typen toe IXmlSerializable .

IXmlSerializable-inhoudstypen

Wanneer u een gegevenslid serialiseert van een type dat wordt geïmplementeerd en een inhoudstype IXmlSerializable is dat eerder is gedefinieerd, schrijft de serialisatiefunctie het wrapper-element voor het gegevenslid en geeft het besturingselement door aan de WriteXml methode. De WriteXml implementatie kan elke XML schrijven, inclusief het toevoegen van kenmerken aan het wrapper-element. Nadat WriteXml het is voltooid, sluit de serializer het element.

Wanneer een gegevenslid wordt gedeserialiseerd van een type dat een inhoudstype implementeert en een inhoudstype IXmlSerializable is zoals eerder is gedefinieerd, plaatst de deserializer de XML-lezer op het wrapper-element voor het gegevenslid en geeft het besturingselement door aan de ReadXml methode. De methode moet het hele element lezen, inclusief de begin- en eindtags. Zorg ervoor dat de ReadXml code het geval afhandelt waarin het element leeg is. Bovendien moet uw ReadXml implementatie niet vertrouwen op het wrapper-element dat een bepaalde manier wordt genoemd. De naam wordt gekozen door de serializer kan variëren.

Het is toegestaan om inhoudstypen polymorf toe te wijzen IXmlSerializable , bijvoorbeeld aan gegevensleden van het type Object. Het is ook toegestaan dat de typeexemplaren null zijn. Ten slotte is het mogelijk om typen te gebruiken IXmlSerializable met behoud van objectgrafiek ingeschakeld en met de NetDataContractSerializer. Voor al deze functies moet de WCF-serializer bepaalde kenmerken koppelen aan het wrapper-element ('nil' en 'type' in de naamruimte van het XML-schema-exemplaar en 'Id', 'Ref', 'Type' en 'Assembly' in een WCF-specifieke naamruimte).

Kenmerken die moeten worden genegeerd bij het implementeren van ReadXml

Voordat het besturingselement aan uw ReadXml code wordt doorgegeven, onderzoekt de deserializer het XML-element, detecteert deze speciale XML-kenmerken en handelt erop. Als 'nil' bijvoorbeeld is, wordt trueeen null-waarde gedeserialiseerd en ReadXml wordt deze niet aangeroepen. Als polymorfisme wordt gedetecteerd, wordt de inhoud van het element gedeserialiseerd alsof het een ander type is. De implementatie van ReadXml het polymorf toegewezen type wordt aangeroepen. In elk geval moet een ReadXml implementatie deze speciale kenmerken negeren omdat deze worden verwerkt door de deserializer.

Schemaoverwegingen voor IXmlSerializable-inhoudstypen

Wanneer u een schema exporteert naar een IXmlSerializable inhoudstype, wordt de methode van de schemaprovider aangeroepen. Er XmlSchemaSet wordt een doorgegeven aan de methode van de schemaprovider. De methode kan elk geldig schema toevoegen aan de schemaset. De schemaset bevat het schema dat al bekend is op het moment dat schema-export plaatsvindt. Wanneer de methode van de schemaprovider een item moet toevoegen aan de schemaset, moet deze bepalen of er al een XmlSchema met de juiste naamruimte in de set bestaat. Als dit het geval is, moet de methode van de schemaprovider het nieuwe item toevoegen aan het bestaande XmlSchema. Anders moet er een nieuw XmlSchema exemplaar worden gemaakt. Dit is belangrijk als matrices van IXmlSerializable typen worden gebruikt. Als u bijvoorbeeld een IXmlSerializable type hebt dat wordt geëxporteerd als type 'A' in naamruimte 'B', is het mogelijk dat de schemaprovidermethode op het moment dat de schemaprovidermethode het schema voor B bevat, al het schema voor 'B' bevat om het type ArrayOfA te bevatten.

Naast het toevoegen van typen aan de XmlSchemaSet, moet de methode van de schemaprovider voor inhoudstypen een niet-null-waarde retourneren. Het kan een XmlQualifiedName retourneert die de naam van het schematype aangeeft dat moet worden gebruikt voor het opgegeven IXmlSerializable type. Deze gekwalificeerde naam fungeert ook als de naam van het gegevenscontract en de naamruimte voor het type. Het is toegestaan om een type te retourneren dat niet direct in de schemaset bestaat wanneer de methode van de schemaprovider wordt geretourneerd. Het is echter verwacht dat alle gerelateerde typen worden geëxporteerd (de Export methode wordt aangeroepen voor alle relevante typen op de XsdDataContractExporter en de Schemas eigenschap wordt geopend), het type bestaat in de schemaset. Het openen van de Schemas eigenschap voordat alle relevante Export aanroepen zijn gedaan, kan leiden tot een XmlSchemaException. Zie Schema's exporteren uit klassen voor meer informatie over het exportproces.

De methode van de schemaprovider kan ook het XmlSchemaType te gebruiken resultaat geven. Het type is al dan niet anoniem. Als het anoniem is, wordt het schema voor het IXmlSerializable type geëxporteerd als een anoniem type telkens wanneer het IXmlSerializable type wordt gebruikt als gegevenslid. Het IXmlSerializable type heeft nog steeds een naam en naamruimte voor een gegevenscontract. (Dit wordt bepaald zoals beschreven in Namen van gegevenscontract , behalve dat het DataContractAttribute kenmerk niet kan worden gebruikt om de naam aan te passen.) Als het niet anoniem is, moet het een van de typen in de XmlSchemaSet. Dit geval is gelijk aan het retourneren van het XmlQualifiedName type.

Daarnaast wordt een globale elementdeclaratie geëxporteerd voor het type. Als het type het kenmerk niet op het kenmerk heeft XmlRootAttribute toegepast, heeft het element dezelfde naam en naamruimte als het gegevenscontract en is truede eigenschap 'nillable'. De enige uitzondering hierop is de schemanaamruimte (http://www.w3.org/2001/XMLSchema). Als het gegevenscontract van het type zich in deze naamruimte bevindt, bevindt het bijbehorende globale element zich in de lege naamruimte, omdat het verboden is om nieuwe elementen toe te voegen aan de schemanaamruimte. Als op het type het XmlRootAttribute kenmerk is toegepast, wordt de declaratie van het globale element geëxporteerd met behulp van de volgende eigenschappen: ElementName, Namespaceen IsNullable. De standaardinstellingen die worden XmlRootAttribute toegepast, zijn de naam van het gegevenscontract, een lege naamruimte en 'nillable' die waar zijn.

Dezelfde regels voor declaratie van globale elementen zijn van toepassing op verouderde gegevenssettypen. Houd er rekening mee dat de XmlRootAttribute declaraties van globale elementen die zijn toegevoegd via aangepaste code, niet XmlSchemaSet kunnen worden overschreven door middel van de methode van de schemaprovider of voor GetSchema verouderde gegevenssettypen.

Typen IXmlSerializable-elementen

IXmlSerializable elementtypen hebben de IsAny eigenschap ingesteld true op of hebben de methode van de schemaprovider geretourneerd null.

Het serialiseren en deserialiseren van een elementtype is vergelijkbaar met het serialiseren en deserialiseren van een inhoudstype. Er zijn echter enkele belangrijke verschillen:

  • De WriteXml implementatie zal naar verwachting precies één element schrijven (dat natuurlijk meerdere onderliggende elementen kan bevatten). Het mag geen kenmerken schrijven buiten dit ene element, meerdere elementen op hetzelfde niveau of gemengde inhoud. Het element is mogelijk leeg.

  • De ReadXml implementatie mag het wrapper-element niet lezen. Naar verwachting wordt het ene element gelezen dat WriteXml produceert.

  • Wanneer u een elementtype regelmatig serialiseert (bijvoorbeeld als gegevenslid in een gegevenscontract), voert de serializer een wrapper-element uit voordat het wordt aangeroepen WriteXml, net als bij inhoudstypen. Bij het serialiseren van een elementtype op het hoogste niveau voert de serializer normaal gesproken geen wrapper-element uit rond het element dat WriteXml wordt geschreven, tenzij er expliciet een hoofdnaam en naamruimte zijn opgegeven bij het maken van de serialisatiefunctie in de DataContractSerializer of NetDataContractSerializer constructors. Zie Serialisatie en deserialisatie voor meer informatie.

  • Bij het serialiseren van een elementtype op het hoogste niveau zonder de hoofdnaam en naamruimte tijdens de bouw op te geven, WriteStartObject en WriteEndObject voert in wezen niets en WriteObjectContent aanroepen WriteXmluit. In deze modus kan het object dat wordt geserialiseerd niet null zijn en kan niet polymorf worden toegewezen. Het behoud van objectgrafiek kan ook niet worden ingeschakeld en kan NetDataContractSerializer niet worden gebruikt.

  • Wanneer u een elementtype deserialiseert op het hoogste niveau zonder de hoofdnaam en naamruimte op te geven tijdens de bouw, IsStartObject wordt geretourneerd true of het begin van een element kan worden gevonden. ReadObject waarbij de verifyObjectName parameterset zich true op dezelfde manier gedraagt als IsStartObject voordat het object daadwerkelijk wordt gelezen. ReadObject geeft vervolgens het besturingselement door aan ReadXml de methode.

Het schema dat wordt geëxporteerd voor elementtypen is hetzelfde als voor het XmlElement type zoals beschreven in een eerdere sectie, behalve dat de methode van de schemaprovider elk extra schema kan toevoegen aan het XmlSchemaSet type, net als bij inhoudstypen. Het gebruik van het XmlRootAttribute kenmerk met elementtypen is niet toegestaan en globale elementdeclaraties worden nooit verzonden voor deze typen.

Verschillen met xmlSerializer

De IXmlSerializable interface en de XmlSchemaProviderAttributeXmlRootAttribute kenmerken worden ook begrepen door de XmlSerializer . Er zijn echter enkele verschillen in hoe deze worden behandeld in het gegevenscontractmodel. De belangrijke verschillen worden samengevat in het volgende:

  • De methode van de schemaprovider moet openbaar zijn om bruikbaar te zijn in de XmlSerializer, maar hoeft niet openbaar te zijn om bruikbaar te zijn in het gegevenscontractmodel.

  • De methode van de schemaprovider wordt aangeroepen wanneer IsAny waar is in het gegevenscontractmodel, maar niet met de XmlSerializer.

  • Wanneer het XmlRootAttribute kenmerk niet aanwezig is voor inhoud of verouderde gegevenssettypen, exporteert u XmlSerializer een globale elementdeclaratie in de lege naamruimte. In het gegevenscontractmodel is de gebruikte naamruimte normaal gesproken de naamruimte van het gegevenscontract, zoals eerder is beschreven.

Houd rekening met deze verschillen bij het maken van typen die worden gebruikt met beide serialisatietechnologieën.

IXmlSerializable Schema importeren

Bij het importeren van een schema dat is gegenereerd op basis van IXmlSerializable typen, zijn er enkele mogelijkheden:

  • Het gegenereerde schema kan een geldig gegevenscontractschema zijn, zoals beschreven in Data Contract Schema Reference. In dit geval kan het schema worden geïmporteerd zoals gebruikelijk en worden reguliere gegevenscontracttypen gegenereerd.

  • Het gegenereerde schema is mogelijk geen geldig gegevenscontractschema. Uw schemaprovidermethode kan bijvoorbeeld een schema genereren dat XML-kenmerken omvat die niet worden ondersteund in het gegevenscontractmodel. In dit geval kunt u het schema importeren als IXmlSerializable typen. Deze importmodus is niet standaard ingeschakeld, maar kan eenvoudig worden ingeschakeld, bijvoorbeeld met de /importXmlTypes opdrachtregelswitch naar het hulpprogramma voor metagegevens van ServiceModel (Svcutil.exe). Dit wordt gedetailleerd beschreven in het importschema voor het genereren van klassen. Houd er rekening mee dat u rechtstreeks met de XML voor uw typeexemplaren moet werken. U kunt ook overwegen om een andere serialisatietechnologie te gebruiken die ondersteuning biedt voor een breder scala aan schema's. Zie het onderwerp over het gebruik van de XmlSerializer.

  • Mogelijk wilt u uw bestaande IXmlSerializable typen opnieuw gebruiken in de proxy in plaats van nieuwe typen te genereren. In dit geval kan de functie waarnaar wordt verwezen in het importschema voor het genereren van typen worden gebruikt om aan te geven welk type opnieuw moet worden gebruikt. Dit komt overeen met het gebruik van de /reference schakelaar op svcutil.exe, waarmee de assembly wordt opgegeven die de typen bevat die moeten worden hergebruikt.

Willekeurige XML in gegevenscontracten vertegenwoordigen

Met de XmlElementmatrix en XmlNodeIXmlSerializable typen kunt u willekeurige XML in het gegevenscontractmodel injecteren. De DataContractSerializer en NetDataContractSerializer geef deze XML-inhoud door aan de XML-schrijver die in gebruik is, zonder het proces te verstoren. De XML-schrijvers kunnen echter bepaalde beperkingen afdwingen voor de XML die ze schrijven. Hier volgen enkele belangrijke voorbeelden:

  • De XML-schrijvers staan doorgaans geen XML-documentdeclaratie toe (bijvoorbeeld <?xml version='1.0'?>) in het midden van het schrijven van een ander document. U kunt een volledig XML-document niet gebruiken en het als gegevenslid ArrayXmlNode serialiseren. Hiervoor moet u de documentdeclaratie verwijderen of uw eigen coderingsschema gebruiken om deze weer te geven.

  • Alle XML-schrijvers die zijn geleverd met WCF weigeren XML-verwerkingsinstructies (<? ... ?>) en definities van documenttypen (<!... >), omdat ze niet zijn toegestaan in SOAP-berichten. Nogmaals, u kunt uw eigen coderingsmechanisme gebruiken om deze beperking te omzeilen. Als u deze in uw resulterende XML moet opnemen, kunt u een aangepaste encoder schrijven die gebruikmaakt van XML-schrijvers die deze ondersteunen.

  • Vermijd bij het implementeren van de methode voor het aanroepen WriteXmlvan WriteRaw de XML-schrijver. WCF maakt gebruik van verschillende XML-coderingen (inclusief binair), het is erg moeilijk of onmogelijk om zo te gebruiken WriteRaw dat het resultaat bruikbaar is in elke codering.

  • Vermijd bij het implementeren WriteXmlhet gebruik van de WriteEntityRef en WriteNmToken methoden die niet worden ondersteund op de XML-schrijvers die worden geleverd met WCF.

Gegevensset, getypte gegevensset en gegevenstabel gebruiken

Het gebruik van deze typen wordt volledig ondersteund in het gegevenscontractmodel. Houd bij het gebruik van deze typen rekening met de volgende punten:

  • Het schema voor deze typen (met name DataSet en de getypte afgeleide klassen) is mogelijk niet compatibel met sommige niet-WCF-platforms of kan leiden tot een slechte bruikbaarheid wanneer deze platforms worden gebruikt. Daarnaast kan het gebruik van het DataSet type gevolgen hebben voor de prestaties. Ten slotte kan het voor u lastiger zijn om uw toepassing in de toekomst te versien. Overweeg expliciet gedefinieerde gegevenscontracttypen te gebruiken in plaats van DataSet typen in uw contracten.

  • Bij het DataSet importeren of DataTable schema is het belangrijk om naar deze typen te verwijzen. Met het opdrachtregelprogramma Svcutil.exe kunt u dit doen door de System.Data.dll assemblynaam door te geven aan de /reference switch. Als u een getypt gegevenssetschema importeert, moet u verwijzen naar het type van de getypte gegevensset. Geef met Svcutil.exe de locatie van de assembly van de getypte gegevensset door aan de /reference switch. Zie het importschema voor het genereren van klassen voor meer informatie over verwijzingen naar typen.

Ondersteuning voor getypte DataSets in het gegevenscontractmodel is beperkt. Getypte DataSets kunnen worden geserialiseerd en gedeserialiseerd en kunnen hun schema exporteren. Het importeren van het gegevenscontractschema kan echter geen nieuwe gegevenssettypen genereren uit het schema, omdat bestaande gegevenssets alleen opnieuw kunnen worden gebruikt. U kunt naar een bestaande getypeerde DataSet verwijzen met behulp van de /r schakeloptie Svcutil.exe. Als u probeert een Svcutil.exe te gebruiken zonder de /r schakeloptie voor een service die gebruikmaakt van een getypte gegevensset, wordt automatisch een alternatieve serializer (XmlSerializer) geselecteerd. Als u DataContractSerializer moet gebruiken en DataSets moet genereren op basis van het schema, kunt u de volgende procedure gebruiken: de getypte DataSet-typen genereren (met behulp van het hulpprogramma Xsd.exe met de /d schakeloptie op de service), de typen compileren en deze vervolgens aanwijzen met behulp van de /r schakelaar op Svcutil.exe.

Zie ook