Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Annotazioni
Questo articolo è relativo a DataContractJsonSerializer. Per la maggior parte degli scenari che comportano la serializzazione e la deserializzazione di JSON, è consigliabile usare le API nello spazio dei nomi System.Text.Json.
JSON (JavaScript Object Notation) è un formato di dati appositamente progettato per essere usato dal codice JavaScript in esecuzione nelle pagine Web all'interno del browser. È il formato di dati predefinito usato da ASP.NET servizi AJAX creati in Windows Communication Foundation (WCF).
Questo formato può essere usato anche durante la creazione di servizi AJAX senza l'integrazione con ASP.NET. In questo caso, XML è l'impostazione predefinita, ma è possibile scegliere JSON.
Infine, se è necessario il supporto JSON ma non si crea un servizio AJAX, DataContractJsonSerializer consente di serializzare direttamente gli oggetti .NET in dati JSON e di deserializzare tali dati in istanze di tipi .NET. Per una descrizione di come eseguire questa operazione, vedere Procedura: Serializzare e deserializzare i dati JSON.
Quando si usa JSON, sono supportati gli stessi tipi .NET, con alcune eccezioni, come sono supportati da DataContractSerializer. Per un elenco dei tipi supportati, vedere Tipi supportati dal serializzatore di contratti dati. Sono inclusi la maggior parte dei tipi primitivi, la maggior parte dei tipi array e collezione, nonché i tipi complessi che usano il DataContractAttribute e il DataMemberAttribute.
Eseguire il mapping dei tipi .NET ai tipi JSON
La tabella seguente illustra la corrispondenza tra i tipi .NET e i tipi JSON/JavaScript quando viene eseguito il mapping tramite le procedure di serializzazione e deserializzazione.
| Tipi .NET | JSON/JavaScript | Note |
|---|---|---|
| Tutti i tipi numerici, ad esempio Int32, Decimal o Double | Numero | I valori speciali, Double.NaNad esempio , Double.PositiveInfinity e Double.NegativeInfinity non sono supportati e generano codice JSON non valido. |
| Enum | Numero | Vedere "Enumerazioni e JSON" più avanti in questo articolo. |
| Boolean | Booleano | |
| String, Char | Stringa | |
| TimeSpan, Guid, Uri | Stringa | Il formato di questi tipi in JSON è uguale a quello in XML (essenzialmente, intervallo di tempo nel formato ISO 8601 Duration, GUID nel formato "12345678-ABCD-ABCD-ABCD-1234567890AB" e URI nel formato stringa naturale come "http://www.example.com"). Per informazioni precise, vedere Riferimento allo schema del contratto dati. |
| XmlQualifiedName | Stringa | Il formato è "name:namespace" (qualsiasi elemento prima del primo due punti è il nome). Il nome o il namespace può essere mancante. Se non è presente alcuno spazio dei nomi, è possibile omettere i due punti. |
Command di tipo System.Windows.Input.ICommand |
Matrice di numeri | Ogni numero rappresenta il valore di un byte. |
| DateTime | Data e Ora o Stringa | Vedere Date/Ore e JSON più avanti in questo articolo. |
| DateTimeOffset | Tipo complesso | Vedere Date/Ore e JSON più avanti in questo articolo. |
| Tipi XML e ADO.NET (XmlElement, XElement. Matrici di XmlNode, ISerializable, DataSet). |
Stringa | Vedere la sezione Tipi XML e JSON di questo articolo. |
| DBNull | Tipo complesso vuoto | -- |
| Raccolte, dizionari e matrici | Array | Vedere la sezione Raccolte, dizionari e matrici di questo argomento. |
| Tipi complessi (con DataContractAttribute o SerializableAttribute applicati) | Tipo complesso | I campi dati diventano membri del tipo complesso JavaScript. |
| Tipi complessi che implementano l'interfaccia ISerializable ) | Tipo complesso | Analogamente ad altri tipi complessi, alcuni ISerializable tipi non sono supportati – vedere Supporto ISerializable per dettagli. |
Null valore per qualsiasi tipo |
Nullo | I tipi di valore nullable sono anche supportati e mappati su JSON allo stesso modo dei tipi di valore non nullable. |
Enumerazioni e JSON
I valori dei membri di enumerazione vengono considerati come numeri in JSON, che è diverso dal modo in cui vengono trattati nei contratti dati, dove vengono inclusi come nomi di membri. Per altre informazioni sul trattamento del contratto dati, vedere Tipi di enumerazione nei contratti dati.
Ad esempio, se si ha
public enum Color {red, green, blue, yellow, pink}e si serializzayellow, questo produce il numero 3 e non la stringa "gialla".Tutti i
enummembri sono serializzabili. Gli EnumMemberAttribute attributi e NonSerializedAttribute vengono ignorati se utilizzati.È possibile deserializzare un valore inesistente
enum, ad esempio il valore 87 può essere deserializzato nell'enumerazione Color precedente anche se non è definito alcun nome di colore corrispondente.Un flag
enumnon è speciale e viene trattato lo stesso di qualsiasi altroenum.
Date/ore e JSON
Il formato JSON non supporta direttamente date e ore. Tuttavia, sono molto comunemente usati e ASP.NET AJAX fornisce supporto speciale per questi tipi. Quando si usano i proxy AJAX di ASP.NET, il DateTime tipo in .NET corrisponde completamente al DateTime tipo in JavaScript.
Quando non si usa ASP.NET, un DateTime tipo viene rappresentato in JSON come stringa con un formato speciale descritto nella sezione Informazioni avanzate di questo argomento.
DateTimeOffset è rappresentato in JSON come tipo complesso: {"DateTime":d ateTime,"OffsetMinutes":offsetMinutes}. Il
offsetMinutesmembro è l'offset dell'ora locale rispetto all'ora di Greenwich (GMT), ora noto anche come UTC (Coordinated Universal Time), associato alla posizione dell'evento di interesse. IldateTimemembro rappresenta l'istante in cui si verifica l'evento di interesse (nel caso di utilizzo di ASP.NET AJAX, diventa un oggettoDateTimein JavaScript, altrimenti diventa una stringa). Durante la serializzazione, ildateTimemembro viene sempre serializzato in GMT. Pertanto, se si descrive l'ora di New York alle 3:00,dateTimeha un componente di ora delle 8:00 eoffsetMinutessono 300 (meno 300 minuti o 5 ore dal GMT).Annotazioni
DateTime e DateTimeOffset gli oggetti, se serializzati in JSON, mantengono solo le informazioni sulla precisione in millisecondi. I valori sub millisecondi (micro/nanosecondi) vengono persi durante la serializzazione.
Tipi XML e JSON
I tipi XML diventano stringhe JSON.
Ad esempio, se un membro dati "q" di tipo XElement contiene <abc/>, il codice JSON è {"q":"<abc/>"}.
Esistono alcune regole speciali che specificano il modo in cui viene eseguito il wrapping xml. Per altre informazioni, vedere la sezione Informazioni avanzate più avanti in questo articolo.
Se si usa ASP.NET AJAX e non si desidera utilizzare stringhe nel JavaScript, ma si preferisce utilizzare il DOM XML, è possibile impostare la proprietà ResponseFormat su XML su WebGetAttribute o la proprietà ResponseFormat su XML su WebInvokeAttribute.
Raccolte, dizionari e matrici
Tutte le raccolte, i dizionari e le matrici sono rappresentati in JSON come matrici.
Qualsiasi personalizzazione che usa il CollectionDataContractAttribute viene ignorata nella rappresentazione JSON.
I dizionari non sono un modo per lavorare direttamente con JSON. Stringa di dizionario<, l'oggetto> potrebbe non essere supportato nello stesso modo in WCF previsto dall'uso di altre tecnologie JSON. Ad esempio, se si esegue il mapping di "abc" a "xyz" e "def" a 42 in un dizionario, la rappresentazione JSON non è {"abc":"xyz","def":42}, ma [{ "Key":"abc", "Value":"xyz"}, {"Key":"def", "Value":42}].
Se si vuole lavorare direttamente con JSON (accesso a chiavi e valori in modo dinamico, senza definire un contratto rigido), sono disponibili diverse opzioni:
Prendere in considerazione l'uso dell'esempio AJAX (Weakly-typed JSON Serialization).
È consigliabile usare l'interfaccia ISerializable e i costruttori di deserializzazione. Questi due meccanismi consentono di accedere rispettivamente alle coppie chiave/valore JSON sulla serializzazione e sulla deserializzazione, ma non funzionano in scenari di fiducia parziale.
Prendere in considerazione l'uso del mapping tra JSON e XML invece di usare un serializzatore.
Il polimorfismo nel contesto della serializzazione si riferisce alla possibilità di serializzare un tipo derivato in cui è previsto il tipo di base. Esistono regole speciali specifiche di JSON quando si usano le raccolte in modo polimorfico, ad esempio quando si assegna una raccolta a un oggetto Object. Questo problema è descritto più in dettaglio nella sezione Informazioni avanzate più avanti in questo articolo.
Dettagli aggiuntivi
Ordine dei membri dati
L'ordine dei membri dati non è importante quando si usa JSON. In particolare, anche se Order è impostato, i dati JSON possono comunque essere deserializzati in qualsiasi ordine.
Tipi JSON
Il tipo JSON non deve corrispondere alla tabella precedente alla deserializzazione. Ad esempio, un oggetto Int normalmente esegue il mapping a un numero JSON, ma può anche essere deserializzato correttamente da una stringa JSON purché tale stringa contenga un numero valido. Ovvero, sia {"q":42} che {"q":"42"} sono validi se è presente un Int membro dati denominato "q".
Polimorfismo
La serializzazione polimorfica è costituita dalla possibilità di serializzare un tipo derivato in cui è previsto il tipo di base. Questa funzionalità è supportata per la serializzazione JSON da WCF paragonabile al modo in cui è supportata la serializzazione XML. Ad esempio, è possibile serializzare MyDerivedType dove MyBaseType è previsto o serializzare Int dove Object è previsto.
Le informazioni sul tipo possono essere perse durante la deserializzazione di un tipo derivato se è previsto il tipo di base, a meno che non si deseriali un tipo complesso. Ad esempio, se Uri viene serializzato dove Object è previsto, viene restituita una stringa JSON. Se questa stringa viene deserializzata nuovamente in Object, viene restituito un file .NET String . Il deserializzatore non sa che la stringa era inizialmente di tipo Uri. In genere, quando si prevede Object, tutte le stringhe JSON vengono deserializzate come stringhe .NET e tutte le matrici JSON usate per serializzare raccolte, dizionari e matrici .NET vengono deserializzate come .NET Array di tipo Object, indipendentemente dal tipo originale effettivo. Un valore booleano JSON corrisponde a un .NET Boolean. Tuttavia, quando si prevede un Object, i numeri JSON vengono deserializzati come .NET Int32, Decimal o Double, dove viene selezionato automaticamente il tipo più appropriato.
Durante la deserializzazione in un tipo di interfaccia, DataContractJsonSerializer viene deserializzato come se il tipo dichiarato fosse un oggetto.
Quando si lavora con tipi di base e derivati personalizzati, è generalmente necessario utilizzare i tag KnownTypeAttribute, ServiceKnownTypeAttribute o un meccanismo equivalente. Ad esempio, se si dispone di un'operazione con un valore di ritorno Animal e questa restituisce effettivamente un'istanza di Cat (derivata da Animal), è necessario applicare KnownTypeAttribute al tipo Animal o ServiceKnownTypeAttribute all'operazione, e specificare il tipo Cat in questi attributi. Per altre informazioni, vedere Tipi noti del contratto dati.
Per informazioni dettagliate sul funzionamento della serializzazione polimorfica e su alcune delle limitazioni che devono essere rispettate durante l'uso, vedere la sezione Informazioni avanzate più avanti in questo articolo.
Controllo delle versioni
Le funzionalità di controllo delle versioni del contratto dati, inclusa l'interfaccia IExtensibleDataObject , sono completamente supportate in JSON. Inoltre, nella maggior parte dei casi è possibile deserializzare un tipo in un formato (ad esempio, XML) e quindi serializzarlo in un altro formato (ad esempio JSON) e mantenere comunque i dati in IExtensibleDataObject. Per altre informazioni, vedere Forward-Compatible Contratti dati. Tenere presente che JSON non è ordinato in modo che le informazioni sull'ordine vengano perse. Json non supporta inoltre più coppie chiave/valore con lo stesso nome di chiave. Infine, tutte le operazioni su IExtensibleDataObject sono intrinsecamente polimorfiche, ovvero il tipo derivato vengono assegnate a Object, il tipo di base per tutti i tipi.
JSON negli URL
Quando si usano ASP.NET endpoint AJAX con il verbo HTTP GET (usando l'attributo ), i parametri in ingresso vengono visualizzati nell'URL WebGetAttribute della richiesta anziché nel corpo del messaggio. JSON è supportato anche nell'URL della richiesta, quindi se si dispone di un'operazione che accetta un Int tipo denominato "number" e un Person tipo complesso denominato "p", l'URL potrebbe essere simile all'URL seguente.
http://example.com/myservice.svc/MyOperation?number=7&p={"name":"John","age":42}
Se usi un controllo Gestore script AJAX di ASP.NET e un proxy per chiamare il servizio, questo URL viene generato automaticamente dal proxy e non viene visualizzato. Non è possibile usare JSON negli URL in non-ASP.NET endpoint AJAX.
Informazioni avanzate
Supporto ISerializable
Tipi ISerializable supportati e non supportati
In generale, i tipi che implementano l'interfaccia ISerializable sono completamente supportati durante la serializzazione/deserializzazione di JSON. Tuttavia, alcuni di questi tipi, inclusi alcuni tipi .NET Framework, vengono implementati in modo che gli aspetti specifici della serializzazione JSON causano una deserializzazione errata.
Con ISerializable, il tipo di singoli membri dati non è mai noto in anticipo. Ciò comporta una situazione polimorfica simile alla deserializzazione dei tipi in un oggetto . Come accennato in precedenza, questo può causare la perdita di informazioni sul tipo in JSON. Ad esempio, un tipo che serializza un
enumnella sua implementazione ISerializable e tenta di deserializzare direttamente in unenum(senza cast appropriati) fallisce perché unenumviene serializzato utilizzando numeri in JSON e questi vengono deserializzati in tipi numerici predefiniti di .NET (Int32, Decimal o Double). Quindi il fatto che il numero fosse unenumvalore è stato perso.Un ISerializable tipo che dipende da un ordine specifico di deserializzazione nel relativo costruttore di deserializzazione può anche non riuscire a deserializzare alcuni dati JSON, perché la maggior parte dei serializzatori JSON non garantisce alcun ordine specifico.
Tipi di fabbrica
Anche se l'interfaccia IObjectReference è supportata in JSON in generale, tutti i tipi che richiedono la funzionalità "tipo factory" (restituendo un'istanza di un tipo diverso da GetRealObject(StreamingContext) quello che implementa l'interfaccia) non sono supportati.
Formato di collegamento DateTime
DateTime i valori vengono visualizzati come stringhe JSON sotto forma di "/Date(700000+0500)/", dove il primo numero (700000 nell'esempio fornito) è il numero di millisecondi nel fuso orario GMT, ora regolare (senza ora legale) dalla mezzanotte del 1° gennaio 1970. Il numero può essere negativo per rappresentare i tempi precedenti. La parte costituita da "+0500" nell'esempio è facoltativa e indica che l'ora è del Local tipo, ovvero deve essere convertita nel fuso orario locale alla deserializzazione. Se è assente, l'ora viene deserializzata come Utc. Il numero effettivo ("0500" in questo esempio) e il relativo segno (+ o -) vengono ignorati.
Quando si serializzano DateTime, Local e Unspecified, le ore vengono scritte con un offset, mentre Utc viene scritto senza.
Il codice JavaScript del client AJAX ASP.NET converte automaticamente tali stringhe in istanze JavaScript DateTime . Se sono presenti altre stringhe con un formato simile che non sono di tipo DateTime in .NET, vengono convertite anche.
La conversione avviene solo se i caratteri "/" sono preceduti da un carattere di escape (ovvero il codice JSON è simile a "\/Date(70000+0500)\/"), e per questo motivo il codificatore JSON di WCF (abilitato da WebHttpBinding) esegue sempre l'escape del carattere "/".
XML nelle stringhe JSON
XmlElement
XmlElement viene serializzato così com'è, senza essere racchiuso. Ad esempio, il membro dati "x" di tipo XmlElement che contiene <abc/> è rappresentato come segue:
{"x":"<abc/>"}
Matrici di XmlNode
Array gli oggetti di tipo XmlNode vengono inclusi in un elemento denominato ArrayOfXmlNode nello spazio dei nomi del contratto dati standard per il tipo. Se "x" è una matrice che contiene il nodo attributo "N" nello spazio dei nomi "ns" che contiene "value" e un nodo elemento vuoto "M", la rappresentazione è la seguente.
{"x":"<ArrayOfXmlNode xmlns=\"http://schemas.datacontract.org/2004/07/System.Xml\" a:N=\"value\" xmlns:a=\"ns\"><M/></ArrayOfXmlNode>"}
Gli attributi nello spazio dei nomi vuoto all'inizio delle matrici XmlNode (prima di altri elementi) non sono supportati.
I tipi IXmlSerializable, inclusi XElement e DataSet
ISerializable i tipi sono suddivisi in "tipi di contenuto", "Tipi di DataSet" e "tipi di elemento". Per le definizioni di questi tipi, vedere TIPI XML e ADO.NET in Contratti dati.
I tipi "Content" e "DataSet" vengono serializzati in modo analogo agli Array oggetti descritti XmlNode nella sezione precedente. Vengono inclusi in un elemento il cui nome e spazio dei nomi corrispondono al nome e allo spazio dei nomi del contratto dati del tipo in questione.
I tipi "Element", come XElement, sono serializzati così come sono, come illustrato in precedenza con XmlElement in questo articolo.
Polimorfismo
Mantenimento delle informazioni sul tipo
Come indicato in precedenza, il polimorfismo è supportato in JSON con alcune limitazioni. JavaScript è un linguaggio a tipizzazione debole e l'identificazione del tipo di solito non rappresenta un problema. Tuttavia, quando si usa JSON per comunicare tra un sistema fortemente tipizzato (.NET) e un sistema debolmente tipizzato (JavaScript), è utile mantenere l'identità dei tipi. Ad esempio, i tipi con nomi di contratto dati "Square" e "Circle" derivano da un tipo con un nome di contratto dati "Shape". Se "Circle" viene inviato da .NET a JavaScript e successivamente viene restituito a un metodo .NET che prevede "Shape", è utile per il lato .NET sapere che l'oggetto in questione era originariamente un "Circle", altrimenti eventuali informazioni specifiche del tipo derivato (ad esempio, il membro dati "radius" in "Circle") potrebbero andare perse.
Per mantenere l'identità del tipo, quando si serializzano tipi complessi in JSON è possibile aggiungere un "hint di tipo" e il deserializzatore riconosce l'hint e agisce in modo appropriato. Il "type hint" è una coppia chiave/valore JSON con la chiave denominata "__type" (due trattini bassi seguiti dalla parola "type"). Il valore è una stringa JSON nel formato "DataContractName:DataContractNamespace" (qualsiasi elemento fino ai primi due punti è il nome). Usando l'esempio precedente, "Circle" può essere serializzato come indicato di seguito.
{"__type":"Circle:http://example.com/myNamespace","x":50,"y":70,"radius":10}
L'hint di tipo è molto simile all'attributo definito dallo standard dell'istanza xsi:type di XML Schema e usato durante la serializzazione/deserializzazione di XML.
I membri dati denominati "__type" non sono consentiti a causa di potenziali conflitti con l'indicazione di tipo.
Riduzione delle dimensioni delle annotazioni di tipo
Per ridurre le dimensioni dei messaggi JSON, il prefisso predefinito dello spazio dei nomi del contratto dati (http://schemas.datacontract.org/2004/07/) viene sostituito con il carattere "#". Per rendere reversibile questa sostituzione, viene usata una regola di escape: se lo spazio dei nomi inizia con i caratteri "#" o "\", vengono accompagnati da un carattere "\" aggiuntivo. Pertanto, se "Circle" è un tipo nello spazio dei nomi .NET "MyApp.Shapes", lo spazio dei nomi predefinito del contratto dati è http://schemas.datacontract.org/2004/07/MyApp. Le forme e la rappresentazione JSON sono le seguenti.
{"__type":"Circle:#MyApp.Shapes","x":50,"y":70,"radius":10}
Sia i nomi troncati (#MyApp.Shapes) sia i nomi completi (http://schemas.datacontract.org/2004/07/MyApp.Shapes) vengono riconosciuti durante la deserializzazione.
Posizione del tipo hint negli oggetti JSON
Si noti che l'hint di tipo deve essere visualizzato per primo nella rappresentazione JSON. Questo è l'unico caso in cui l'ordine delle coppie chiave/valore è importante nell'elaborazione JSON. Ad esempio, il codice seguente non è un modo valido per specificare il suggerimento di tipo.
{"x":50,"y":70,"radius":10,"__type":"Circle:#MyApp.Shapes"}
Sia l'oggetto DataContractJsonSerializer usato da WCF sia le pagine client AJAX di ASP.NET generano sempre per primo il suggerimento di tipo.
Gli hint di tipo si applicano solo ai tipi complessi
Non è possibile generare un hint di tipo per i tipi non complessi. Ad esempio, se un'operazione ha un Object tipo restituito ma restituisce un circle, la rappresentazione JSON può essere come illustrato in precedenza e le informazioni sul tipo vengono mantenute. Tuttavia, se l'URI viene restituito, la rappresentazione JSON è una stringa e si perde il fatto che la stringa fosse utilizzata per rappresentare un URI. Questo vale non solo per i tipi primitivi, ma anche per le raccolte e le matrici.
Quando sono emessi gli hint di tipo
Gli hint di tipo possono aumentare significativamente le dimensioni dei messaggi (un modo per attenuare questo problema consiste nell'usare spazi dei nomi dei contratti di dati più brevi, se possibile). Di conseguenza, le regole seguenti determinano se vengono generati hint di tipo:
Quando si utilizza ASP.NET AJAX, i suggerimenti di tipo vengono sempre generati ove possibile, anche se non vi è alcuna assegnazione di base/derivata. Ad esempio, anche nel caso in cui un Cerchio sia assegnato a un Cerchio. Questa operazione è necessaria per abilitare completamente il processo di chiamata dall'ambiente JSON debolmente tipizzato all'ambiente .NET fortemente tipizzato senza una perdita inattesa di informazioni.
Quando si usano servizi AJAX senza integrazione ASP.NET, gli hint di tipo vengono generati solo quando è presente un'assegnazione di base/derivata, ovvero generata quando Circle viene assegnato a Shape o Object non quando viene assegnato a Circle. In questo modo vengono fornite le informazioni minime necessarie per implementare correttamente un client JavaScript, migliorando così le prestazioni, ma non contro la perdita di informazioni sui tipi nei client progettati in modo non corretto. Evitare completamente assegnazioni di base/derivate nel server se si vuole evitare di gestire questo problema nel client.
Quando si usa il DataContractSerializer tipo, il
alwaysEmitTypeInformationparametro del costruttore consente di scegliere tra le due modalità precedenti, con l'impostazione predefinita "false" (vengono generati solo hint di tipo quando necessario).
Nomi duplicati dei membri di dati
Le informazioni sul tipo derivato sono presenti nello stesso oggetto JSON insieme alle informazioni sul tipo di base e possono verificarsi in qualsiasi ordine. Ad esempio, Shape può essere rappresentato come segue.
{"__type":"Shape:#MyApp.Shapes","x":50,"y":70}
Mentre Circle può essere rappresentato come segue.
{"__type":"Circle:#MyApp.Shapes","x":50, "radius":10,"y":70}
Se il tipo di base Shape conteneva anche un membro dati denominato "radius", ciò comporta un conflitto in entrambe le serializzazioni (perché gli oggetti JSON non possono avere nomi di chiave ripetuti) e deserializzazione (perché non è chiaro se "radius" fa riferimento a Shape.radius o Circle.radius). Pertanto, sebbene il concetto di "proprietà nascosta" (membri dati dello stesso nome su classi basate e derivate) non sia in genere consigliato nelle classi del contratto dati, in realtà non è consentito nel caso di JSON.
Polimorfismo e tipi IXmlSerializable
IXmlSerializable I tipi possono essere assegnati polimorficamente l'uno all'altro, purché vengano soddisfatti i requisiti dei tipi noti, in base alle normali regole del contratto dati. Tuttavia, la serializzazione di un IXmlSerializable tipo al posto di Object comporta la perdita di informazioni sul tipo come risultato è una stringa JSON.
Polimorfismo e determinati tipi di interfaccia
Non è consentito serializzare un tipo di raccolta o un tipo che implementa IXmlSerializable quando è previsto un tipo non di raccolta diverso da IXmlSerializable (ad eccezione di Object). Ad esempio, un'interfaccia personalizzata chiamata IMyInterface e un tipo MyType che implementano sia IEnumerable<T> di tipo int sia IMyInterface. Non è consentito restituire MyType da un'operazione il cui tipo restituito è IMyInterface. Ciò è dovuto al fatto che MyType deve essere serializzato come array JSON e richiede un hint di tipo e, come indicato prima, non si può includere un hint di tipo con gli array, solo con tipi complessi.
Tipi noti e configurazione
Tutti i meccanismi di tipo noto usati da DataContractSerializer sono supportati anche nello stesso modo da DataContractJsonSerializer. Entrambi i serializzatori leggono lo stesso elemento di configurazione, <dataContractSerializer> in <system.runtime.serialization>, per individuare i tipi noti aggiunti tramite un file di configurazione.
Raccolte assegnate all'oggetto
Le raccolte assegnate a Object vengono serializzate come se fossero raccolte che implementano IEnumerable<T>: una matrice JSON con ogni voce con hint di tipo se si tratta di un tipo complesso. Ad esempio, un List<T> di tipo Shape assegnato a Object ha un aspetto come il seguente.
[{"__type":"Shape:#MyApp.Shapes","x":50,"y":70},
{"__type":"Shape:#MyApp.Shapes","x":58,"y":73},
{"__type":"Shape:#MyApp.Shapes","x":41,"y":32}]
Quando viene deserializzato di nuovo in Object:
Shapedeve trovarsi nell'elenco Tipi noti. La presenza di List<T> di tipoShapenei tipi conosciuti non ha alcun effetto. Nota che non è necessario aggiungereShapeai tipi noti in questo caso durante la serializzazione - questa operazione viene eseguita automaticamente.La raccolta viene deserializzata come Array di tipo Object, che contiene istanze
Shape.
Raccolte derivate assegnate alle raccolte di base
Quando una raccolta derivata viene assegnata a una raccolta di base, la raccolta viene in genere serializzata come se fosse una raccolta del tipo di base. Tuttavia, se il tipo di elemento della raccolta derivata non può essere assegnato al tipo di elemento della raccolta di base, viene generata un'eccezione.
Suggerimenti di tipo e dizionari
Quando un dizionario viene assegnato a un Objectoggetto, ogni voce Chiave e Valore nel dizionario viene trattata come se fosse assegnata a Object e riceve un indice di tipo.
Quando si serializzano i tipi di dizionario, l'oggetto JSON che contiene i membri "Key" e "Value" non è interessato dall'impostazione alwaysEmitTypeInformation e contiene solo un hint di tipo quando le regole di raccolta precedenti lo richiedono.
Nomi di chiave JSON validi
Il serializzatore XML codifica i nomi di chiave che non sono nomi XML validi. Ad esempio, un membro dati con il nome "123" avrà un nome codificato, ad esempio "_x0031__x0032__x0033_" perché "123" è un nome di elemento XML non valido (inizia con una cifra). Una situazione simile può verificarsi con alcuni set di caratteri internazionali non validi nei nomi XML. Per una spiegazione di questo effetto di XML nell'elaborazione JSON, vedere Mapping tra JSON e XML.