.NET標準のDataContractJsonSerializerでのJSON処理
それでは、以下のようなJSONデータについて、最初にDataContractJsonSerializerでの読み書きの方法を見ていきましょう。このJSONデータは友人情報を表しており、文字列データとしてNameとAddress、数値としてAgeというフィールドを含んでいます。
{
"Name":"Doi",
"Address":"Tokyo",
"Age":32
}
なお、以降のコードは、配布サンプルのDataContractJsonSerializerSampleプロジェクトに含まれています。
参照設定
まず、DataContractJsonSerializerを使用するための設定を行いましょう。DataContractJsonSerializerはSystem.Runtime.Serializationというコンポーネントに含まれるクラスです。このクラスは、Visual Studioのプロジェクトの作成の際に、WCFに関連するテンプレートを選択した場合などは、そのまま使用できますが、[コンソール アプリケーション]などのテンプレートでは参照設定を行う必要があります。
Visual Studioの[プロジェクト]メニューから[参照の追加]を選択し、[.NET]タブから以下のように、System.Runtime.Serializationコンポーネントを選択して[OK]ボタンを押します。
また、必要なusingステートメントをファイル先頭で以下のように宣言しておきます。
using System.Runtime.Serialization; using System.Runtime.Serialization.Json;
.NETクラスの定義
DataContractJsonSerializerは、JSONを読み書きするためのライブラリというよりは、あくまでも.NETのクラスとJSONデータの相互変換を目的として準備されたライブラリです。そのため、JSONデータを扱う際には、JSONデータの構造に対応する.NETのクラスをあらかじめ定義しておく必要があります。先ほどのJSONデータに対応する.NETのクラスの定義は以下のようになります。
[DataContract]
public class FriendInfo
{
[DataMember]
public string Name{get;set;}
[DataMember]
public string Address { get; set; }
[DataMember]
public int Age { get; set; }
}
ここでは、JSONデータのフィールドと同じ名前のName, Address, Ageプロパティを定義しています。なお、注意しなければならないのは、対象とするクラスにはDataContract属性を、プロパティにはDataMember属性を、それぞれ指定する必要がある点です。これらの属性はWCFでクラスを公開するために必要な属性で、データ・コントラクトと呼ばれます。データ・コントラクトの詳細については以下の記事を参照してください。
JSONデータの読み書き
.NETクラスの定義ができれば、JSONデータの読み書きは簡単です。
まずはJSONデータの読み込みを行ってみましょう。
//(1)読み込むJSONデータ
var jsonString = @"{""Address"":""Tokyo"",""Age"":32,""Name"":""Doi""}";
//(2)DataContractJsonSerializerをインスタンス化
var serializer = new DataContractJsonSerializer(typeof(FriendInfo));
//(3)JSONデータを文字列からバイト配列に変換
var jsonBytes = Encoding.Unicode.GetBytes(jsonString);
//(4)バイト配列を読み込むMemoryStreamクラスを定義
var sr = new MemoryStream(jsonBytes);
//(5)ReadObjectメソッドでJSONデータを.NETオブジェクトに変換
var obj = (FriendInfo)serializer.ReadObject(sr);
//(6)変換したオブジェクトのプロパティ内容を確認
Console.WriteLine("Name:{0}, Address:{1}, Age:{2}",
obj.Name,obj.Address,obj.Age);
実際にデータを読み込むのはDataContractJsonSerializerクラスのReadObjectというメソッドですが、このメソッドを使用するにはいくつかの前準備が必要になるので、順を追って見ていきましょう。
(1)は読み込むJSONデータです。今回は文字列として定義していますが、もちろんWebサービスから取得したデータなどでも構いません。
(2)では、DataContractJsonSerializerをインスタンス化しています。この際、変換対象とする型(今回はFriendInfoクラス)を引数に指定するのがポイントです。これにより、このインスタンスはJSONデータとFriendInfoオブジェクトの相互変換を行うように設定されます。
(3)、(4)では、JSONデータの文字列をいったんバイト配列に変換した上で、それを読み込むMemoryStreamクラスを作成しています。これは、DataContractJsonSerializerがJSONデータを文字列としてではなく、Stream(.NETにおいて、ファイルや通信など連続するバイト列を表すクラス)として扱う仕様となっているためです。JSONデータを文字列として読み書きできないのはやや使いづらいですが、「.NETのクラスをJSONデータのWebサービスとして公開する」というDataContractJsonSerializerの本来の用途から考えると、こういった仕様になっているのは仕方ないところです。
(5)では、DataContractJsonSerializerのReadObjectメソッドを使い、StreamからJSONデータを読み取り、.NETオブジェクトに変換しています。ReadObjectメソッドの返値はObject型なので、ここではFriendInfo型にキャストしています。
(6)では、JSONデータから変換したFriendInfoオブジェクトの内容を確認しています。出力結果は以下のようになります。
Name:Doi, Address:Tokyo, Age:32
(1)で定義したJSONデータがきちんと.NETのオブジェクトに変換されていることが分かります。
一方、JSONデータの書き込みは以下のようなコードとなります。やはり書き込み先がStreamであるため、それに関わる部分を除けば、シンプルなコードです。
//DataContractJsonSerializerをインスタンス化
var serializer = new DataContractJsonSerializer(typeof(FriendInfo));
//変換する.NETオブジェクトを作成
var friend = new FriendInfo()
{
Name = "Doi",
Address = "Tokyo",
Age = 32
};
//JSONデータを書き込むためのMemoryStreamを作成
var stream = new MemoryStream();
//(1)WriteObjectメソッドで.NETオブジェクトをJSONデータに変換
serializer.WriteObject(stream, friend);
//(2)書き込んだMemoryStreamの内容を出力
stream.Position = 0;
var reader = new StreamReader(stream);
Console.Write(reader.ReadToEnd());
(1)では、DataContractJsonSerializerのWriteObjectメソッドを使い、.NETオブジェクトをJSONデータに変換しています。
(2)ではJSONデータの確認を行うため、MemoryStreamの内容を出力しています。WriteObjectメソッドの書き込み先がMemoryStreamのため、StreamをReader(.NETにおいて、連続する文字列を表すクラス)に変換するためのStreamReaderクラスを使うなど、多少ややこしいコードとなっています。出力結果は以下のようになります。
{"Address":"Tokyo","Age":32,"Name":"Doi"}
このように、DataContractJsonSerializerを使うことで、.NETオブジェクトとJSONデータの相互変換を行えます。事前に対応する.NETクラスの定義が必要なこと、読み書きはStreamを対象とすることに注意すれば、使用方法は簡単です。

![[参照の追加]ウィンドウでSystem.Runtime.Serializationコンポーネントを追加](http://cz-cdn.shoeisha.jp/static/images/article/5868/5868_DataContract01_s.gif)