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 XmlElement
van , 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 XmlNode
worden 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 XmlNode
zijn gedeclareerd als matrices van typen die zijn afgeleid XmlNode
van, 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 DataContractSerializer
matrix 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 NetDataContractSerializer
matrix 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 retourneertnull
niet en de IsAny eigenschap op het kenmerk blijft staan op de standaardwaarde vanfalse
. Dit is het meest voorkomende gebruik vanIXmlSerializable
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 kenmerktrue
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 deXmlSchemaProviderAttribute
. AlsIsAny
dat het zo istrue
en er een schemaprovidermethode is opgegeven, moet de methode null retourneren.Verouderde DataSet typen zijn
IXmlSerializable
typen die niet zijn gemarkeerd met hetXmlSchemaProviderAttribute
kenmerk. In plaats daarvan zijn ze afhankelijk van de GetSchema methode voor het genereren van schema's. Dit patroon wordt gebruikt voor hetDataSet
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 deXmlSchemaProviderAttribute
typen toeIXmlSerializable
.
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 true
een 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 true
de 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 datWriteXml
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 datWriteXml
wordt geschreven, tenzij er expliciet een hoofdnaam en naamruimte zijn opgegeven bij het maken van de serialisatiefunctie in deDataContractSerializer
ofNetDataContractSerializer
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
WriteXml
uit. 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 kanNetDataContractSerializer
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 deverifyObjectName
parameterset zichtrue
op dezelfde manier gedraagt alsIsStartObject
voordat het object daadwerkelijk wordt gelezen.ReadObject
geeft vervolgens het besturingselement door aanReadXml
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 XmlSchemaProviderAttribute
XmlRootAttribute
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 deXmlSerializer
.Wanneer het
XmlRootAttribute
kenmerk niet aanwezig is voor inhoud of verouderde gegevenssettypen, exporteert uXmlSerializer
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 deXmlSerializer
.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 XmlElement
matrix en XmlNode
IXmlSerializable
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
Array
XmlNode
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
WriteXml
van WriteRaw de XML-schrijver. WCF maakt gebruik van verschillende XML-coderingen (inclusief binair), het is erg moeilijk of onmogelijk om zo te gebruikenWriteRaw
dat het resultaat bruikbaar is in elke codering.Vermijd bij het implementeren
WriteXml
het 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 vanDataSet
typen in uw contracten.Bij het
DataSet
importeren ofDataTable
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.