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.
I lettori e i writer prodotti da JsonReaderWriterFactory forniscono una API XML sul contenuto JSON (JavaScript Object Notation). JSON codifica i dati utilizzando un sottoinsieme dei valori letterali di oggetto di JavaScript. I lettori e i writer prodotti da questa factory sono utilizzati anche quando le applicazioni Windows Communication Foundation (WCF) inviano o ricevono contenuto JSON utilizzando WebMessageEncodingBindingElement o WebHttpBinding.
In caso di inizializzazione con contenuto JSON, il lettore JSON si comporta nello stesso modo di un lettore XML testuale su un'istanza di XML. Il writer JSON, in presenza di una sequenza di chiamate prodotte da una certa istanza XML su un lettore XML testuale, scrive il contenuto JSON. In questo argomento viene illustrato il mapping tra questa istanza di XML e il contenuto JSON, per l'utilizzo in scenari avanzati.
Internamente, JSON è rappresentato come un infoset XML quando elaborato da WCF. In genere non è necessario occuparsi di questa rappresentazione interna poiché il mapping è solo logico: JSON non viene normalmente convertito fisicamente in XML in memoria né in JSON da XML. Il mapping significa che le API XML sono utilizzate per accedere a contenuto JSON.
Quando WCF utilizza JSON, di norma DataContractJsonSerializer viene automaticamente inserito dal comportamento WebScriptEnablingBehavior o dal comportamento WebHttpBehavior quando appropriato. DataContractJsonSerializer è in grado di comprendere il mapping tra JSON e l'infoset XML e si comporta come se stesse interagendo direttamente con JSON. È possibile utilizzare DataContractJsonSerializer con qualsiasi lettore o scrittore XML, a condizione che l'XML sia conforme al mapping seguente.
Negli scenari avanzati, può rendersi necessario accedere direttamente al mapping seguente. Questi scenari si verificano quando si desidera serializzare e deserializzare JSON in modalità personalizzate, senza basarsi su DataContractJsonSerializero quando si interagisce direttamente con il tipo Message per messaggi che contengono JSON. Il mapping JSON-XML è utilizzato anche per la registrazione dei messaggi. Quando si utilizza la funzionalità di registrazione dei messaggi in WCF, i messaggi JSON vengono registrati come XML in conformità con il mapping descritto nella prossima sezione.
Per chiarire il concetto di mapping, l'esempio seguente fa riferimento a un documento JSON.
{"product":"pencil","price":12}
Per leggere il documento JSON tramite uno dei lettori indicato in precedenza, utilizzare la stessa sequenza di chiamate a XmlDictionaryReader utilizzata per leggere il documento XML seguente.
<root type="object">
<product type="string">pencil</product>
<price type="number">12</price>
</root>
Inoltre, se il messaggio JSON nell'esempio venisse ricevuto da WCF e registrato, si vedrebbe il frammento XML nel log precedente.
Mapping tra JSON e l'InfoSet XML
Formalmente, il mapping è tra JSON come descritto in RFC 4627 (eccetto per alcune restrizioni alleggerite e altre aggiunte) e l'InfoSet XML (e non XML testuale) come descritto in Set di informazioni XML. Vedi questo argomento per la definizione di elementi informativi e dei campi tra [parentesi quadre].
Un documento JSON vuoto corrisponde a un documento XML vuoto e un documento XML vuoto corrisponde a un documento JSON vuoto. Nel mapping da XML a JSON, non sono consentiti spazi vuoti precedenti e successivi rispetto al contenuto del documento.
Il mapping viene definito tra un DII (Document Information Item) o un EII (Element Information Item) e JSON. La proprietà [elemento del documento] del DII, o EII, è chiamata elemento radice JSON. Si noti che in questo mapping non sono supportati frammenti di documento (XML con più elementi radice).
Esempio: il documento seguente.
<?xml version="1.0"?>
<root type="number">42</root>
E l'elemento seguente:
<root type="number">42</root>
Entrambi hanno una mappatura a JSON. In entrambi i casi, l'elemento <root> è l'elemento JSON radice.
Nel caso di un DII, inoltre, è necessario prendere in considerazione gli elementi seguenti:
Alcuni elementi nell'elenco [figli] non devono essere presenti. Non fare affidamento su tale situazione in caso di lettura di XML mappato da JSON.
L'elenco [figli] non contiene voci di informazioni di commento.
L'elenco [figli] non contiene elementi informativi DTD.
L'elenco [figli] non contiene voci delle informazioni personali (PI) (la dichiarazione
<?xml…>non è considerata un elemento di informazione PI)L'insieme di notazioni è vuoto.
Il set [entità non analizzate] è vuoto.
Esempio: nel documento seguente non è contenuto alcun mapping a JSON perché [figli] contiene una PI e un commento.
<?xml version="1.0"?>
<!--comment--><?pi?>
<root type="number">42</root>
L'EII per l'Elemento JSON radice ha le caratteristiche seguenti:
[nome locale] ha il valore "root".
[nome dello spazio dei nomi] non ha valore.
[prefisso] non ha valore.
[figli] possono contenere EII (che rappresentano elementi interni come descritto più avanti) o CII (Elementi Informativi di Carattere come descritto più avanti) o nessuno dei due, ma non entrambi.
[attributi] possono contenere i seguenti elementi informativi facoltativi sugli attributi (AII)
L'attributo di tipo JSON ("type") come descritto più avanti. Questo attributo è utilizzato per mantenere il tipo JSON (stringa, numero, booleano, oggetto, matrice o null) nell'XML di cui è stato eseguito il mapping.
L'attributo del nome del contratto dati ("__type") come descritto dettagliatamente più avanti. Questo attributo può essere presente solo se è presente anche l'attributo del tipo JSON e il suo [valore normalizzato] è "object". Questo attributo è utilizzato da
DataContractJsonSerializerper mantenere informazioni sul tipo di contratto dati , ad esempio, nei casi polimorfici in cui viene serializzato un tipo derivato ed è previsto un tipo di base. Se non si utilizzaDataContractJsonSerializer, nella maggior parte dei casi questo attributo viene ignorato.[namespace in ambito] contiene il binding di "xml" a
http://www.w3.org/XML/1998/namespacecome imposto dalla specifica dell'infoset.[figli], [attributi] e [spazi dei nomi nell'ambito] non devono avere altri elementi tranne quelli specificati in precedenza e [attributi dello spazio dei nomi] non deve avere membri, ma non fare affidamento su questa situazione in caso di lettura di XML mappato da JSON.
Esempio: Nel documento seguente non c'è alcun mapping a JSON perché gli [attributi del namespace] non sono vuoti.
<?xml version="1.0"?>
<root xmlns:a="myattributevalue">42</root>
L'AII per l'attributo del tipo JSON ha le caratteristiche seguenti:
- [nome dello spazio dei nomi] non ha valore.
- [prefisso] non ha valore.
- [nome locale] è "tipo".
- [valore normalizzato] è uno dei possibili valori del tipo descritto nella sezione seguente.
- [specificato] è
true. - [tipo attributo] non ha valore.
- [riferimenti] non ha valore.
L'AII per l'attributo del nome del contratto dati ha le caratteristiche seguenti:
- [nome dello spazio dei nomi] non ha valore.
- [prefisso] non ha valore.
- [nome locale] è "__type (due trattini di sottolineatura seguiti da "type").
- [valore normalizzato] è qualsiasi stringa Unicode valida, il mapping di questa stringa a JSON viene descritto nella sezione seguente.
- [specificato] è
true. - [tipo attributo] non ha valore.
- [riferimenti] non ha valore.
Gli elementi interni contenuti all'interno dell'Elemento JSON radice o altri elementi interni hanno le caratteristiche seguenti:
- [nome locale] può avere qualsiasi valore, come descritto più avanti.
- [nome dello spazio dei nomi], [prefisso], [figli], [attributi], [attributi dello spazio dei nomi] e [spazi dei nomi nell'ambito] sono soggetti alle stesse regole dell'Elemento JSON Radicale.
Sia negli elementi JSON radice che negli elementi interni, l'attributo del tipo JSON definisce il mapping a JSON, i [figli] possibili e la loro rispettiva interpretazione. Il [valore normalizzato] dell'attributo prevede la distinzione tra maiuscole e minuscole, deve essere in lettere minuscole e non può contenere spazio vuoto.
| [valore normalizzato] dell'AII dell'attributo di tipo JSON | I [figli] consentiti dell'EII corrispondente | Mapping a JSON |
|---|---|---|
string (o assenza dell'AII del tipo JSON)string e l'assenza del tipo JSON AII sono equivalenti e rendono string il predefinito.Pertanto, <root> string1</root> viene mappato su JSON string "string1". |
0 o più CII | Un string oggetto JSON (JSON RFC, sezione 2.5). Ogni char è un carattere che corrisponde al [character code] di CII. Se non sono presenti CII, esegue il mapping a una string JSON vuota.Esempio: l'elemento seguente viene mappato a un frammento JSON: <root type="string">42</root>Il frammento JSON è "42". Nel mapping da XML a JSON, i caratteri che devono essere sottoposti a escape sono mappati a caratteri codificati, tutti gli altri sono mappati a caratteri non codificati. Il carattere "/" è speciale – viene preceduto da un carattere di escape anche se non è necessario (scritto come "\/"). Esempio: l'elemento seguente viene mappato a un frammento JSON. <root type="string">the "da/ta"</root>Il frammento JSON è "\"da\/ta\"". Nel mapping da JSON a XML, qualsiasi carattere con o senza escape viene mappato correttamente al codice carattere corrispondente. Esempio: il frammento JSON "\u0041BC" viene mappato all'elemento XML seguente. <root type="string">ABC</root>La stringa può essere racchiusa tra spazi bianchi ('white space' nella sezione 2 del JSON RFC) che non vengono trasformati in XML. Esempio: il frammento JSON "ABC", (sono presenti spazi prima delle doppie virgolette di apertura) viene mappato all'elemento XML seguente. <root type="string">ABC</root>Qualsiasi spazio bianco nel codice XML viene mappato al corrispondente spazio bianco in JSON. Esempio: l'elemento XML seguente viene mappato a un frammento JSON. <root type="string"> A BC </root>Il frammento JSON è " A BC ". |
number |
1 o più CII | Un number JSON (JSON RFC, sezione 2.4), eventualmente racchiuso da spazio vuoto. Ogni carattere nella combinazione numero/spazio è un carattere che corrisponde al [codice carattere] secondo il CII.Esempio: l'elemento seguente viene mappato a un frammento JSON. <root type="number"> 42</root>Il frammento JSON è 42 Lo spazio viene mantenuto. |
boolean |
4 o 5 CII (il che corrisponde a true o false), possibilmente circondati da spazio vuoto aggiuntivo. |
Una sequenza di CII che corrisponde alla stringa "true" viene mappata al valore letterale true e la sequenza di CII che corrisponde alla stringa "false" viene mappata al valore letterale false. Lo spazio circostante viene mantenuto.Esempio: l'elemento seguente viene mappato a un frammento JSON. <root type="boolean"> false</root>Il frammento JSON è false. |
null |
Nessuno permesso. | Valore letterale null. Nel mapping da JSON a XML, null può essere racchiuso tra spazi vuoti ('ws' nella sezione 2) di cui non viene eseguito il mapping al codice XML.Esempio: l'elemento seguente viene mappato a un frammento JSON. <root type="null"/>o <root type="null"></root>: In entrambi i casi il frammento JSON è Null. |
object |
0 o più EII. |
begin-object (graffa aperta) come nella sezione 2.2 del RFC JSON, seguito da un record del membro per ogni EII come descritto più avanti. Se esiste più di un EII, sono presenti separatori di valore (virgole) tra i record dei membri. Tutto è seguito da un fine oggetto (parentesi graffa chiusa).Esempio: l'elemento seguente viene mappato al frammento JSON. <root type="object"><type1 type="string">aaa\</type1><type2 type="string">bbb\</type2></root >Il frammento JSON è {"type1":"aaa","type2":"bbb"}.Se l'attributo di tipo di contratto dati è presente nel mapping da XML a JSON, viene inserito un record membro aggiuntivo all'inizio. Il suo nome è il [nome locale] dell'attributo tipo di contratto dati ("__type") e il suo valore è il [valore normalizzato] dell'attributo. Per contro, nel mapping da JSON a XML, se il nome del primo record del membro è il [nome locale] dell'attributo tipo di contratto dati (ovvero, "__type"), nell'XML sottoposto a mapping è presente un attributo tipo di contratto dati corrispondente, ma non è presente un EII corrispondente. Si noti che, perché questo mapping speciale si applichi, il record del membro deve essere per primo nell'oggetto JSON. Ciò si discosta dall'elaborazione JSON abituale, in cui l'ordine dei record dei membri non è importante. Esempio: Il frammento JSON seguente viene convertito in XML. {"__type":"Person","name":"John"}L'XML è il codice seguente. <root type="object" __type="Person"> <name type="string">John</name> </root>Si noti che __type AII è presente, ma __type EII non è presente. Se, tuttavia, l'ordine in JSON è invertito come illustrato nell'esempio seguente. {"name":"John","\_\_type":"Person"}Viene illustrato l'XML corrispondente. <root type="object"> <name type="string">John</name> <__type type="string">Person</__type> </root>Ovvero, __type cessa di avere un significato speciale e viene mappato a un EII come d'abitudine, non ad AII. Le regole sull'utilizzo o meno di caratteri di escape per il [valore normalizzato] di AII quando mappato a un valore JSON sono identiche a quelle per le stringhe JSON, come specificato nella riga "string" di questa tabella. Esempio: <root type="object" __type="\abc" />il seguente JSON può essere mappato all'esempio precedente. {"__type":"\\abc"}In un mapping da XML a JSON, il [nome locale] del primo EII non deve essere "__type". La spaziatura ( ws) non viene mai creata nella mappatura da XML a JSON per gli oggetti e viene ignorata nella mappatura da JSON a XML.Esempio: il seguente frammento JSON corrisponde a un elemento XML. { "ccc" : "aaa", "ddd" :"bbb"}Nel codice seguente viene illustrato l'elemento XML. <root type="object"> <ccc type="string">aaa</ccc> <ddd type="string">bbb</bar> </root > |
| elenco | 0 o più EII | Un inizio di matrice (parentesi quadra aperta) come nella sezione 2.3 di JSON RFC, seguita da un record della matrice per ogni EII come descritto più avanti. Se esiste più di un EII, sono presenti separatori di valore (virgole) tra i record delle matrici. Il tutto, è seguito da un fine matrice. Esempio: l'elemento XML seguente viene mappato a un frammento JSON. <root type="array"/> <item type="string">aaa</item> <item type="string">bbb</item> </root >Il frammento JSON è ["aaa","bbb"]Lo spazio bianco ( ws) non viene mai generato nel mapping da XML a JSON per gli array e viene ignorato nel mapping da JSON a XML.Esempio: un frammento JSON. ["aaa", "bbb"]L'elemento XML a cui è associato. <root type="array"/> <item type="string">aaa</item> <item type="string">bbb</item> </root > |
I record dei membri funzionano nei modi seguenti:
- Il [nome locale] dell'elemento interno viene mappato alla parte
stringdimember, come definito nella sezione 2.2 delle specifiche JSON RFC.
Esempio: l'elemento seguente viene mappato a un frammento JSON.
<root type="object">
<myLocalName type="string">aaa</myLocalName>
</root>
Viene visualizzato il frammento JSON seguente.
{"myLocalName":"aaa"}
Nel mapping da XML a JSON, i caratteri che devono essere preceduti dal carattere di escape in JSON sono preceduti dal carattere di escape, gli altri no. Il carattere "/",viene preceduto da un carattere di escape anche se ciò non è necessario (non richiede il carattere di escape nel mapping da JSON a XML). Ciò è necessario per supportare il formato ASP.NET AJAX per i dati
DateTimein JSON.Nel mapping da JSON a XML, vengono presi tutti i caratteri (compresi quelli senza carattere di escape, se necessario) per formare una
stringche produce un [nome locale].Gli elementi interni [figli] sono mappati al valore nella sezione 2.2, secondo quanto fatto per
JSON Type Attributecome perRoot JSON Element. Sono consentiti più livelli di annidamento di EII (incluso l'annidamento all'interno di matrici).
Esempio: l'elemento seguente viene mappato a un frammento JSON.
<root type="object">
<myLocalName1 type="string">myValue1</myLocalName1>
<myLocalName2 type="number">2</myLocalName2>
<myLocalName3 type="object">
<myNestedName1 type="boolean">true</myNestedName1>
<myNestedName2 type="null"/>
</myLocalName3>
</root >
Viene mappato al frammento JSON seguente.
{"myLocalName1":"myValue1","myLocalName2":2,"myLocalName3":{"myNestedName1":true,"myNestedName2":null}}
Nota
Nel mapping precedente non esiste alcun passaggio di codifica XML. Pertanto, WCF supporta solo documenti JSON in cui tutti i caratteri nei nomi delle chiavi siano caratteri validi nei nomi degli elementi XML. Il documento JSON {"<":"a"}, ad esempio, non è supportato perché < non è un nome valido per un elemento XML.
La situazione inversa (caratteri validi in XML ma non in JSON) non causa alcun problema perché la mappatura precedente permette il passaggio di escape/non escape dei caratteri in JSON.
I record di matrici funzionano come segue:
Il [nome locale] dell'elemento interno è "item".
I [figli] dell'elemento interno vengono mappati al valore nella sezione 2.3, secondo l'Attributo Tipo di JSON, come avviene per l'Elemento JSON Radice. Sono consentiti più livelli di annidamento di EII (incluso l'annidamento all'interno di oggetti).
Esempio: l'elemento seguente viene mappato a un frammento JSON.
<root type="array">
<item type="string">myValue1</item>
<item type="number">2</item>
<item type="array">
<item type="boolean">true</item>
<item type="null"/></item>
</root>
Quello che segue è il frammento JSON.
["myValue1",2,[true,null]]