Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Opmerking
Dit artikel gaat over DataContractJsonSerializer. Voor de meeste scenario's waarbij JSON wordt geserialiseerd en gedeserialiseerd, raden we de API's aan in de naamruimte System.Text.Json.
JSON (JavaScript Object Notation) is een gegevensindeling die speciaal is ontworpen voor gebruik door JavaScript-code die wordt uitgevoerd op webpagina's in de browser. Dit is de standaardgegevensindeling die wordt gebruikt door ASP.NET AJAX-services die zijn gemaakt in Windows Communication Foundation (WCF).
Deze indeling kan ook worden gebruikt bij het maken van AJAX-services zonder integratie met ASP.NET. In dit geval is XML de standaardinstelling, maar kan JSON worden gekozen.
Ten slotte, als u JSON-ondersteuning nodig hebt maar geen AJAX-service maakt, maakt de DataContractJsonSerializer het mogelijk om .NET-objecten direct te serialiseren naar JSON-gegevens en dergelijke gegevens weer te deserialiseren naar .NET-type-instanties. Zie How to: Serialize and Deserialize JSON Data (JSON-gegevens serialiseren en deserialiseren) voor een beschrijving van hoe u dit doet.
Wanneer u met JSON werkt, worden dezelfde .NET-typen ondersteund, met enkele uitzonderingen, zoals wordt ondersteund door de DataContractSerializer. Zie Typen die worden ondersteund door de Serializer van het gegevenscontract voor een lijst met ondersteunde typen. Dit omvat de meeste primitieve typen, de meeste matrix- en verzamelingstypen, evenals complexe typen die gebruikmaken van en DataContractAttributeDataMemberAttribute.
.NET-typen toewijzen aan JSON-typen
In de volgende tabel ziet u de correspondentie tussen .NET-typen en JSON-/JavaScript-typen wanneer deze zijn toegewezen door serialisatie- en deserialisatieprocedures.
| .NET-typen | JSON/JavaScript | Opmerkingen |
|---|---|---|
| Alle numerieke typen, bijvoorbeeld Int32of DecimalDouble | Aantal | Speciale waarden zoals Double.NaNen Double.PositiveInfinityDouble.NegativeInfinity worden niet ondersteund en resulteren in ongeldige JSON. |
| Enum | Aantal | Zie 'Opsommingen en JSON' verderop in dit artikel. |
| Boolean | Booleaan | |
| String, Char | Snaar / Touwtje | |
| TimeSpan, , GuidUri | Snaar / Touwtje | De opmaak van deze typen in JSON is hetzelfde als in XML: de tijdsduur in het ISO 8601-formaat, GUID in het formaat 12345678-ABCD-ABCD-ABCD-1234567890AB, en URI in zijn natuurlijke tekstvorm zoals "http://www.example.com". Zie Data Contract Schema Reference (Schemareferentie voor gegevenscontract) voor nauwkeurige informatie. |
| XmlQualifiedName | Snaar / Touwtje | De indeling is "name:namespace" (alles wat vóór de eerste dubbele punt staat, is de naam). De naam of de naamruimte kan ontbreken. Als er geen naamruimte is, kan de dubbele punt ook worden weggelaten. |
| Array van het type Byte | Matrix met getallen | Elk getal vertegenwoordigt de waarde van één byte. |
| DateTime | Datum/tijd of tekenreeks | Zie Datums/tijden en JSON verderop in dit artikel. |
| DateTimeOffset | Complexe type | Zie Datums/tijden en JSON verderop in dit artikel. |
| XML- en ADO.NET-typen (XmlElement) XElement. Matrices van XmlNode, ISerializable, DataSet). |
Snaar / Touwtje | Zie de sectie XML-typen en JSON van dit artikel. |
| DBNull | Leeg complex soort | -- |
| Verzamelingen, woordenlijsten en matrices | Array | Zie de sectie Verzamelingen, woordenlijsten en matrices van dit onderwerp. |
| Complexe typen (met DataContractAttribute of SerializableAttribute toegepast) | Complexe type | Gegevensvelden worden onderdeel van het complexe JavaScript-type. |
| Complexe typen die de ISerializable interface implementeren) | Complexe type | Hetzelfde als andere complexe typen, maar sommige ISerializable typen worden niet ondersteund. Zie ISerializable Support. |
Null waarde voor elk type |
Nul | Nullable waarde types worden ook ondersteund en worden op dezelfde manier in JSON overgezet als niet-nullable waarde types. |
Opsommingen en JSON
De waarden van opsommingsleden worden behandeld als getallen in JSON. Dit verschilt van de manier waarop ze worden behandeld in gegevenscontracten, waarbij ze als lidnamen worden opgenomen. Zie Opsommingstypen in Gegevenscontracten voor meer informatie over de gegevenscontractbehandeling.
Bijvoorbeeld, als u
public enum Color {red, green, blue, yellow, pink}hebt, zal het serialiseren vanyellowhet getal 3 opleveren en niet de tekenreeks 'geel'.Alle
enumleden zijn serialiseerbaar. De EnumMemberAttribute en de NonSerializedAttribute kenmerken worden genegeerd als ze worden gebruikt.Het is mogelijk om een niet-bestaande
enumwaarde te deserialiseren, bijvoorbeeld de waarde 87 kan worden gedeserialiseerd in de vorige color-enum, zelfs als er geen overeenkomende kleurnaam is gedefinieerd.Een vlag
enumis niet speciaal en wordt hetzelfde behandeld als andereenum.
Data/tijden en JSON
De JSON-indeling biedt geen rechtstreekse ondersteuning voor datums en tijden. Ze worden echter zeer vaak gebruikt en ASP.NET AJAX biedt speciale ondersteuning voor deze typen. Wanneer u ASP.NET AJAX-proxy's gebruikt, komt het DateTime type in .NET volledig overeen met het DateTime type in JavaScript.
Wanneer u geen ASP.NET gebruikt, wordt een DateTime type in JSON weergegeven als een tekenreeks met een speciale indeling die wordt beschreven in de sectie Geavanceerde informatie van dit onderwerp.
DateTimeOffset wordt in JSON weergegeven als een complex type: {"DateTime":d ateTime,"OffsetMinutes":offsetMinutes}. Het
offsetMinuteselement is het lokale tijdsverschil van Greenwich Mean Time (GMT), ook bekend als Coordinated Universal Time (UTC), gekoppeld aan de locatie van het betreffende evenement. HetdateTimelid vertegenwoordigt het tijdstip waarop de gebeurtenis van belang heeft plaatsgevonden (het wordt dan eenDateTimein JavaScript wanneer ASP.NET AJAX wordt gebruikt en een tekenreeks wanneer dit niet het geval is). Tijdens serialisatie wordt hetdateTimelid altijd geserialiseerd in GMT. Dus, als we het hebben over 3:00 uur New York tijd,dateTimeheeft een tijdscomponent van 8:00 uur enoffsetMinutesis min 300 (min 300 minuten of 5 uur van GMT).Opmerking
DateTime en DateTimeOffset objecten behouden, wanneer ze naar JSON zijn geserialiseerd, alleen informatie tot precisie in milliseconden. Waarden van minder dan milliseconden (micro/nanoseconden) gaan verloren tijdens de serialisatie.
XML-formatten en JSON-indelingen
XML-typen worden JSON-tekenreeksen.
Als bijvoorbeeld een gegevenslid "q" van het type XElement de inhoud <abc/> bevat, is de JSON {"q":"<abc/>"}.
Er zijn enkele speciale regels die aangeven hoe XML wordt verpakt. Zie de sectie Geavanceerde informatie verderop in dit artikel voor meer informatie.
Als u ASP.NET AJAX gebruikt en geen tekenreeksen in JavaScript wilt gebruiken, maar in plaats daarvan de XML-DOM wilt gebruiken, stelt u de ResponseFormat eigenschap in op XML op WebGetAttribute XML of de ResponseFormat eigenschap op XML op de WebInvokeAttribute.
Verzamelingen, woordenlijsten en matrices
Alle verzamelingen, woordenlijsten en matrices worden in JSON weergegeven als matrices.
Aanpassingen die gebruikmaken van de toepassing CollectionDataContractAttribute , worden genegeerd in de JSON-weergave.
Woordenlijsten zijn geen manier om rechtstreeks met JSON te werken. In WCF kan een woordenboek<string, object> mogelijk niet op dezelfde manier worden ondersteund als verwacht bij het gebruik van andere JSON-technologieën. Als 'abc' bijvoorbeeld is toegewezen aan 'xyz' en 'def' is toegewezen aan 42 in een woordenlijst, is de JSON-weergave niet {"abc":"xyz","def":42} maar is [{"Key":"abc","Value":"xyz"},{"Key":"def","Value":42}] in plaats daarvan.
Als u rechtstreeks met JSON wilt werken (toegang tot sleutels en waarden dynamisch wilt gebruiken zonder vooraf een star contract te definiëren), hebt u verschillende opties:
Overweeg het gebruik van het ajax-voorbeeld (Weakly-typed JSON Serialization).
Overweeg het gebruik van de ISerializable interface- en deserialisatieconstructors. Met deze twee mechanismen hebt u respectievelijk toegang tot JSON-sleutel-/waardeparen voor serialisatie en deserialisatie, maar werkt u niet in gedeeltelijke vertrouwensscenario's.
Overweeg om te werken met de toewijzing tussen JSON en XML in plaats van een serializer te gebruiken.
Polymorfisme in de context van serialisatie verwijst naar de mogelijkheid om een afgeleid type te serialiseren waar het basistype wordt verwacht. Er zijn speciale JSON-specifieke regels wanneer u verzamelingen polymorf gebruikt, wanneer u bijvoorbeeld een verzameling toewijst aan een Object. Dit probleem wordt verderop in dit artikel uitgebreider besproken in de sectie Geavanceerde informatie.
Aanvullende details
Volgorde van gegevensleden
Volgorde van gegevensleden is niet belangrijk bij het gebruik van JSON. Specifiek kunnen JSON-gegevens, zelfs als deze Order is ingesteld, nog steeds in elke volgorde worden gedeserialiseerd.
JSON-typen
Het JSON-type hoeft niet overeen te komen met de voorgaande tabel voor deserialisatie. Bijvoorbeeld, een Int wordt normaal gesproken toegewezen aan een JSON-getal, maar het kan ook succesvol worden gedeserialiseerd vanuit een JSON-tekenreeks, zolang die tekenreeks een geldig getal bevat. Dat wil gezegd: {"q":42} en {"q":"42"} zijn geldig als er een Int gegevenslid met de naam q is.
Polymorfisme
Polymorfische serialisatie bestaat uit de mogelijkheid om een afgeleid type te serialiseren waarvan het basistype wordt verwacht. Dit wordt ondersteund voor JSON-serialisatie door WCF, vergelijkbaar met de manier waarop XML-serialisatie wordt ondersteund. U kunt bijvoorbeeld MyDerivedType serialiseren waar MyBaseType wordt verwacht, of Int serialiseren waar Object wordt verwacht.
Typegegevens gaan mogelijk verloren wanneer een afgeleid type wordt gedeserialiseerd als het basistype wordt verwacht, tenzij u een complex type deserialiseert. Als bijvoorbeeld Uri wordt geserialiseerd waar Object wordt verwacht, resulteert dit in een JSON-tekenreeks. Als deze tekenreeks vervolgens wordt gedeserialiseerd naar Object, wordt een .NET String geretourneerd. De deserializer weet niet dat de tekenreeks aanvankelijk van het type Uriwas. Over het algemeen, wanneer u Object verwacht, worden alle JSON-tekenreeksen gedeserialiseerd als .NET-tekenreeksen, en worden alle JSON-arrays die worden gebruikt voor het serialiseren van .NET-collecties, woordenlijsten en arrays gedeserialiseerd als .NET Array van het type Object, ongeacht wat het oorspronkelijke type was geweest. Een JSON-boolean wordt toegewezen aan een .NET Boolean. Wanneer u echter JSON-nummers verwacht, worden ze als .NET Object, Int32 of Decimal gedeserialiseerd, waarbij het meest geschikte type automatisch wordt gekozen.
Bij het deserialiseren in een interfacetype, wordt het DataContractJsonSerializer ontserialiseerd alsof het gedeclareerde type object was.
Wanneer u met uw eigen basis- en afgeleide typen werkt, wordt normaal gesproken het gebruik van KnownTypeAttribute, ServiceKnownTypeAttribute of een gelijkwaardig mechanisme vereist. Als u bijvoorbeeld een bewerking hebt die een Animal retourwaarde heeft en daadwerkelijk een exemplaar van Cat (afgeleid van Animal) retourneert, moet u het KnownTypeAttribute, op het Animal type of de ServiceKnownTypeAttribute bewerking toepassen en het Cat type in deze kenmerken opgeven. Zie Bekende typen gegevenscontracten voor meer informatie.
Zie de sectie Geavanceerde informatie verderop in dit artikel voor meer informatie over hoe polymorfe serialisatie werkt en een bespreking van enkele van de beperkingen die moeten worden gerespecteerd wanneer u deze gebruikt.
Versiebeheer
De functies voor versiebeheer van gegevenscontracten, inclusief de IExtensibleDataObject interface, worden volledig ondersteund in JSON. Bovendien is het in de meeste gevallen mogelijk om een type in één indeling (bijvoorbeeld XML) te deserialiseren en deze vervolgens te serialiseren in een andere indeling (bijvoorbeeld JSON) en de gegevens nog steeds in IExtensibleDataObjectte bewaren. Zie Forward-Compatible Data Contracts voor meer informatie. Houd er rekening mee dat JSON niet is gerangschikt, zodat alle ordergegevens verloren gaan. Bovendien biedt JSON geen ondersteuning voor meerdere sleutel-/waardeparen met dezelfde sleutelnaam. Ten slotte zijn alle bewerkingen op IExtensibleDataObject inherent polymorf: dat wil zeggen dat hun afgeleide type wordt toegewezen aan Object, het basistype voor alle typen.
JSON in URL's
Wanneer u ASP.NET AJAX-eindpunten gebruikt met het HTTP GET-werkwoord (met behulp van het WebGetAttribute kenmerk), worden binnenkomende parameters weergegeven in de aanvraag-URL in plaats van de berichttekst. JSON wordt zelfs ondersteund in de aanvraag-URL, dus als u een bewerking hebt die een Int zogenaamde 'getal' en een Person complex type met de naam 'p' gebruikt, lijkt de URL mogelijk op de volgende URL.
http://example.com/myservice.svc/MyOperation?number=7&p={"name":"John","age":42}
Als u een ASP.NET AJAX Script Manager-besturingselement en proxy gebruikt om de service aan te roepen, wordt deze URL automatisch gegenereerd door de proxy en wordt deze niet gezien. JSON kan niet worden gebruikt in URL's op non-ASP.NET AJAX-eindpunten.
Geavanceerde informatie
Ondersteuning voor ISerializable
ISerializable-typen: ondersteund en niet-ondersteund
Over het algemeen worden typen die de ISerializable interface implementeren volledig ondersteund bij het serialiseren/deserialiseren van JSON. Sommige van deze typen (waaronder sommige .NET Framework-typen) worden echter zodanig geïmplementeerd dat de JSON-specifieke serialisatieaspecten ervoor zorgen dat ze niet correct deserialiseren:
Hiermee ISerializablewordt het type afzonderlijke gegevensleden nooit van tevoren bekend. Dit leidt tot een polymorfe situatie die vergelijkbaar is met het deserialiseren van typen in een object. Zoals eerder vermeld, kan dit leiden tot verlies van typegegevens in JSON. Een type dat bijvoorbeeld een
enumin de ISerializable-implementatie serialiseert en probeert rechtstreeks te deserialiseren naar eenenum(zonder de juiste casts) zal mislukken, omdat eenenumwordt geserialiseerd met behulp van cijfers in JSON en JSON-getallen deserialiseren naar ingebouwde .NET-numerieke typen (Int32, Decimaal of Dubbel). Het feit dat het getal dat vroeger eenenumwaarde was, gaat dus verloren.Een ISerializable type dat afhankelijk is van een bepaalde volgorde van deserialisatie in zijn deserialisatieconstructor, kan mogelijk niet sommige JSON-data deserialiseren, omdat de meeste JSON-serializers geen specifieke volgorde garanderen.
Fabriekstypen
Hoewel de IObjectReference interface in het algemeen wordt ondersteund in JSON, worden alle typen waarvoor de functie Factory-type is vereist (waarbij een exemplaar van een ander type wordt geretourneerd dan het type GetRealObject(StreamingContext) dat de interface implementeert) niet ondersteund.
Datum/tijd-gegevensindeling
DateTime waarden worden weergegeven als JSON-tekenreeksen in de vorm van '/Date(700000+0500)/', waarbij het eerste getal (7000000 in het voorbeeld) het aantal milliseconden in de GMT-tijdzone is, normale (niet-zomertijd) tijd sinds middernacht, 1 januari 1970. Het getal kan negatief zijn om eerdere tijden weer te geven. Het deel dat uit '+0500' in het voorbeeld bestaat, is optioneel en geeft aan dat de tijd van het Local type is, dat wil gezegd, moet worden geconverteerd naar de lokale tijdzone voor deserialisatie. Als het afwezig is, wordt de tijd gedeserialiseerd als Utc. Het werkelijke getal ('0500' in dit voorbeeld) en het bijbehorende teken (+ of -) worden genegeerd.
Wanneer u serialiseert, worden DateTime en Local tijden geschreven met een offset en Unspecified zonder.
De javaScript-code van de ASP.NET AJAX-client converteert dergelijke tekenreeksen automatisch naar JavaScript-exemplaren DateTime . Als er andere tekenreeksen zijn die een vergelijkbare vorm hebben die niet van het type DateTime in .NET zijn, worden ze ook geconverteerd.
De conversie vindt alleen plaats als de '/'-tekens zijn ontsnapt (dat wil gezegd: de JSON ziet eruit als \/Date(700000+0500)\/), en om deze reden ontsnapt de JSON-encoder van WCF (ingeschakeld door de WebHttpBinding) altijd aan het teken '/'.
XML in JSON-tekenreeksen
XmlElement
XmlElement wordt geserialiseerd zoals het is, zonder omlijsting. Gegevenslid 'x' van het type XmlElement dat abc/< bevat>, wordt bijvoorbeeld als volgt weergegeven:
{"x":"<abc/>"}
Matrices van XmlNode
Array objecten van het type XmlNode worden verpakt in een element met de naam ArrayOfXmlNode in de standaardnaamruimte voor het gegevenscontract voor het type. Als 'x' een matrix is die kenmerkknooppunt 'N' bevat in naamruimte 'ns' die 'waarde' en een leeg elementknooppunt 'M' bevat, is de weergave als volgt.
{"x":"<ArrayOfXmlNode xmlns=\"http://schemas.datacontract.org/2004/07/System.Xml\" a:N=\"value\" xmlns:a=\"ns\"><M/></ArrayOfXmlNode>"}
Kenmerken in de lege naamruimte aan het begin van XmlNode-matrices (vóór andere elementen) worden niet ondersteund.
IXmlSerializable Types, waaronder XElement en DataSet
ISerializable typen worden onderverdeeld in 'inhoudstypen', 'Gegevenssettypen' en 'elementtypen'. Zie XML- en ADO.NET-typen in gegevenscontracten voor definities van deze typen.
De typen 'Inhoud' en 'DataSet' worden geserialiseerd op een vergelijkbare manier als de Array-objecten van XmlNode, die in de vorige sectie zijn besproken. Ze worden verpakt in een element waarvan de naam en naamruimte overeenkomt met de naam van het gegevenscontract en de naamruimte van het type in kwestie.
'Element'-typen zoals XElement worden zodanig geserialiseerd, vergelijkbaar met XmlElement zoals eerder in dit artikel besproken.
Polymorfisme
Typegegevens behouden
Zoals eerder vermeld, wordt polymorfisme ondersteund in JSON met enkele beperkingen. JavaScript is een zwak getypte taal en typeidentiteit is normaal gesproken geen probleem. Wanneer u echter JSON gebruikt om te communiceren tussen een sterk getypt systeem (.NET) en een zwak getypt systeem (JavaScript), is het handig om de typeidentiteit te behouden. Typen met gegevenscontractnamen 'Vierkant' en 'Cirkel' zijn bijvoorbeeld afgeleid van een type met de naam van het gegevenscontract 'Shape'. Als 'Circle' wordt verzonden van .NET naar JavaScript en later wordt geretourneerd naar een .NET-methode die verwacht dat 'Shape' wordt verwacht, is het handig voor de .NET-zijde om te weten dat het betreffende object oorspronkelijk een 'Cirkel' was. Anders kan informatie die specifiek is voor het afgeleide type (bijvoorbeeld 'radius'-gegevenslid op 'Cirkel') verloren gaan.
Als u de typeidentiteit wilt behouden, kan bij het serialiseren van complexe typen naar JSON een 'typehint' worden toegevoegd en herkent de deserializer de hint en handelt deze op de juiste manier. De 'typehint' is een JSON-sleutel/waardepaar met de sleutelnaam '__type' (twee onderstrepingstekens gevolgd door het woord 'type'). De waarde is een JSON-tekenreeks van het formulier 'DataContractName:DataContractNamespace' (alles tot aan de eerste dubbele punt is de naam). In het eerdere voorbeeld kan Cirkel als volgt worden geserialiseerd.
{"__type":"Circle:http://example.com/myNamespace","x":50,"y":70,"radius":10}
De typehint is vergelijkbaar met het xsi:type kenmerk dat is gedefinieerd door de standaard xml-schema-instantie en wordt gebruikt bij het serialiseren/deserialiseren van XML.
Gegevensleden met de naam '__type' zijn verboden vanwege een mogelijk conflict met de typehint.
De grootte van typehints verkleinen
Als u de grootte van JSON-berichten wilt verkleinen, wordt het standaardvoorvoegsel voor de naamruimte van het gegevenscontract (http://schemas.datacontract.org/2004/07/) vervangen door het teken #. (Als u deze vervanging omkeerbaar wilt maken, wordt een escape-regel gebruikt: als de naamruimte begint met de tekens '#' of '\', worden deze toegevoegd met een extra '\'-teken). Als 'Circle' dus een type is in de .NET-naamruimte 'MyApp.Shapes', is http://schemas.datacontract.org/2004/07/MyAppde standaardnaamruimte van het gegevenscontract. Shapes en de JSON-weergave zijn als volgt.
{"__type":"Circle:#MyApp.Shapes","x":50,"y":70,"radius":10}
Zowel de afgekorte (#MyApp.Shapes) als de volledige (http://schemas.datacontract.org/2004/07/MyApp.Shapes) namen worden begrepen bij deserialisatie.
Positie van type-hint in JSON-objecten
Houd er rekening mee dat de typehint eerst moet worden weergegeven in de JSON-weergave. Dit is het enige geval waarin volgorde van sleutel-/waardeparen belangrijk is in JSON-verwerking. Het volgende is bijvoorbeeld geen geldige manier om de typehint op te geven.
{"x":50,"y":70,"radius":10,"__type":"Circle:#MyApp.Shapes"}
Zowel de DataContractJsonSerializer clientpagina's van WCF als ASP.NET AJAX verzenden altijd eerst de typehint.
Typehints zijn alleen van toepassing op complexe typen
Er is geen manier om een typehint te verzenden voor niet-complexe typen. Als een bewerking bijvoorbeeld een Object retourtype heeft, maar een cirkel retourneert, kan de JSON-weergave worden weergegeven zoals eerder wordt weergegeven en blijft de typegegevens behouden. Als URI echter wordt geretourneerd, is de JSON-weergave een tekenreeks en gaat de tekenreeks die wordt gebruikt om een URI weer te geven verloren. Dit geldt niet alleen voor primitieve typen, maar ook voor verzamelingen en matrices.
Wanneer worden type hints gegenereerd
Typehints kunnen de berichtgrootte aanzienlijk vergroten (een manier om dit te verhelpen is het gebruik van kortere naamruimten voor gegevenscontract indien mogelijk). Daarom bepalen de volgende regels of type hints worden verzonden:
Wanneer u ASP.NET AJAX gebruikt, worden type-hints altijd waar mogelijk uitgevoerd, zelfs wanneer er geen basis-/afgeleide toewijzing plaatsvindt - bijvoorbeeld wanneer een cirkel aan een cirkel wordt toegewezen. (Dit is vereist om het proces van aanroepen vanuit de zwak getypte JSON-omgeving volledig in te schakelen in de sterk getypeerde .NET-omgeving zonder verrassend verlies van informatie.)
Bij gebruik van AJAX-services zonder ASP.NET-integratie worden typehints alleen uitgegeven wanneer er een basis-/afgeleidetoewijzing is, dat wil zeggen, wanneer Circle wordt toegewezen aan Shape of Object, maar niet wanneer het aan Circle is toegewezen. Dit biedt de minimale informatie die nodig is om een JavaScript-client correct te implementeren, waardoor de prestaties worden verbeterd, maar niet wordt beschermd tegen typegegevensverlies bij onjuist ontworpen clients. Vermijd basis-/afgeleide toewijzingen helemaal op de server als u wilt voorkomen dat dit probleem op de client wordt opgelost.
Wanneer u het DataContractSerializer type gebruikt, kunt u met de
alwaysEmitTypeInformationconstructorparameter kiezen tussen de voorgaande twee modi, waarbij de standaardwaarde 'false' is (indien nodig alleen hints voor het type verzenden).
Namen van gegevenslid dupliceren
Afgeleide typegegevens zijn aanwezig in hetzelfde JSON-object samen met basistypegegevens en kunnen in elke volgorde voorkomen. Kan bijvoorbeeld Shape als volgt worden weergegeven.
{"__type":"Shape:#MyApp.Shapes","x":50,"y":70}
Circle kan als volgt worden weergegeven.
{"__type":"Circle:#MyApp.Shapes","x":50, "radius":10,"y":70}
Als het basistype Shape ook een gegevenslid met de naam 'radius' bevat, leidt dit tot een botsing op beide serialisaties (omdat JSON-objecten geen herhalende sleutelnamen kunnen hebben) en deserialisatie (omdat het onduidelijk is of 'radius' verwijst naar Shape.radius of Circle.radius). Daarom wordt het concept 'eigenschap verbergen' (gegevensleden van dezelfde naam op basis en afgeleide klassen) over het algemeen niet aanbevolen in gegevenscontractklassen, maar is het in feite verboden in het geval van JSON.
Polymorfisme en IXmlSerializable Types
IXmlSerializable typen kunnen polymorf aan elkaar worden toegewezen, zoals gebruikelijk, zolang aan de vereisten voor bekende typen wordt voldaan, volgens de gebruikelijke regels voor gegevenscontracten. Het serialiseren van een IXmlSerializable type in plaats van een Object type resulteert echter in verlies van type-informatie omdat het resultaat een JSON-tekenreeks is.
Polymorfisme en bepaalde interfacetypen
Het is verboden om een verzamelingstype of een type te serialiseren dat wordt geïmplementeerd IXmlSerializable wanneer een niet-verzamelingstype niet IXmlSerializable (met uitzondering van Object) wordt verwacht. Een aangepaste interface, bijvoorbeeld IMyInterface, en een type MyType dat zowel IEnumerable<T> van het type int als IMyInterface implementeert. Het is verboden om MyType terug te geven van een bewerking waarvan het retourtype IMyInterface is. Dit komt doordat MyType moet worden geserialiseerd als een JSON-matrix en een typehint vereist, en zoals eerder is aangegeven, kunt u geen typehint met matrices opnemen, alleen met complexe typen.
Bekende typen en configuratie
Alle bekende typemechanismen die door het DataContractSerializer type worden gebruikt, worden ook op dezelfde manier ondersteund door de DataContractJsonSerializer. Beide serializers lezen hetzelfde configuratie-element, <dataContractSerializer> in <system.runtime.serialization>, om bekende typen te detecteren die zijn toegevoegd via een configuratiebestand.
Verzamelingen die zijn toegewezen aan object
Verzamelingen die aan Object zijn toegewezen, worden geserialiseerd alsof het verzamelingen zijn die gebruik maken van IEnumerable<T>: een JSON-array waarbij elke vermelding een typehint heeft als het een complex type is. Een List<T> van het type Shape toegewezen aan Object ziet er als volgt uit.
[{"__type":"Shape:#MyApp.Shapes","x":50,"y":70},
{"__type":"Shape:#MyApp.Shapes","x":58,"y":73},
{"__type":"Shape:#MyApp.Shapes","x":41,"y":32}]
Wanneer gedeserialiseerd wordt naar Object:
Shapemoet in de lijst Bekende typen staan. Een List<T> van het typeShapein bekende types hebben heeft geen effect. Houd er rekening mee dat u in dit geval niet hoeft toe te voegenShapeaan bekende typen voor serialisatie. Dit wordt automatisch gedaan.De verzameling wordt gedeserialiseerd als een Array van type Object dat
Shapeexemplaren bevat.
Afgeleide verzamelingen die zijn toegewezen aan basisverzamelingen
Wanneer een afgeleide verzameling wordt toegewezen aan een basisverzameling, wordt de verzameling meestal geserialiseerd alsof het een verzameling van het basistype was. Als het itemtype van de afgeleide verzameling echter niet kan worden toegewezen aan het itemtype van de basisverzameling, wordt er een uitzondering gegenereerd.
Type-aanwijzingen en Dictionaries
Wanneer een woordenlijst wordt toegewezen aan een Object, wordt elke sleutel- en waardevermelding in de woordenlijst behandeld alsof deze aan Object is toegewezen en krijgt een typehint.
Wanneer u woordenlijsttypen serialiseert, wordt het JSON-object dat de leden Sleutel en Waarde bevat, niet beïnvloed door de alwaysEmitTypeInformation instelling en bevat alleen een typehint wanneer de voorgaande verzamelingsregels dit vereisen.
Geldige JSON-sleutelnamen
De serializer XML-codeert sleutelnamen die geen geldige XML-namen zijn. Een gegevenslid met de naam 123 heeft bijvoorbeeld een gecodeerde naam, zoals '_x0031__x0032__x0033_' omdat '123' een ongeldige XML-elementnaam is (begint met een cijfer). Er kan een vergelijkbare situatie optreden bij sommige internationale tekensets die niet geldig zijn in XML-namen. Zie Toewijzing tussen JSON en XML voor een uitleg van dit effect van XML op JSON-verwerking.