Open棟梁Project - マイクロソフト系技術情報 Wiki
[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]

* 目次 [#ec67115c]
#contents

*出力したいJSONを確認する [#dbc5c33d]
まず、どのようなJSONを出力したいのかを確認します。~
これがなければ、始まりません。

*出力したいJSONに合わせて、クラスやプロパティを定義する [#e10b9cbb]
次に、出力したいJSONに合わせて、クラスやプロパティを定義します。

**基本 [#i16a4292]
基本的には、以下のルールに従って、クラスやプロパティを定義します。
-JSONオブジェクト ({ キー名 : 値 }) の場合は、「キー名」を名前に持つプロパティを定義する
-JSON配列 ([ 値1, 値2, ... ]) の場合は、リストまたは配列のプロパティを定義する

***例 [#jc13febc]
|出力したいJSON|定義するクラス・プロパティ|h
|{ "key1" : "value1", "key2" : "value2" }|public class Sample&br;{&br;    ''string key1'' { get; set; }&br;    ''string key2'' { get; set; }&br;}|
|[ "1", "2", "3" ]|''List<string>'' listData { get; set; }|
|{ "key1" : [ "1", "2", "3" ] }|public class Sample&br;{&br;&nbsp;&nbsp;&nbsp;&nbsp;''List<string> key1'' { get; set; }&br;}|
|{ "key" : { "key1" : "value1", "key2" : "value2" } }|public class Sample&br;{&br;&nbsp;&nbsp;&nbsp;&nbsp;''string key1'' { get; set; }&br;&nbsp;&nbsp;&nbsp;&nbsp;''string key2'' { get; set; }&br;}&br;public class Sample2&br;{&br;&nbsp;&nbsp;&nbsp;&nbsp;''Sample key'' { get; set; }&br;}|
|[ { "key1" : "value1", "key2" : "value2" }, &br;{ "key1" : "value3", "key2" : "value4" } ]|public class Sample&br;{&br;&nbsp;&nbsp;&nbsp;&nbsp;''string key1'' { get; set; }&br;&nbsp;&nbsp;&nbsp;&nbsp;''string key2'' { get; set; }&br;}&br;''List<Sample>'' listData { get; set; }|

**応用 [#zc3d7aa2]
***キー名が不定の場合 [#ffae339a]
キー名が不定 (実行時に決まる) の場合、事前にクラス/プロパティを定義しておくことができません。~
このようなときは、Dictionary<string, object> として定義します。

*JSONを返すサービスを作成する [#n81c4388]
**WCFの場合 [#wdb092a0]
WCFでJSONを返す場合、既定ではDataContractJsonSerializerが使用されます。

***既定のDataContractJsonSerializerを使用してJSONを返す方法 [#c008c778]
-WCFサービスを作成し、コントラクト部分にWebGet属性を追加します。ポイントは以下の2点です。
--ResponseFormatに、WebMessageFormat.Jsonを指定し、JSONを返すサービスであることを宣言する
--サービスメソッドの戻り値の型に、先ほど定義したクラス/プロパティの型を指定する

-サービスを実装します。
 [ServiceContract]
 public interface IJSONService
 {
     [OperationContract]
     [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetJson")]
     Sample GetJson();
 }
 
 public class JSONService : IJSONService
 {
     public Sample GetJson()
     {
         // JSON にシリアライズする元となるオブジェクトを作成する
         Sample sample = new Sample()
         {
             StringKey = "StringValue",
             IntKey = 123,
             ListKey = new List<string>() { "List1", "List2", "List3" }
         };
 
         // クライアントにデータを返す
         return sample;
     }
 }
 
 public class Sample
 {
     public string StringKey { get; set; }
     public int IntKey { get; set; }
     public List<string> ListKey { get; set; }
 }

-作成したWCFサービスを、RESTサービスとして公開するための設定をweb.configに行います
 <system.serviceModel>
     <services>
         <service name="WebApplication1.JSONService">
             <endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyBehavior"
                       contract="WebApplication1.IJSONService" />
         </service>
     </services>
     <behaviors>
         <serviceBehaviors>
             <behavior name="">
                 <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                 <serviceDebug includeExceptionDetailInFaults="false" />
             </behavior>
         </serviceBehaviors>
         <endpointBehaviors>
             <behavior name="MyBehavior">
                 <webHttp/>
             </behavior>
         </endpointBehaviors>
     </behaviors>
     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
         multipleSiteBindingsEnabled="true" />
 </system.serviceModel>

-"http://~/JSONService.svc/GetJson" にリクエストを送ったときの実行結果
 {"IntKey":123,"ListKey":["List1","List2","List3"],"StringKey":"StringValue"}

-既定のDataContractJsonSerializerの注意点~
既定のDataContractJsonSerializerでは、Dictionary型のオブジェクトを正しく扱えません。~
Dictionary型のオブジェクトを扱う場合は、[http://www.newtonsoft.com/json JSON.NET]やJavaScriptSerializerなど、その他のシリアライザーを使用する必要があります。その方法は、次に紹介します。

***DataContractJsonSerializer以外のシリアライザーを使用してJSONを返す方法 [#t49e9049]
-WCFサービスを作成し、コントラクト部分にWebGet属性を追加します。ポイントは以下の2点です。
--ResponseFormatには何も指定しない
--サービスメソッドの戻り値の型は、System.ServiceModel.Channels.Messageを指定する~
(SOAPのMessage BodyにJSONを直接書き込む)

-サービスを実装します。
 [ServiceContract]
 public interface IJSONService2
 {
     [OperationContract]
     [WebGet(UriTemplate = "GetJson")]
     Message GetJson();
 }
 
 public class JSONService2 : IJSONService2
 {
     public Message GetJson()
     {
         // JSON にシリアライズする元となるオブジェクトを作成する
         Sample2 sample = new Sample2()
         {
             key = new Dictionary<string, string>()
             {
                 {"key1", "value1"}, 
                 {"key2", "value2"}, 
                 {"key3", "value3"}
             }
         };
 
         // JSON.NET を使用して JSON 形式にシリアライズ
         string jsonStr = JsonConvert.SerializeObject(sample);
 
         // 'X-Content-Type-Options: nosniff' ヘッダーを追加する
         WebOperationContext.Current.OutgoingResponse.Headers.Add("X-Content-Type-Options", "nosniff");
 
         // JSON を返す
         return WebOperationContext.Current.CreateTextResponse(jsonStr,
             "application/json; charset=utf-8",
             Encoding.UTF8);
     }
 }
 
 public class Sample2
 {
     public Dictionary<string, string> key { get; set; }
 }

-作成したWCFサービスを、RESTサービスとして公開するための設定をweb.configに行います
 <system.serviceModel>
     <services>
         <service name="WebApplication1.JSONService2">
             <endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyBehavior"
                       contract="WebApplication1.IJSONService2" />
         </service>
     </services>
     <behaviors>
         <serviceBehaviors>
             <behavior name="">
                 <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                 <serviceDebug includeExceptionDetailInFaults="false" />
             </behavior>
         </serviceBehaviors>
         <endpointBehaviors>
             <behavior name="MyBehavior">
                 <webHttp/>
             </behavior>
         </endpointBehaviors>
     </behaviors>
     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
         multipleSiteBindingsEnabled="true" />
 </system.serviceModel>

-"http://~/JSONService2.svc/GetJson" にリクエストを送ったときの実行結果
 {"key":{"key1":"value1","key2":"value2","key3":"value3"}}

**ASP.NET Web APIの場合 [#paf23e5b]
ASP.NET Web APIでは、既定でJSON.NETによってシリアライズされます。~
このため、Dictionary型も問題なくシリアライズできます。

-Webアプリケーションに、Web APIを作成します。
 public class ValuesController : ApiController
 {
     // GET api/values
     public Sample Get()
     {
         // JSON にシリアライズする元となるオブジェクトを作成する
         Sample sample = new Sample()
         {
             key = new Dictionary<string, string>()
             {
                 {"key1", "value1"}, 
                 {"key2", "value2"}, 
                 {"key3", "value3"}
             }
         };
         
         // JSON を返す
         return sample;
     }
 }
 
 public class Sample
 {
     public Dictionary<string, string> key { get; set; }
 }

-"http://~/api/Values" にリクエストを送ったときの実行結果
 {"key":{"key1":"value1","key2":"value2","key3":"value3"}}

-ASP.NET Web APIの注意点~
既定では、ASP.NET Web APIは、HTTPリクエストに含まれるAcceptヘッダーの内容により、クライアントに返すデータの形式が決められます。
--Acceptに''application/xml''が含まれていた場合は、XMLとして返されます。(レスポンスのContent-Typeヘッダーが''application/xml''となる)
--Acceptに''application/json''が含まれていた場合は、JSONとして返されます。(レスポンスのContent-Typeヘッダーが''application/json''となる)~
このため、常にJSONとしてデータを受け取りたい場合は、リクエストヘッダーに''Accept: application/json''を必ずつけるようにしてください。


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS