Serializzazione JSON autonoma
JSON (JavaScript Object Notation) è un formato dati progettato specificatamente per essere utilizzato dal codice JavaScript in esecuzione su pagine Web all'interno del browser. JSON è il formato dati predefinito utilizzato dai servizi ASP.NET AJAX creati in Windows Communication Foundation (WCF).
Questo formato può essere utilizzato durante la creazione di servizi AJAX senza effettuare l'integrazione con ASP.NET: in questo caso, il formato predefinito è XML, ma è anche possibile scegliere JSON.
Infine, se è necessario disporre del supporto JSON ma non si sta creando un servizio AJAX, DataContractJsonSerializer consente di serializzare direttamente oggetti di tipo .NET in dati JSON e di deserializzare tali dati in istanze di tipi .NET. Per una descrizione della procedura, vedere Procedura: serializzare e deserializzare dati JSON.
Tranne rare eccezioni, quando si lavora con JSON sono supportati gli stessi tipi .NET supportati da DataContractSerializer. Per un elenco dei tipi supportati, vedere Tipi supportati dal serializzatore dei contratti dati. L'elenco include la maggior parte dei tipi primitivi e dei tipi di matrice e di insieme, nonché i tipi complessi che utilizzano DataContractAttribute e DataMemberAttribute.
Mapping di tipi .NET a tipi JSON
Nella tabella seguente viene illustrata la corrispondenza tra i tipi .NET e i tipi JSON/Javascript quando questi sono mappati mediante le procedure di serializzazione e deserializzazione.
Tipi .NET | JSON/Javascript | Note |
---|---|---|
Numero |
I valori speciali quali Double.NaN, Double.PositiveInfinity e Double.NegativeInfinity non sono supportati e determinano un tipo JSON non valido. |
|
Numero |
Vedere "Enumerazioni e JSON" più avanti in questo argomento. |
|
Booleano |
-- |
|
Stringa |
-- |
|
Stringa |
Il formato di questi tipi in JSON è lo stesso che in XML (fondamentalmente TimeSpan nel formato durata ISO 8601, GUID nel formato "12345678-ABCD-ABCD-ABCD-1234567890AB" e URI nella sua forma di stringa naturale, ad esempio "http://www.example.com") Per informazioni dettagliate, vedere Riferimento allo schema del contratto dati. |
|
Stringa |
Il formato è "nome:spazio dei nomi" (tutto ciò che si trova prima del primo segno di due punti è il nome). Il nome o lo spazio dei nomi potrebbero non essere presenti. Se non esiste alcuno spazio dei nomi, è possibile omettere anche i due punti. |
|
Matrice di numeri |
Ogni numero rappresenta il valore di un byte. |
|
DateTime o String |
Vedere Date/Ore e JSON più avanti in questo argomento. |
|
Tipo complesso |
Vedere Date/Ore e JSON più avanti in questo argomento. |
|
Tipi XML e ADO.NET (XmlElement,. DataSet). |
Stringa |
Vedere la sezione relativa ai tipi XML e a JSON in questo argomento. |
Tipo complesso vuoto |
-- |
|
Insiemi, dizionari e matrici |
Matrice |
Vedere la sezione relativa agli insiemi, ai dizionari e alle matrici in questo argomento. |
Tipi complessi (con applicazione dell'attributo DataContractAttribute o SerializableAttribute) |
Tipo complesso |
I membri dati diventano membri del tipo complesso Javascript. |
Tipi complessi che implementano l'interfaccia ISerializable |
Tipo complesso |
Come altri tipi complessi ma alcuni tipi ISerializable non sono supportati. Vedere la parte relativa al supporto per ISerializable nella sezione Informazioni avanzate di questo argomento. |
Valore Null per qualsiasi tipo. |
Null |
Anche i tipi nullable sono supportati e mappati a JSON, così come i tipi non-nullable. |
Enumerazioni e JSON
In JSON, i valori membro dell'enumerazione vengono trattati come numeri, a differenza di quanto accade nei contratti dati, nei quali questi vengono inclusi come nomi dei membri. Per ulteriori informazioni sul trattamento dei contratti dati, vedereTipi di enumerazioni nei contratti dati
- Con
public enum Color {red, green, blue, yellow, pink}
, ad esempio, la serializzazione diyellow
produce il numero 3 e non la stringa "yellow". - Tutti i membri enum sono serializzabili. Gli attributi EnumMemberAttribute e NonSerializedAttribute, se utilizzati, vengono ignorati.
- È possibile deserializzare un valore enum non esistente: ad esempio, il valore 87 può essere deserializzato nell'enumerazione Color precedente anche se non è stato definito un nome di colore corrispondente.
- Un enum di flag non è speciale e viene trattato come qualsiasi altro enum.
Date/Ore e JSON
Il formato JSON non supporta direttamente le date e le ore. Tuttavia, queste vengono comunemente utilizzate e in ASP.NET AJAX è disponibile un supporto speciale per tali tipi. Quando si utilizzano i proxy ASP.NET AJAX, il tipo DateTime in .NET corrisponde perfettamente al tipo DateTime in JavaScript.
Quando non si utilizza ASP.NET, un tipo DateTime viene rappresentato in JSON come una stringa con formato speciale descritta nella sezione Informazioni avanzate di questo argomento.
DateTimeOffset è rappresentato in JSON come tipo complesso: {"DateTime":dateTime,"OffsetMinutes":offsetMinutes}. Il membro offsetMinutes rappresenta la differenza tra l'ora locale e l'ora di Greenwich (GMT), nota anche come ora UTC (Coordinated Universal Time), associata all'ubicazione dell'evento di interesse. Il membro dateTime rappresenta il momento in cui si è verificato l'evento di interesse (anche in questo caso diventa DateTime in JavaScript se è in uso ASP.NET AJAX oppure una stringa in caso contrario). Al momento della serializzazione, il membro dateTime viene sempre serializzato in GMT. Pertanto, nella descrizione dell'ora 03.00 di New York, il membro dateTime conterrà il componente temporale 08.00, mentre i offsetMinutes saranno 300 (meno 300 minuti o 5 ore rispetto a GMT).
Nota
Quando gli oggetti DateTime e DateTimeOffset vengono serializzati in JSON, conservano solo le informazioni con una precisione espressa in millisecondi. I sottomultipli di millisecondi (micro/nanosecondi) vanno persi durante la serializzazione.
Tipi XML e JSON
I tipi XML diventano stringhe JSON.
- Se, ad esempio, un membro dati "q" di tipo XElement contiene <abc/>, la stringa JSON è {"q":"<abc/>"}.
- Alcune regole speciali determinano la modalità di incapsulamento dell'XML. Per ulteriori informazioni vedere la sezione Informazioni avanzate più avanti in questo argomento.
- Se si sta utilizzando ASP.NET AJAX e, al posto di stringhe in Javascript, si desidera utilizzare DOM XML, impostare la proprietà ResponseFormat su XML in WebGetAttribute o la proprietà ResponseFormat su XML in WebInvokeAttribute.
Insiemi, dizionari e matrici
In JSON, tutti gli insiemi, i dizionari e le matrici vengono rappresentati come matrici.
- Qualsiasi personalizzazione che utilizza CollectionDataContractAttribute viene ignorata nella rappresentazione JSON.
- I dizionari non sono un modo per lavorare direttamente con JSON. In WCF, Dictionary<string,object> potrebbe non essere supportato come quando si lavora con altre tecnologie JSON. Se, ad esempio, "abc" viene mappato a "xyz" e "def" viene mappato a 42 in un dizionario, la rappresentazione JSON non può essere {"abc":"xyz","def":42}, ma sarà [{"Key":"abc","Value":"xyz"},{"Key":"def","Value":42}].
- Se si desidera lavorare direttamente con JSON (accedendo alle chiavi e ai valori in modo dinamico, senza definire preliminarmente un contratto rigido), sono disponibili diverse opzioni:
- Utilizzo dell'esempio Weakly-typed JSON Serialization (AJAX).
- Utilizzo dell'interfaccia ISerializable e dei costruttori di deserializzazione. Questi due meccanismi consentono di accedere alle coppie chiave/valore di JSON rispettivamente durante la serializzazione e la deserializzazione, ma non funzionano in scenari di trust parziale.
- Utilizzo di Mapping tra JSON e XML al posto di un serializzatore.
- Nel contesto della serializzazione, Polimorfismo si riferisce alla capacità di serializzare un tipo derivato nei casi in cui è previsto un tipo di base. Quando vengono utilizzati insiemi in modo polimorfico (ad esempio quando si assegna un insieme a un elemento Object), esistono regole speciali specifiche per JSON. Questo argomento viene trattato in modo approfondito nella sezione Informazioni avanzate più avanti in questo argomento.
Ulteriori informazioni
Ordine dei membri dati
L'ordine dei membri dati non è importante quando si utilizza JSON. In particolare, anche se è impostato Order, è comunque possibile deserializzare i dati JSON in qualsiasi ordine.
Tipi JSON
Il tipo JSON non deve necessariamente corrispondere alla tabella precedente durante la deserializzazione. Ad esempio, un Int normalmente viene mappato a un numero JSON, ma può anche essere deserializzato da una stringa JSON, se questa contiene un numero valido. Ovvero, sia {"q": 42} che {"q": "42"} sono validi se esiste un membro dati Int chiamato "q".
Polimorfismo
Per serializzazione polimorfa si intende la capacità di serializzare un tipo derivato nei casi in cui è previsto un tipo di base. Tale operazione è supportata per la serializzazione JSON mediante WCF, allo stesso modo in cui è supportata la serializzazione XML. Ad esempio, è possibile serializzare MyDerivedType quando è previsto MyBaseType, oppure serializzare Int quando è previsto un Object.
Le informazioni sul tipo potrebbero andare perdute durante la deserializzazione di un tipo derivato nei casi in cui è previsto un tipo di base, a meno che non si stia deserializzando un tipo complesso. Se, ad esempio, viene serializzato Uri quando è previsto Object, il risultato sarà una stringa JSON. Se la stringa viene deserializzata di nuovo in Object viene restituito un elemento String .NET. Il deserializzatore non è a conoscenza del fatto che la stringa era inizialmente di tipo Uri. In genere, quando è previsto un elemento Object, tutte le stringhe JSON vengono deserializzate come stringhe .NET, mentre tutte le matrici JSON utilizzate per serializzare i dizionari, le matrici e gli insiemi .NET vengono deserializzati come elementi Array .NET di tipo Object, indipendentemente da quale fosse il tipo originario. Un booleano JSON viene mappato a un elemento Boolean .NET. Tuttavia, quando è previsto un elemento Object, i numeri JSON vengono deserializzati automaticamente come Int32, Decimal o Double .NET, a seconda del tipo più appropriato.
In caso di deserializzazione in un tipo di interfaccia, DataContractJsonSerializer deserializza come se il tipo dichiarato fosse un oggetto.
Quando si lavora con i propri tipi derivati e di base, è generalmente necessario utilizzare KnownTypeAttribute, ServiceKnownTypeAttribute o un meccanismo equivalente. Ad esempio, se il valore restituito di un'operazione è Animal e questa effettivamente restituisce un'istanza di Cat (derivata da Animal), è necessario applicare KnownTypeAttribute al tipo Animal oppure applicare ServiceKnownTypeAttribute all'operazione, specificando il tipo Cat in questi attributi. Per ulteriori informazioni, vedere Tipi conosciuti di contratto dati.
Per dettagli sul funzionamento della serializzazione polimorfica e una discussione su alcune delle restrizioni che è necessario rispettare durante il suo utilizzo, vedere la sezione Informazioni avanzate più avanti in questo argomento.
Controllo delle versioni
Le funzionalità di controllo delle versioni dei contratti dati, inclusa l'interfaccia IExtensibleDataObject sono pienamente supportate in JSON. Inoltre, nella maggior parte di casi è possibile deserializzare un tipo in un formato (ad esempio XML) e quindi serializzarlo in un altro formato (ad esempio JSON), conservando comunque i dati in un elemento IExtensibleDataObject. Per ulteriori informazioni, vedere Contratti dati compatibili con versioni successive. Poiché JSON non è ordinato, le informazioni relative all'ordine andranno perse. Inoltre, JSON non supporta più coppie chiave/valore con lo stesso nome di chiave. Infine, tutte le operazioni su IExtensibleDataObject sono intrinsecamente polimorfiche. ovvero i relativi tipi derivati sono assegnati a Object, il tipo di base per tutti i tipi.
JSON negli URL
Quando si utilizzano endpoint ASP.NET AJAX con il verbo HTTP GET (utilizzando l'attributo WebGetAttribute), nell'URL della richiesta vengono visualizzati i parametri in arrivo anziché il corpo del messaggio. JSON è supportato anche nell'URL della richiesta, pertanto se è presente un'operazione che prende un Int chiamato "number" e un tipo complesso di Person chiamato "p", l'URL potrebbe assomigliare all'URL seguente:
http://example.com/myservice.svc/MyOperation?number=7&p={"name":"John","age":42}
Se si utilizzano un controllo Script Manager ASP.NET AJAX e un proxy per chiamare il servizio, l'URL viene automaticamente generato dal proxy e non viene visualizzato. Non è possibile utilizzare JSON in URL su endpoint non ASP.NET AJAX.
Informazioni avanzate
Supporto per 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 tale che gli aspetti specifici della serializzazione di JSON ne impediscono la corretta deserializzazione.
- Con ISerializable, il tipo dei singoli membri dati non è noto in anticipo. Ciò causa una situazione polimorfica simile alla deserializzazione di tipi in un oggetto. Come già sottolineato, ciò potrebbe causare la perdita di informazioni sul tipo in JSON. Ad esempio, un tipo che serializza un enum nella sua implementazione di ISerializable e tenta di effettuare la deserializzazione direttamente in un elemento enum (senza cast adeguati) non riesce poiché un enum viene serializzato utilizzando un numero in JSON mentre i numeri JSON eseguono la deserializzazione in tipi numerici incorporati .NET (Int32 .NET, Decimal o Double). Pertanto, l'informazione che il numero utilizzato era in precedenza un valore enum viene persa.
- Un tipo ISerializable che dipende da un particolare ordine di deserializzazione nel relativo costruttore di deserializzazione potrebbe non riuscire a deserializzare alcuni dati JSON poiché la maggior parte dei serializzatori JSON non garantisce un ordine specifico.
Tipi Factory
Mentre l'interfaccia IObjectReference è generalmente supportata in JSON, i tipi che richiedono la funzionalità "tipo factory" (che restituisce un'istanza di un tipo differente da GetRealObject rispetto al tipo che implementa l'interfaccia) non sono supportati.
Formato di trasmissione DateTime
I valori DateTime vengono visualizzati come stringhe JSON nella forma "/Date(700000+0500)/", dove il primo numero (700000 nell'esempio fornito) è il numero di millisecondi nel fuso orario di GMT, orario solare (non ora legale) dalla mezzanotte del 1° gennaio 1970. Il numero può essere negativo per indicare momenti precedenti. La parte rappresentata da "+0500" nell'esempio è facoltativa e indica che l'orario è di tipo Local, ossia dovrebbe essere convertito nel fuso orario locale durante la deserializzazione. Se assente, l'orario viene deserializzato come Utc. Il numero effettivo ("0500" in questo esempio) e il relative segno (+ o -) vengono ignorati.
Durante la serializzazione di DateTime, gli orari Local e Unspecified sono scritti con uno scostamento, mentre Utc viene scritto senza alcuno scostamento.
Il codice JavaScript del client ASP.NET AJAX converte automaticamente tali stringhe in istanze DateTime JavaScript. Verranno convertite anche tutte le altre stringhe che presentano una forma simile e non sono di tipo DateTime in .NET.
La conversione avviene solo se viene utilizzato il carattere di escape per "/" (ossia JSON appare "\/Date(700000+0500)\/"); per questa ragione, il codificatore JSON di WCF (attivato mediante WebHttpBinding) utilizza sempre il carattere di escape per "/".
XML nelle stringhe JSON
XmlElement
XmlElement viene serializzato così com'è, senza incapsulamento. Ad esempio, il membro dati "x" di tipo XmlElement contenente <abc/> viene rappresentato nel modo seguente.
{"x":"<abc/>"}
Matrici di XmlNode
Gli oggetti Array di tipo XmlNode vengono incapsulati in un elemento denominato ArrayOfXmlNode nello spazio dei nomi del contratto dati standard per il tipo. Se "x" è una matrice contenente il nodo attributo "N" nello spazio dei nomi "ns" che contiene "value" e un nodo elemento vuoto "M", la rappresentazione risulterà quella 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 della matrice XmlNode (prima di altri elementi) non sono supportati.
Tipi IXmlSerializable inclusi XElement e DataSet
I tipi ISerializable si suddividono in tipi contenuto, tipi DataSet e tipi elemento. Per le definizioni di questi tipi, vedere Tipi XML e ADO.NET nei contratti dati.
I tipi contenuto e DataSet vengono serializzati in modo simile agli oggetti Array di XmlNode descritti nella sezione precedente. Tali tipi vengono incapsulati in un elemento il cui nome e spazio dei nomi corrisponde al nome e allo spazio dei nomi del contratto dati del tipo in questione.
I tipi elemento come XElement vengono serializzati così come sono, in modo analogo a XmlElement, già descritto in questo argomento.
Polimorfismo
Mantenimento delle informazioni sui tipi
Come già illustrato il polimorfismo è supportato in JSON. con alcune restrizioni. Javascript è un linguaggio con tipizzazione debole e l'identità del tipo non rappresenta solitamente un problema. Tuttavia, quando si utilizza JSON per le comunicazioni tra un sistema fortemente tipizzato (.NET) e uno con tipizzazione debole (Javascript), è utile mantenere l'identità del tipo. Ad esempio, i tipi con nomi di contratto dati "Square" e "Circle" derivano da un tipo con nome di contratto dati "Shape". Se "Circle" viene inviato da .NET a Javascript e viene quindi restituito a un metodo .NET che prevede "Shape", è utile per .NET sapere che l'oggetto in questione è stato originariamente un "Circle"; in caso contrario, tutte le informazioni specifiche del tipo derivato (ad esempio il membro dati "radium" su "Circle") potrebbero andare perdute.
Per mantenere l'identità del tipo, durante la serializzazione di tipi complessi in JSON può essere aggiunto un suggerimento; il deserializzatore riconosce tale suggerimento e agisce di conseguenza. Il suggerimento relativo ai tipi è rappresentato da una coppia chiave/valore JSON dove il nome della chiave è "__type" (due caratteri di sottolineatura seguiti dalla parola "type"). Il valore è rappresentato da una stringa JSON con forma "DataContractName:DataContractNamespace" (tutto il testo che precede i due punti rappresenta il nome). Facendo riferimento all'esempio precedente, "cerchio" può essere serializzato nel modo seguente.
{"__type":"Circle:http://example.com/myNamespace","x":50,"y":70,"radius":10}
Il suggerimento relativo ai tipi è molto simile all'attributo xsi:type definito dallo standard delle istanze di schemi XML e utilizzato durante la serializzazione/deserializzazione dell'XML.
I membri dati denominati "__type" non sono consentiti a causa di un potenziale conflitto con il suggerimento relative al tipo.
Riduzione delle dimensioni del suggerimento relativo al tip006F
Per ridurre le dimensioni dei messaggi JSON, il prefisso dello spazio dei nomi del contratto dati predefinito () viene sostituito dal carattere "#". Per rendere reversibile questa sostituzione, viene utilizzata una regola di escape: se il primo carattere nello spazio dei nomi è "#" or "\", verrà aggiunto un carattere "\"). Pertanto, se "Circle" è un tipo nello spazio dei nomi .NET "MyApp.Shapes", il relativo spazio dei nomi del contratto dati sarà http://schemas.datacontract.org/2004/07/MyApp. Le forme e la rappresentazione JSON appaiono nel modo seguente.
{"__type":"Circle:#MyApp.Shapes","x":50,"y":70,"radius":10}
Sia i nomi troncati (#MyApp.Shapes) che quelli completi () vengono riconosciuti durante la deserializzazione.
Posizione del suggerimento relativo ai tipi negli oggetti JSON
Il suggerimento relativo ai tipi deve essere visualizzato innanzitutto nella rappresentazione JSON. Questo è il solo caso in cui l'ordine delle coppie chiave/valore è importante nell'elaborazione di JSON. Di seguito viene riportato un esempio di modalità non valida per specificare un suggerimento relativo ai tipi.
{"x":50,"y":70,"radius":10,"__type":"Circle:#MyApp.Shapes"}
Sia DataContractJsonSerializer utilizzato da WCF che le pagine del client ASP.NET AJAX inviano sempre il suggerimento relativo ai tipi per primo.
I suggerimenti relativi al tipo si applicano solo ai tipi complessi
Non è possibile inviare un suggerimento relativo ai tipi a tipi non complessi. Ad esempio, se il tipo restituito da un'operazione è Object ma viene restituito un Circle, la rappresentazione JSON può essere del tipo illustrato in precedenza e le informazioni sul tipo verranno mantenute. Tuttavia, se viene restituito l'URI, la rappresentazione JSON sarà una stringa e l'informazione che la stringa utilizzata per rappresentare l'URI viene persa. Ciò è valido non solo per i tipi primitivi ma anche per gli insiemi e le matrici.
Invio dei suggerimenti relativi al tipo
I suggerimenti relativi al tipo possono aumentare significativamente le dimensioni dei messaggi; un modo per limitare questa conseguenza è quello di utilizzare uno spazio dei nomi del contratto dati più breve, se possibile. Pertanto, le regole seguenti determinano quali suggerimenti relativi al tipo vengono inviati.
- Se si utilizza ASP.NET AJAX, laddove possibile i suggerimenti relativi al tipo vengono sempre inviati, anche se non esiste un'assegnazione di base/derivata (ad esempio, se un Circle è assegnato a un Circle). Ciò è necessario per abilitare completamente il processo di chiamata da un ambiente JSON con tipizzazione debole a un ambiente .NET fortemente tipizzato, senza un imprevista perdita di informazioni.
- Se si utilizzano i servizi ASP.NET AJAX senza integrazione ASP.NET, i suggerimenti relativi al tipo vengono inviati solamente se esiste un'assegnazione di base/derivata, ossia quando Circle viene assegnato a Shape o a Object, ma non a Circle. Ciò garantisce che vengano fornite le informazioni minime necessarie per l'implementazione corretta di un client Javascript, migliorando in tal modo le prestazioni, ma non offre alcuna protezione contro la perdita delle informazioni sui tipi nei client progettati in modo non corretto. Per impedire che si presenti tale problema sul client, evitare di utilizzare le assegnazioni di base/derivate sul server.
- Se si utilizza il tipo DataContractSerializer, il parametro di costruttore alwaysEmitTypeInformation consente di scegliere tra le due modalità precedenti, mentre l'impostazione predefinita è "false" (i suggerimenti sul tipo vengono inviati solo se richiesto).
Nomi di membro dati duplicati
Le informazioni sul tipo derivato sono incluse nello stesso oggetto JSON delle informazioni sul tipo di base, in qualsiasi ordine. Ad esempio, Shape può essere rappresentato nel modo seguente.
{"__type":"Shape:#MyApp.Shapes","x":50,"y":70}
Circle, invece, potrebbe essere rappresentato nel modo seguente.
{"__type":"Circle:#MyApp.Shapes","x":50, "radius":10,"y":70}
Se anche il tipo Shape di base contiene un membro dati denominato "radius", ciò potrebbe comportare una collisione sia durante la serializzazione (poiché gli oggetti JSON non possono contenere nomi di chiave ripetuti) che durante la deserializzazione (poiché non è chiaro se "radius" si riferisce a Shape.radius o a Circle.radius). Pertanto, mentre il concetto di "occultamento della proprietà" (i membri dati con lo stesso nome sulle classi di base e derivate) non viene generalmente consigliato nelle classi del contratto dati, non è assolutamente consentito nel caso di JSON.
Polimorfismo e tipi IXmlSerializable
In base alle normali regole sui contratti dati, i tipi IXmlSerializable possono non essere assegnati in modo polimorfico l'uno all'altro come di norma a condizione che siano soddisfatti i requisiti dei tipi conosciuti. Tuttavia, la serializzazione di un tipo IXmlSerializable al posto di Object causa la perdita di informazioni sul tipo poiché il risultato è una stringa JSON.
Polimorfismo e determinati tipi di interfaccia
Non è consentito serializzare un insieme di tipi o un tipo che implementa IXmlSerializable nei casi in cui è previsto un tipo non di insieme diverso da IXmlSerializable (ad eccezione di Object). Ad esempio, un'interfaccia personalizzata denominata IMyInterface e un tipo MyType che implementano IEnumerable di tipo int e IMyInterface. Non è consentito restituire MyType da un'operazione il cui tipo restituito è IMyInterface. Ciò è dovuto al fatto che MyType deve essere serializzato come matrice JSON e richiede un suggerimento relative al tipo; come illustrato in precedenza, però, non è possibile includere un suggerimento relativo ai tipi nelle matrici, ma solo nei tipi complessi.
Tipi conosciuti e configurazione
Tutti i meccanismi relativi ai tipi conosciuti utilizzati dall'elemento DataContractSerializer sono supportati anche da DataContractJsonSerializer. Entrambi i serializzatori leggono il medesimo elemento di configurazione, <dataContractSerializer> in <system.runtime.serialization>, per individuare i tipi conosciuti aggiunti tramite un file di configurazione.
Insiemi assegnati a un oggetto
Gli insiemi assegnati a un oggetto vengono serializzati se implementano IEnumerable: una matrice JSON le cui voci dispongono di un suggerimento relativo ai tipi, se si tratta di un tipo complesso. Ad esempio, un List di tipo Shape assegnato a Object appare nel modo 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}]
Se deserializzata di nuovo in Object:
- Shape deve essere presente nell'elenco dei tipi conosciuti. Se List di tipo Shape è presente tra i tipi conosciuti, non si produce alcun effetto. In questo caso, non è necessario aggiungere Shape ai tipi conosciuti durante la serializzazione, poiché l'operazione viene eseguita automaticamente.
- L'insieme viene deserializzato come un elemento Array di tipo Object contenente istanze di Shape.
Insiemi derivati assegnati a insiemi di base
Se un insieme derivato viene assegnato a un insieme di base, verrà generalmente serializzato come se si trattasse di un insieme di tipi di base. Tuttavia, se il tipo di elemento dell'insieme derivato non può essere assegnato al tipo di elemento dell'insieme di base, verrà generata un'eccezione.
Suggerimenti relativi al tipo e dizionari
Se un dizionario viene assegnato a un elemento Object, ciascuna voce Key e Value nel dizionario verrà trattata come se fosse assegnata a Object e ottiene un suggerimento relativo ai tipi.
Durante la serializzazione dei tipi di dizionario, l'oggetto JSON che contiene i membri "Key" e "Value" non è interessato dall'impostazione alwaysEmitTypeInformation e includerà un suggerimento relativo ai tipi solo se le regole dell'insieme precedente lo richiedono.
Nomi di chiave JSON validi
Il serializzatore XML codifica i nomi delle chiavi che non sono nomi XML validi. Ad esempio, il nome codificato di un membro dati con il nome "123" sarebbe "_x0031__x0032__x0033_", dal momento che "123" è un nome di elemento XML non valido (poiché inizia con un numero). Una situazione simile può presentarsi con alcuni set di caratteri internazioni non validi per i nomi XML. Per una spiegazione su questo effetto dell'XML sull'elaborazione JSON, vedere Mapping tra JSON e XML.