スタンドアロン JSON のシリアル化
JSON (JavaScript Object Notation) は、ブラウザ内の Web ページで実行される JavaScript コードで使用するために特別に設計されたデータ形式です。Windows Communication Foundation (WCF) で作成される ASP.NET AJAX サービスは、既定でこのデータ形式を使用します。
この形式は、ASP.NET と統合せずに AJAX サービスを作成する場合にも使用できます。この場合、XML が既定のデータ形式になりますが、JSON を選択することもできます。
JSON をサポートする必要はあっても AJAX サービスを作成する予定はない場合は、DataContractJsonSerializer を使用することで、.NET オブジェクトを JSON データに直接シリアル化したり、このようなデータを .NET 型のインスタンスに逆シリアル化したりできます。この手順の詳細については、「方法 : JSON データをシリアル化および逆シリアル化する」を参照してください。
JSON を使用する場合、一部例外はありますが、DataContractSerializer でサポートされているものと同じ .NET 型 がサポートされます。サポートされる型の一覧については、「データ コントラクト シリアライザでサポートされる型」を参照してください。これには、ほとんどのプリミティブ型、ほとんどの配列型とコレクション型、DataContractAttribute と DataMemberAttribute を使用する複合型などがあります。
.NET 型から JSON 型へのマッピング
シリアル化および逆シリアル化の手順でマップされる場合の .NET 型と JSON/Javascript 型の対応表を次に示します。
.NET 型 | JSON/Javascript | メモ |
---|---|---|
数値 |
Double.NaN、Double.PositiveInfinity、Double.NegativeInfinity などの特殊な値はサポートされていないため、無効な JSON になります。 |
|
数値 |
このトピックの「列挙体と JSON」を参照してください。 |
|
Boolean |
-- |
|
String |
-- |
|
文字列 |
JSON のこれらの型の形式は、XML の場合と同じです (基本的には、TimeSpan は ISO 8601 の日付/時刻形式、GUID は "12345678-ABCD-ABCD-ABCD-1234567890AB" 形式、URI は "http://www.example.com" のような自然な文字列形式です)。正確な情報については、「データ コントラクト スキーマの参照」を参照してください。 |
|
文字列 |
形式は "name:namespace" です (最初のコロンの前が名前です)。名前または名前空間が存在しない場合があります。名前空間がない場合、コロンも省略されることがあります。 |
|
数値の配列型 |
各数値は、1 バイトの値を表します。 |
|
DateTime 型または文字列型 |
このトピックの「日付/時刻と JSON」を参照してください。 |
|
複合型 |
このトピックの「日付時刻と JSON」を参照してください。 |
|
XML 型および ADO.NET 型 (XmlElement、 |
文字列 |
このトピックの「XML 型と JSON」を参照してください。 |
空の複合型 |
-- |
|
コレクション、ディクショナリ、および配列 |
配列 |
このトピックの「コレクション、ディクショナリ、および配列」を参照してください。 |
複合型 (DataContractAttribute または SerializableAttribute が適用された型) |
複合型 |
データ メンバは、Javascript 複合型のメンバになります。 |
ISerializable インターフェイスを実装する複合型 |
複合型 |
他の複合型と同じですが、一部の ISerializable 型はサポートされません。このトピックの「高度な情報」の「ISerializable のサポート」を参照してください。 |
任意の型の Null 値 |
null |
null 許容型もサポートされており、null 非許容型と同様に JSON にマップされます。 |
列挙体と JSON
列挙メンバ値は、JSON では数値として処理されるため、列挙メンバ値がメンバ名として含まれているデータ コントラクトでの処理方法とは異なります。データ コントラクトでの処理詳細については、 、「データ コントラクトの列挙型」を参照してください。
- たとえば、
public enum Color {red, green, blue, yellow, pink}
の場合、yellow
をシリアル化すると、文字列の "yellow" ではなく、数字の 3 が生成されます。 - enum のメンバはすべて、シリアル化できます。EnumMemberAttribute 属性と NonSerializedAttribute 属性は、使用しても無視されます。
- 存在しない enum 値を逆シリアル化できます。たとえば、値 87 に対応する色の名前が定義されていなくても、この値を上記の Color 列挙値に逆シリアル化できます。
- フラグ enum は特殊ではなく、他の enum と同様に処理されます。
日付時刻 とJSON
JSON 形式では、日付と時刻を直接サポートしていません。ただし、日付と時刻は使用されることが非常に多いため、ASP.NET AJAX ではこれらの型を特別にサポートしています。ASP.NET AJAX プロキシを使用する場合、.NET の DateTime 型は JavaScript の DateTime 型に完全に対応します。
- ASP.NET を使用しない場合、JSON では、DateTime 型はこのトピックの「高度な情報」で説明する特殊な形式の文字列として表されます。
- JSON では、DateTimeOffset が複合型 {"DateTime":dateTime,"OffsetMinutes":offsetMinutes} として表現されます。offsetMinutes メンバは、当該イベントの場所に関連付けられたグリニッジ標準時 (GMT) (協定世界時 (UTC) とも呼ばれます) からの現地時刻のオフセットです。dateTime メンバは、当該イベントが発生した時点のインスタンスを表します (この場合も、ASP.NET AJAX を使用しているときは JavaScript の DateTime になり、使用していないときは文字列になります)。シリアル化時には、dateTime メンバは常に GMT でシリアル化されます。したがって、ニューヨーク時間の午前 3 時を示す場合、dateTime の時刻コンポーネントは 8:00 AM であり、offsetMinutes は 300 (GMT マイナス 300 分 (5 時間)) です。
メモ : DateTime オブジェクトと DateTimeOffset オブジェクトを JSON にシリアル化した場合、ミリ秒の精度までしか情報は保持されません。1 ミリ秒未満の値 (マイクロ秒/ナノ秒) は、シリアル化時に失われます。
XML 型と JSON
XML 型は JSON 文字列になります。
- たとえば、XElement 型のデータ メンバ "q" が <abc/> を含む場合、JSON は {"q":"<abc/>"} になります。
- XML のラップ方法を指定する特別なルールがいくつかあります。詳細については、このトピックで後述する「高度な情報」を参照してください。
- ASP.NET AJAX を使用している場合に、JavaScript で文字列ではなく XML DOM を使用するときは、WebGetAttribute で ResponseFormat プロパティを XML に設定するか、WebInvokeAttribute で ResponseFormat プロパティを XML に設定します。
コレクション、ディクショナリ、および配列
コレクション、ディクショナリ、および配列は、JSON ではすべて配列として表されます。
- CollectionDataContractAttribute を使用するカスタマイズは、JSON 表現では無視されます。
- ディクショナリは、直接 JSON を操作する手段ではありません。ディクショナリの <string,object> は、他の JSON テクノロジの使用方法から予想されるように WCF でサポートされていない場合があります。たとえば、ディクショナリで "abc" が "xyz" にマップされ、"def" が 42 にマップされている場合、JSON 表現では {"abc":"xyz","def":42} ではなく、[{"Key":"abc","Value":"xyz"},{"Key":"def","Value":42}] になります。
- JSON を直接使用する (厳密なコントラクトをあらかじめ定義せずに、キーと値に動的にアクセスする) 場合、いくつかのオプションがあります。
- 「Weakly-typed JSON Serialization (AJAX)」のサンプルを使用することを検討します。
- ISerializable インターフェイスと逆シリアル化コンストラクタを使用することを検討します。この 2 つの機構を使用すると、シリアル化と逆シリアル化の実行時にそれぞれ JSON のキーと値のペアにアクセスできます。ただし、これらの機構は、部分信頼シナリオでは機能しません。
- シリアライザを使用するのではなく、JSON と XML 間のマッピングを使用することを検討します。
- シリアル化のコンテキストにおける "ポリモーフィズム" は、基本型が必要な場合に派生型をシリアル化できることを指します**。コレクションをポリモーフィックに使用する場合は (コレクションを Object に割り当てる場合など)、JSON 固有の特別なルールがあります。この問題については、後の「高度な情報」で詳しく説明します。
追加の詳細情報
データ メンバの順序
JSON を使用する際、データ メンバの順序は重要ではありません。具体的には、Order が設定されていても、JSON データを任意の順序で逆シリアル化できます。
JSON の型
JSON の型は、逆シリアル化時には前述の表と一致する必要はありません。たとえば、Int は通常 JSON の数値にマップされますが、JSON 文字列に有効な数値が含まれていれば、その文字列から正常に逆シリアル化することもできます。つまり、"q" という Int データ メンバが存在する場合は、{"q":42} も {"q":"42"} も有効です。
ポリモーフィズム
ポリモーフィックなシリアル化は、基本型が必要な場合に派生型をシリアル化できることで成り立ちます。WCF による JSON シリアル化でこれがサポートされているのは、XML シリアル化がサポートされている方法と互換性がある場合です。たとえば、MyBaseType が必要な場合に MyDerivedType をシリアル化したり、Object が必要な場合に Int をシリアル化したりできます。
複合型を逆シリアル化する場合を除き、基本型が必要な場合に派生型を逆シリアル化すると、型情報が失われることがあります。たとえば、Object が必要な場合に Uri をシリアル化すると、JSON 文字列になります。この文字列を Object に逆シリアル化した場合、.NET の String が返されます。デシリアライザは、この文字列が最初は Uri 型であったことを認識していません。通常、Object を必要とするときに、すべての JSON 文字列が .NET 文字列として逆シリアル化されます。また、.NET のコレクション、ディクショナリ、および配列のシリアル化に使用するすべての JSON 配列は、実際の元の型に関係なく、Object 型の .NET Array として逆シリアル化されます。JSON のブール型は .NET の Boolean にマップされます。ただし、Object が必要な場合、JSON の数値型は .NET の Int32、Decimal、または Double の型として逆シリアル化されます。この場合、最も適切な型が自動的に選択されます。
インターフェイス型に逆シリアル化する場合、DataContractJsonSerializer は、宣言された型がオブジェクトである場合と同様に逆シリアル化します。
独自の基本型と派生型を使用している場合は、通常、KnownTypeAttribute、ServiceKnownTypeAttribute、または同等の機構を使用する必要があります。たとえば、戻り値が Animal である操作があり、実際には (Animal から派生した) Cat のインスタンスを返す場合、KnownTypeAttribute を Animal 型に適用するか、ServiceKnownTypeAttribute を操作に適用し、これらの属性で Cat 型を指定する必要があります。詳細については、「既知のデータ コントラクト型」を参照してください。
ポリモーフィックなシリアル化のしくみの詳細、およびポリモーフィックなシリアル化を使用するときに留意する必要のある制限事項については、このトピックで後述する「高度な情報」を参照してください。
バージョン管理
IExtensibleDataObject インターフェイスをはじめとするデータ コントラクトのバージョン管理機能は、JSON で完全にサポートされています。また、ほとんどの場合、ある形式 (XML など) で型を逆シリアル化した後、その型を別の形式 (JSON など) にシリアル化しても、IExtensibleDataObject にデータを保持できます。詳細な情報については、次のページを参照してください。 「上位互換性のあるデータ コントラクト」を参照してください。JSON は順序なしであるため、順序情報は失われることに注意してください。また、JSON では、同じキー名を持つ複数のキーと値のペアをサポートしていません。IExtensibleDataObject でのすべての操作は、本質的にポリモーフィックです。つまり、派生型はすべての型の基本型である Object に割り当てられます。
URL 内の JSON
(WebGetAttribute 属性を使用して) HTTP GET 動詞と共に ASP.NET AJAX エンドポイントを使用する場合、受信パラメータは、メッセージ本文ではなく要求 URL に配置されます。JSON は、要求 URL 内でもサポートされます。そのため、"number" という Int 型と "p" という Person 複合型を取得する操作がある場合、次のような URL になります。
http://example.com/myservice.svc/MyOperation?number=7&p={"name":"John","age":42}
ASP.NET AJAX Script Manager コントロールとプロキシを使用してサービスを呼び出すと、この URL はプロキシによって自動的に生成されるため、確認することはできません。JSON は、ASP.NET AJAX エンドポイントを使用しない URL では使用できません。
高度な情報
ISerializable のサポート
サポートされる ISerializable 型とサポートされない ISerializable 型
通常、JSON をシリアル化または逆シリアル化するときに、ISerializable インターフェイスを実装する型は完全にサポートされています。ただし、これらの型の一部 (一部の .NET Framework 型を含みます) は、次のような JSON 固有のシリアル化の側面が原因で正しく逆シリアル化されない方法で実装されています。
- ISerializable では、個々のデータ メンバの型は事前にはわかりません。このため、型をオブジェクトに逆シリアル化する場合と同様のポリモーフィックな状況になります。前述のように、これは JSON で型情報が失われる原因となる場合があります。たとえば、ISerializable 実装で enum をシリアル化した型を (適切にキャストせずに) enum に直接逆シリアル化しようとした場合、逆シリアル化は失敗します。これは、enum は JSON の数値型を使用してシリアル化されますが、JSON の数値型は .NET の組み込みの数値型 (Int32、Decimal、または Double) に逆シリアル化されるためです。そのため、この数値が enum 値を表すために使用されているという情報が失われます。
- ISerializable 型が逆シリアル化コンストラクタで特定の順序の逆シリアル化に依存する場合も、一部の JSON データの逆シリアル化に失敗する場合があります。これは、ほとんどの JSON シリアライザが特定の順序を保証しないためです。
ファクトリ型
IObjectReference インターフェイスは JSON で一般にサポートされますが、"ファクトリ型" 機能 (GetRealObject から、このインターフェイスを実装する型とは異なる型のインスタンスを返す機能) を必要とする型はサポートされません。
DateTime ワイヤ形式
DateTime 値は、"/Date(700000+0500)/" 形式の JSON 文字列として表されます。ここで、最初の数値 (この例では 700000) は GMT タイム ゾーンのミリ秒数であり、1970 年 1 月 1 日午前 0 時以降の (夏時間ではなく) 通常時間です。これ以前の時間を表すために、この数値が負の値になる場合があります。この例の "+0500" で構成される部分は省略可能であり、Local の時刻を示します。つまり、逆シリアル化時にローカル タイム ゾーンに変換される必要があります。この部分が指定されていない場合、時刻は Utc として逆シリアル化されます。実際の数値 (この例では "0500") と記号 (+ または -) は無視されます。
DateTime をシリアル化すると、Local と Unspecified の時刻はオフセットして書き込まれ、Utc はオフセットせずに書き込まれます。
ASP.NET AJAX クライアントの JavaScript コードにより、このような文字列は JavaScript の DateTime インスタンスに自動的に変換されます。類似する形式で .NET の DateTime 型ではない他の文字列が存在する場合、これらの文字列も変換されます。
変換は、文字 "/" をエスケープする場合 (つまり、JSON が "\/Date(700000+0500)\/" のような場合) にのみ実行されます。このため、WCF の JSON エンコーダ (WebHttpBinding によって有効になります) は、文字 "/" を常にエスケープします。
JSON 文字列内の XML
XmlElement
XmlElement は、ラップされずにそのままの状態でシリアル化されます。たとえば、<abc/> を含む XmlElement 型のデータ メンバ "x" は、次のように表されます。
{"x":"<abc/>"}
XmlNode の配列
XmlNode 型の Array オブジェクトは、この型の標準のデータ コントラクト名前空間にある ArrayOfXmlNode という要素にラップされます。"x" が、"value" と空の要素ノード "M" を含む名前空間 "ns" にある、属性ノード "N" を含む配列である場合、次のように表されます。
{"x":"<ArrayOfXmlNode xmlns=\"http://schemas.datacontract.org/2004/07/System.Xml\" a:N=\"value\" xmlns:a=\"ns\"><M/></ArrayOfXmlNode>"}
XmlNode 配列の先頭 (他の要素の前) にある空の名前空間の属性はサポートされません。
XElement と DataSet を含む IXmlSerializable 型
ISerializable 型は、"コンテンツ型"、"DataSet 型"、および "要素型" に細分化されます。これらの型の定義については、「データ コントラクトの XML および ADO.NET の種類」を参照してください。
"コンテンツ" 型と "DataSet" 型は、前のセクションで説明した XmlNode の Array オブジェクトと同様にシリアル化されます。これらの型は、その型のデータ コントラクトの名前と名前空間に対応する名前と名前空間を持つ要素にラップされます。
XElement などの "要素" 型は、このトピックで既に説明した XmlElement と同様に、そのままの状態でシリアル化されます。
ポリモーフィズム
型情報の保持
前述のように、ポリモーフィズムは JSON でサポートされていますが、いくつかの制限があります。JavaScript は厳密に型指定されていない言語であるため、通常、型 ID は問題ではありません。ただし、JSON を使用して厳密に型指定されたシステム (.NET) と厳密に型指定されていないシステム (JavaScript) 間で通信する場合、型 ID を保持していると役立ちます。たとえば、"Square" と "Circle" というデータ コントラクト名を持つ型が "Shape" というデータ コントラクト名を持つ型から派生したとします。"Circle" が .NET から JavaScript に送信され、後で "Shape" を必要とする .NET メソッドに返された場合、該当のオブジェクトが本来は "Circle" であったことが .NET 側でわかれば役立ちます。そうでない場合、派生型に固有の情報 ("Circle" のデータ メンバ "radius" など) が失われることがあります。
型 ID を保持するために、複合型を JSON にシリアル化するときに "型ヒント" を追加できます。デシリアライザはこのヒントを認識し、適切に動作します。"型ヒント" は、JSON のキーと値のペアです。キー名は "__type" です (2 つのアンダースコアの後に "type" という語が続きます)。値は、"DataContractName:DataContractNamespace" 形式の JSON 文字列です (最初のコロンまでが名前です)。前述の例の "Circle" は、次のようにシリアル化できます。
{"__type":"Circle:http://example.com/myNamespace","x":50,"y":70,"radius":10}
型ヒントは、XML スキーマ インスタンス標準で定義された xsi:type 属性によく似ており、XML をシリアル化または逆シリアル化するときに使用されます。
"__type" というデータ メンバは、型ヒントと競合する可能性があるため、禁止されています。
型ヒントのサイズの削減
JSON メッセージのサイズを縮小するために、既定のデータ コントラクト名前空間プレフィックス (http://schemas.datacontract.org/2004/07/) は文字 "#" に置き換えられます (この置換を元に戻すことを可能にするために、エスケープ ルールが使用されます。名前空間が "#" または "\" で始まる場合、これらの文字に "\" が追加されます)。したがって、"Circle" が .NET の "MyApp.Shapes" 名前空間の型である場合、既定のデータ コントラクト名前空間は http://schemas.datacontract.org/2004/07/MyApp になります。形状と JSON 表現は次のようになります。
{"__type":"Circle:#MyApp.Shapes","x":50,"y":70,"radius":10}
逆シリアル化時には、切り捨てられた名前 (#MyApp.Shapes) と完全名 (http://schemas.datacontract.org/2004/07/MyApp.Shapes) の両方が認識されます。
JSON オブジェクト内での型ヒントの位置
JSON 表現では、型ヒントは最初に出現する必要があります。JSON の処理でキーと値のペアの順序が重要となるのはこの場合だけです。たとえば、型ヒントの次の指定方法は無効です。
{"x":50,"y":70,"radius":10,"__type":"Circle:#MyApp.Shapes"}
WCF が使用する DataContractJsonSerializer と ASP.NET AJAX クライアント ページでは、いずれも型ヒントが常に最初に出力されます。
複合型にのみ適用される型ヒント
複合型以外の型の型ヒントを出力する方法はありません。たとえば、戻り値の型が Object である操作で Circle を返す場合、前に示したような JSON 表現が可能であり、型情報は保持されます。ただし、Uri が返される場合、JSON 表現は文字列であり、この文字列が Uri を表すために使用されているという情報は失われます。これは、プリミティブ型だけでなく、コレクションと配列にも適用されます。
型ヒントが出力される状況
型ヒントにより、メッセージ サイズが大幅に増加することがあります (これを軽減する 1 つの方法として、可能であれば短いデータ コントラクト名前空間を使用します)。そのため、次のルールによって型ヒントを出力するかどうかが制御されます。
- ASP.NET AJAX を使用する場合、基本型と派生型の割り当てが存在しない場合でも (Circle を Circle に割り当てる場合など)、型ヒントは可能である限り常に出力されます (これは、厳密に型指定されていない JSON 環境から厳密に型指定された .NET 環境への呼び出しプロセスにおいて、情報が予想外に失われることのないプロセスを完全に実現するために必要です)。
- ASP.NET と統合せずに AJAX サービスを使用する場合、基本型と派生型の割り当てが存在する場合にのみ、型ヒントが出力されます。つまり、Circle を Shape または Object に割り当てるときは出力されますが、Circle に割り当てるときには出力されません。この場合、JavaScript クライアントを適切に実装するために必要な最小限の情報しか提供されないため、パフォーマンスは向上しますが、適切に設計されていないクライアントでの型情報の損失を防ぐことはできません。クライアントでこの問題に対処することを避ける必要がある場合は、サーバーで基本型と派生型の割り当てを一切行わないようにします。
- DataContractSerializer 型を使用する場合、alwaysEmitTypeInformation コンストラクタ パラメータを使用すると、上記の 2 つのモードのいずれかを選択できます。既定値は "false" (必要な場合にのみ型情報を出力) です。
重複するデータ メンバ名
派生型情報は、基本型情報と共に同じ JSON オブジェクト内に存在しますが、任意の順序で出現する場合があります。たとえば、Shape は次のように表されることがあります。
{"__type":"Shape:#MyApp.Shapes","x":50,"y":70}
Circle は、次のように表されることがあります。
{"__type":"Circle:#MyApp.Shapes","x":50, "radius":10,"y":70}
基本型 Shape にも "radius" というデータ メンバが含まれている場合、シリアル化と逆シリアル化の両方で競合が発生することになります。これは、シリアル化では JSON オブジェクトは反復するキー名を持つことができないためであり、逆シリアル化では "radius" が Shape.radius と Circle.radius のどちらを参照しているかが不明確であるためです そのため、データ コントラクト クラスでは、"プロパティの隠ぺい" (基本クラスと派生クラスに同じ名前のデータ メンバが存在する) という概念は一般に推奨されていませんが、JSON では実際には禁止されています。
ポリモーフィズムと IXmlSerializable 型
IXmlSerializable 型は、既知の型の要件を満たしている限り、通常のデータ コントラクト規則に従って、通常どおり相互にポリモーフィックな割り当てを行うことができます。ただし、Object の代わりに IXmlSerializable 型をシリアル化すると、結果が JSON 文字列になるため、型情報が失われることになります。
ポリモーフィズムと一部のインターフェイス型
IXmlSerializable ではないコレクション型以外の型 (Object を除きます) が必要な場合、コレクション型または IXmlSerializable を実装する型をシリアル化することは禁止されています。たとえば、IMyInterface というカスタム インターフェイスと、int 型の IEnumerable と IMyInterface の両方を実装する MyType 型があるとします。この場合、戻り値の型が IMyInterface である操作から、MyType を返すことは禁止されています。これは、MyType は JSON 配列としてシリアル化する必要があり、型ヒントを必要としますが、前述のように型ヒントを配列と共に含めることはできないためです。型ヒントを含めることができるのは、複合型を使用する場合だけです。
既知の型と構成
DataContractSerializer が使用する既知の型機構は、DataContractJsonSerializer の場合と同様にすべてサポートされます。両方のシリアライザが同じ構成要素 (<system.runtime.serialization> の <dataContractSerializer>) を読み取って、構成ファイルを通じて追加された既知の型を検出します。
Object に割り当てられたコレクション
Object に割り当てられたコレクションは、IEnumerable を実装するコレクションと同様にシリアル化されます。複合型の場合は、各エントリに型ヒントが含まれた JSON 配列になります。たとえば、Object に割り当てられた Shape 型の List は、次のようになります。
[{"__type":"Shape:#MyApp.Shapes","x":50,"y":70},
{"__type":"Shape:#MyApp.Shapes","x":58,"y":73},
{"__type":"Shape:#MyApp.Shapes","x":41,"y":32}]
Object に逆シリアル化するときは、次の点に注意してください。
- Shape は、既知の型リストに含まれている必要があります。既知の型に含まれている Shape 型の List があっても効果はありません。この場合、シリアル化時に Shape を既知の型に追加する必要はありません。これは、自動的に実行されます。
- コレクションは、Shape インスタンスを格納する Object 型の Array として逆シリアル化されます。
基本コレクションに割り当てられた派生コレクション
派生コレクションを基本コレクションに割り当てると、通常、そのコレクションは基本型のコレクションと同様にシリアル化されます。ただし、派生コレクションの項目の型を基本コレクションの項目の型に割り当てることができない場合は、例外がスローされます。
型ヒントとディクショナリ
ディクショナリを Object に割り当てると、ディクショナリに含まれる Key および Value の各エントリは、Object に割り当てられている場合と同様に処理され、型ヒントを取得します。
ディクショナリ型をシリアル化した場合、"Key" メンバと "Value" メンバを含む JSON オブジェクトは、alwaysEmitTypeInformation 設定の影響を受けません。オブジェクトに型ヒントが含まれるのは、前述のコレクション ルールで必要とされる場合だけです。
JSON の有効なキー名
シリアライザは、有効な XML 名ではないキー名を XML エンコードします。たとえば、"123" という名前のデータ メンバの場合、"123" は無効な XML 要素名 (数字で始まる要素名) であるため、"_x0031__x0032__x0033_" のような名前にエンコードされます。XML 名が有効ではない一部の国際文字セットでも、同様の状況が発生する場合があります。JSON 処理に対する XML のこの影響については、「JSON と XML 間のマッピング」を参照してください。