はじめに
前回に続き、.NET Framework 3.0から導入されたコンポーネントとVisual Studio 2008でのサポートについて解説していきます。今回扱うのは通信フレームワークであるWCF(Windows Communication Foundation)です。.NET Framework 3.5でさまざまな新機能が追加され、より実用的なサービスの提供が可能となりました。
対象読者
- VS 2008に興味がある方
- WCFに興味がある方
- .NET技術でのWebサービス構築に興味がある方
必要な環境
シリーズ第1回を参考に、Visual Studio 2008のインストールを行ってください。
WCFについて
WCFは.NET Framework 3.0で導入された統合通信フレームワークです。
WCF導入前に存在したさまざまな通信フレームワークは、相互に互換性が無く、通信方式を簡単に差し替えることはできませんでした。例えば、.NETコンポーネント間で使われているTCPベースの.NET Remotingで構築したアプリケーションを、SOAPベースのWebサービスに対応させようとするなら、通信部分について、多くの書き換えが必要になっていました。
WCFはこうした複数の通信フレームワークを統合しており、共通のアプローチで複数の通信方式を扱うことができます。
具体的には
やや抽象的な話になってしまいましたが、具体的にはどんな効能があるのでしょうか。WCFはRPC(Remote Procedure Call:遠隔手続呼出)の一種であり、ネットワークを介してアプリケーション同士がお互いの公開する処理を相互に呼び出すための仕組みです。
これでもまだ抽象的です。「アプリケーション同士」とか「お互いの公開する処理」といった部分は、具体的には何を指すのでしょうか? 一番身近に感じられるWCFのユースケースは「WebサーバとWebブラウザ」あるいは「Webサーバ同士」が、「Webサービス」を公開する/呼び出すために使用する、というものでしょう。
- エンタープライズシステムで、Microsoft Message Queuingを使ったメッセージキューサービスを使用するため
- P2P(Peer to Peer)通信をサポートするため
- .NET Remotingで相互通信を行っていたアプリケーションをWCFベースの処理に移行するため
.NET Framework 3.0では、SOAPベースのXML Webサービスのみがサポートされていましたが、.NET Framework 3.5の新機能として、WCF Webプログラミング モデルがサポートされ、SOAPを使わない簡潔な方式の、いわゆる「RESTスタイル」のWebサービスや、AJAXでしばしば用いられるJSON(JavaScript Object Notation)形式のサポート、RSS/ATOMを使った配信のサポートなどが追加され、Webサービスの構築において、より実際的なフレームワークとなりました。
RESTの定義はさまざまありますが、本記事では次のような条件を満たすサービスをRESTスタイルのWebサービスとして扱います。
- ステートレスな(状態を持たない)プロトコル
- すべてのリソースはURIで一意に表される
- HTTPの基本操作(GET/PUT/DELETEなど)を用いる
- SOAPのようにメッセージの厳密な抽象化を行わず、XMLを直接扱う
本記事では、WCFの基本概念を説明した後に、SOAPベースのWebサービスの公開、RESTスタイルのWebサービスの公開、JSON形式のサポートなどのサンプルを見ていきます。
特に、WCFでWebサービスを提供することを主眼に記事を進めていきますので、WCFでクライアント側の処理を実装する部分については省略します。
WCFがサポートする通信方式
WCFは特定の通信方式に依存しないフレームワークで、現在のところ以下の通信方式をサポートしています。
通信方式 | 概要 | 相互運用性 |
TCP | TCP/IPベースのテキスト/バイナリ通信 | WCFコンポーネント |
HTTP | HTTPベースで、SOAPを使ったXML Web Services(Basic-ProfileないしはWebサービス拡張仕様)や、RESTスタイルのWebサービス、JSONなどをサポート | Webサービス(SOAP/REST/JSONなど)をサポートするアプリケーション |
名前付きパイプ | 名前付きパイプを使用する通信方式 | 同一マシン内のWCFコンポーネント同士 |
MSMQ | Microsoft Message Queuingを使用する通信方式 | WCFコンポーネント/MSMQをサポートするアプリケーション |
Peer to Peer | Windows Peer-to-Peer Networkingを使用する通信方式 | WCFコンポーネント |
さまざまな通信方式がサポートされていますが、相互運用性の観点からすると、HTTPベースのWebサービスを使うケースが多いでしょう。WCFを使えば、必要に応じて以上の通信方式を切り替える、ないしは共存させることができます。
WCFはABC(Address , Binding , Contract)という基本的な概念を導入することで、通信方式とロジックの分離を図り、通信方式の切り替えを容易にしています。
まずはこれらの概念を確認しておきましょう。
WCFのキーワード:ABC(+Bv)=E
WCFの基本的な概念を表すキーワードが「ABC(+Bv)=E」です。
ABC(+Bv)は「どこで(A:Address)、どのように(B:Binding , Bv:Behavior)、何を(C:Contract)」提供するかを表すキーワードの集合です。これらで構成されたサービスの提供口をエンドポイント(E:Endpoint)と呼びます。
頭文字 | キーワード | 意味 |
A | Address | サービスを提供する場所 |
B | Binding | サービスで使用するデータの表現形式 |
C | Contract | サービス内容の定義 |
Bv | Behaivor | サービスの細かな挙動 |
E | Endpoint | ABC(+Bv)で構成されたサービスの提供口 |
それぞれのキーワードについて説明していきましょう。
A:Address
「どこでサービスを提供するか」を表すAはAddress(アドレス)の略で、サービスを提供するURIを表します。WCFサービスを利用するクライアントはこのURIに対してリクエストを発行することになります。
以下にアドレスの例を示します。
使用する通信方式 | URI |
HTTP | http://somehost:8080/BasicService |
TCP | net.tcp://somehost:8081/TcpService |
名前付きパイプ | net.pipe://somehost/NamedPipeService |
本記事で解説するWebサービスの場合は、HTTP/HTTPSプロトコルを使ったURIがAddressとなります。
B:Binding
「どのようにサービスを提供するか」を表すBはBinding(バインディング)の略で、データの表現形式を表します。
例えば、同じHTTPプロトコルを使用する中でも、SOAPベースのWebサービスとRESTベースのWebサービスとJSONベースのWebサービスでは、同じデータを異なる表現形式で表すことになります。つまり、AddressだけではHTTPプロトコルだ、ということしか分かりませんので、それに加えて、HTTPプロトコル上でどのようにデータを表現するか、を表すのがこのバインディングです。
WCFでは、次のようなバインディングが提供されています。
バインディング名 | 概要 |
netTcpBinding | TCP/IPを使用するバインディング |
basicHttpBinding | SOAPベースのWebサービスのBasic-Profileを使用するバインディング |
wsHttpBinding | Webサービス拡張仕様を使用するバインディング |
netNamedPipeBinding | 名前付きパイプを使用するバインディング |
netMsmqBinding | MSMQを使用してWCFコンポーネントと接続するためのバインディング |
webHttpBinding | RESTスタイルのWebサービスおよびJSONをサポートするWebプログラミングモデルのバインディング |
Visual Studio 2008でWCFを使ったプロジェクトを作成すると、SOAPベースのWebサービスを提供するbasicHttpBindingがデフォルトで使用されます。.NET Framework 3.5からサポートされたWebプログラミングモデルに対応するwebHttpBindingを使用すれば、RESTスタイルのWebサービスやJSONをサポートすることができます。
なお、Webプログラミングモデルを使用する場合にはセキュリティに関する注意点があります。
basicHttpBindingやwsHttpBindingなど、SOAPベースのBindingでは、WS-Securityを含むWS-*(Webサービス拡張仕様)に基づくセキュリティを使用することができます。しかし、SOAPを使用しないWebプログラミングモデルでは、SOAPヘッダーがないため、特別なセキュリティ情報を付加することができません。webHttpBindingを使ったWebプログラミングモデルの場合、AddressにHTTPSプロトコルを指定することで、暗号化のみを行うことができます。
C:Contract
「何をサービスとして提供するか」を表すCはContract(コントラクト)の略で、実際にWCFを介してやり取りするデータを定義します。
WCFのコントラクトには以下の2種類があります。
種類 | 概要 |
サービス・コントラクト | サービスを提供するクラス・インターフェイスの定義 |
データ・コントラクト | やり取りするデータについての定義 |
コントラクトは、サービスを定義した.NETのクラス・インターフェイスに対し、属性として付加します。ここで重要な点ですが、コントラクトは通信方式やデータの表現形式には依存せず、公開するクラス・インターフェイス・メソッド・データがどれであるのか、WCFに通知する役割を担っています。
今回のサンプルで使用するコントラクトを見てみましょう。最初はサービス・コントラクトですが、サービスを提供するIService1
インターフェイスにServiceContract
属性が、インターフェイス内の実際の操作を表すGetMessage
メソッドにOperationContact
属性がそれぞれ付加されています。WCFはServiceContract
属性の付加されたクラス・インターフェイスを、サービスとして公開するクラス・インターフェイスとして、OperationContract
属性の付加されたメソッドを実際のサービスとして認識し、外部に公開します。
[ServiceContract] public interface IService1 { [OperationContract] string GetMessage(string name); ・・・中略・・・ }
次に、データ・コントラクトを見てみましょう。int
やstring
といった、.NET Frameworkの基本データ型については、特に定義することなく使用することができますが、独自のクラスについては、データをどのように受け渡す必要があるのかをWCFに通知する必要があり、これをデータ・コントラクトと呼びます。データ・コントラクトもサービス・コントラクトと同様に属性として表現します。
以下のサンプルでは、独自のクラスであるAddressBookEntry
クラスにDataContract
属性が、受け渡す必要のあるデータであるId/Name
プロパティにDataMember
属性が付加されています。これにより、WCFはAddressBookEntry
クラスのインスタンスがやり取りされる際に、そこに含まれるデータを適正に受け渡すことができます。
[DataContract] public class AddressBookEntry { int id; string name; [DataMember] public int Id { get { return id; } set { id = value; } } [DataMember] public string Name { get { return name; } set { name = value; } } ・・・中略・・・
Bv:Behavior
サービスの細かな挙動を表すBvはBehavior(ビヘイビア)の略です。WCFサービスのサーバ・クライアントで共有する必要がない、細かな設定情報が含まれています。
複数のエンドポイントを含むサービス全体に対する設定を行う、サービス・ビヘイビアと、エンドポイントごとの設定を行う、エンドポイント・ビヘイビアが存在します。
E:Endpoint
EはEndpoint(エンドポイント)の略で、ここまで説明したABC(+Bv)で構成されるサービスの提供口、ソケットのような概念を表します。
WCFサービスを利用するクライアントは、このエンドポイントに対してサービスのリクエストを行います。つまり、
- 通信先としてAで指定されたアドレスに
- データ表現形式としてBで指定されたバインディングを使い
- サービスの定義としてCで指定されたコントラクトに基づいて
リクエストする、というわけです。
このエンドポイントはサービス内に複数持つことができ、同じコントラクトに基づいて、異なるアドレス(通信方式)や、異なるバインディングを持つエンドポイントを同時に提供することもできます。
WCFのホスティング
WCFはABC(+Bv)で構成されるエンドポイントをクライアントに向けて提供しますが、以下の2種類のホスティング形態を持っています。
- アプリケーションによるホスティング
- IISによるホスティング(開発時はVisual Studioの提供するASP.NET 開発サーバ)
アプリケーションによるホスティングでもHTTPベースのWebサービスを提供することができますが、一般的な用途を考え、本記事ではIISによるWebサービスのホスティングを使用します。
ABC(+Bv)の指定方法
エンドポイントを構成するABC(+Bv)のうち、C(コントラクト)については、ソースコード中に属性として記述することを既に解説しました。それ以外のAB(+Bv)については、以下の2種類の指定方法があります。
- ソースコードで指定
- XMLベースの設定ファイルで指定
後者のXMLベースの設定ファイルは、.NET標準の構成ファイル(WindowsアプリケーションではApp.config、Webアプリケーションの場合はWeb.config)を使用します。本記事ではIISによるホスティングを使用しますので、ABCはWeb.configファイルで設定します。
以下に実際の記述例を示します。
<configuration> ・・・中略・・・ <system.serviceModel> <services> <service behaviorConfiguration="WcfServiceTest.Service1Behavior"
name="WcfServiceTest.Service1"> <endpoint address="" binding="basicHttpBinding"
bindingConfiguration=""
name="" contract="WcfServiceTest.IService1" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WcfServiceTest.Service1Behavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
中ほどにあるendpoint
要素のaddress/binding/contract
属性が、それぞれABCを指しています。
IISによるホスティングを使用する場合、アドレスはHTTPプロトコルベースで、IIS側で割り当てられます。ここではbinding
属性にSOAPベースのWebサービスであるbasicHttpBinding
を、contract
属性としてServiceContract
属性を付加した、先ほどのWcfServiceTest.IService1
インターフェイスを指定しています。
さて、前置きが非常に長くなりましたが、WCFの基本概念を押さえることができたでしょうか。WCFサービスのキーワードであるABCをしっかり押さえつつ、サンプル作成に入っていきましょう。
サンプル1:SOAPスタイルのWebサービス
まず最初にWCFのデフォルトである、SOAPスタイルのWebサービスのサンプルから作成しましょう。
今回のサンプルでは、入力された文字列に挨拶メッセージを返すGetMessage
と、ID・名前・住所を持つアドレス帳のエントリを返すGetAddressBookEntry
の2つのサービスを提供します。サービス内容はシンプルなものですが、どのようにサービスを公開することができるのか、WCFを使った流れを把握しましょう。
プロジェクトの作成
Visual Studio 2008を起動し、新しいプロジェクトを作成します。今回は[Visual C#]-[Web]カテゴリから[WCFサービス アプリケーション]を選択し、「WcfServiceTest」という名前でプロジェクトを作成します。
新しいプロジェクトを作成すると、自動的にいくつかのファイルが作成されます。
ファイル名 | 概要 |
IService1.cs | 公開するサービスのインターフェイス定義。サービス・コントラクトとデータ・コントラクトが記されている。 |
Service1.svc | 公開されるWCFサービスのエントリポイント。 |
Service1.svc.cs | サービスの実装コード。IService1インターフェイスを実装したService1クラスが記されている。 |
Web.config | XMLベースの設定ファイル。WCFで提供するサービスの設定が記されている。 |
まず「Service1.svc」を見てみましょう。
<%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceTest.Service1" CodeBehind="Service1.svc.cs" %>
内容はシンプルで、どのサービスを提供するかを定義しているだけです。今回は自動生成されたファイルにサービスを実装していきますので、このファイルは特に変更しません。このファイルがエントリポイントとなって、サービスを受け付けることになる、という点を押さえておきましょう。
コントラクトの定義
では、最初にコントラクトを定義します。「IService1.cs」を開き、以下の内容に書き換えてください。
[ServiceContract] public interface IService1 { [OperationContract] string GetMessage(string name); [OperationContract] AddressBookEntry GetAddressBookEntry(string id); } [DataContract] public class AddressBookEntry { int id; string name; string address; [DataMember] public int Id { get { return id; } set { id = value; } } [DataMember] public string Name { get { return name; } set { name = value; } } [DataMember] public string Address { get { return address; } set { address = value; } } }
外部に公開する2つのメソッドのインターフェイス定義と、そこで使用するデータに対して、属性を付加しています。各属性の意味はコントラクトの項で説明した通りです。
サービスの実装
次に「Service1.svc.cs」を開き、サービスの実装コードを記します。
public class Service1 : IService1 { public string GetMessage(string name) { return string.Format("Hello {0}!", name); } public AddressBookEntry GetAddressBookEntry(string id) { int idvalue = int.Parse(id); AddressBookEntry entry; switch (idvalue) { case 1: entry = new AddressBookEntry() { Id = 1, Name = "Doi", Address = "Tokyo" }; break; default: entry = new AddressBookEntry() { Id = 0, Name = "Anonymous", Address = "?" }; break; } return entry; } }
実装自体は特別な内容ではなく、GetMessage
メソッドは入力された名前にあいさつを付加した文字列を返し、GetAddressBookEntry
メソッドはアドレス帳の項目を返します。本来であればGetAddressBookEntry
メソッドには、データベースにアクセスするなどの処理が含まれることでしょう。実装クラスにWCFに依存した内容がまったく含まれないことに注目してください。
ABCの定義
次に、このサービスで使用するABCの指定を行います。
Web.configファイルを直接編集することもできますが、Visual Studio 2008にはMicrosoft Service Configuration Editorという、WCFの設定項目をGUIで編集するツールが付属していますので、これを利用することにしましょう。
[ツール]-[WCF Service Configuration Editor]を選択し、[File]-[Open]よりWcfServiceTestプロジェクトのWeb.configファイルを開きます。
複数のプロジェクトでMicrosoft Service Configuration Editorを使用する場合、間違って異なるプロジェクトの設定ファイルを開かないよう注意してください。
設定ファイルを開くと、次のような画面が表示されます。
右下に2つのエンドポイントが表示されています。下はメタデータ取得のためにVisual Studio 2008が自動的に作成するエンドポイントですので無視してください。
上のエンドポイントが今回使用するものです。
- Addressは空
- BindingはSOAPベースの
basicHttpBinding
- Contractは
WcfServiceTest.Iservice1
インターフェイス
となっています。今回は変更の必要はありませんので、[File]-[Exit]から終了させましょう。
サンプルの実行
[F5]キーを押してサービスを実行してみましょう。最初に1回、デバッグを有効にするかどうかについてのダイアログが表示されますので、[OK]ボタンを押してください。
Webブラウザが起動し、次のようなサービス画面が表示されるはずです。
画面中のリンクをクリックすると、WebサービスのWSDL定義を閲覧することができます。この時点でWCFによるSOAPベースのWebサービスは完成し、クライアントのリクエストを受け付けることができます。実際にクライアントを作成してみましょう。
IISへのホスティング
クライアント作成の前に、IISへのホスティングを行っておきます。これはASP.NET開発サーバではポート番号が不定のため、クライアントから接続するサービスを提供するには不都合なためです。
WcfServiceTestプロジェクトの上で右クリックし、[発行]を選択します。
「Webの発行」ダイアログで、右の[...]ボタンを押します。
「Webサイトを開く」ダイアログで、左側の[ローカルIIS]をクリックします。右上の[新しいWebアプリケーションの作成]ボタンを押して新しいWebアプリケーション(ここではWcfTestとした)を作成し、[開く]ボタンを押します。
「Webの発行」ダイアログで[発行]ボタンを押します。
これでIISへのホスティングが完了しました。実際にアクセスして確かめてみましょう。
http://localhost/WcfTest/Service1.svc
にアクセスし、先ほどと同じ画面が表示されることを確認してください。
クライアントの作成
では、IISで公開されたWCFによるSOAPベースのWebサービスを、クライアントから呼び出してみましょう。SOAPベースのWebサービスはクライアントの種類を問いませんが、今回はWindows Formアプリケーションから呼び出してみます。
[ファイル]-[追加]-[新しいプロジェクト]から[Visual C#]-[Windows]カテゴリの[Windowsフォーム アプリケーション]を選択し、新規プロジェクトを追加します。今回はプロジェクト名を「ClientTest」としました。
Webサービスを呼び出すため、[プロジェクト]-[サービス参照の追加]から、先ほどのURIを指定して参照の追加を行います。
左側のサービスペインでIService1を選択すると、右側に公開された操作が表示されます。[OK]ボタンを押すと、サービスを利用するための参照クラスが生成されます。
フォームにボタンとラベルを配置し、ボタンをダブルクリックしてイベントハンドラを記述します。
イベントハンドラ内で、WCFサービスを呼び出す処理を行います。
private void button1_Click(object sender, EventArgs e) { ServiceReference1.IService1 service = new ServiceReference1.Service1Client(); ServiceReference1.AddressBookEntry entry = service.GetAddressBookEntry("1"); label1.Text = string.Format("ID={0} , Name={1} , Address={2}", entry.Id, entry.Name, entry.Address); }
自動生成されたServiceReference1.Service1Client
クラスを使い、IService1
インターフェイスを介して、IISでホスティングされているGetAddressBookEntry
メソッドを呼び出し、結果をラベルに表示します。
ClientTestプロジェクトをスタートアップ プロジェクトに指定し、[F5]キーを押して実行してみましょう。正しくサービスが公開されていれば、次のように、アドレス帳の項目が表示されるはずです。
以上の手順でSOAPベースのWebサービスを作成し、呼び出しを確認することができました。ABCを適切に設定すれば、簡単にWebサービスを公開することができます。
サンプル2:RESTスタイルのWebサービス
SOAPベースのWebサービスは、厳密なXML定義を扱う関係上、前項のサンプル作成を見ても分かるとおり、クライアント実装においてもそれなりの手順を踏む必要があります。Visual Studioを使って参照クラスを自動生成すれば手順は簡略化できますが、Ajaxなどで簡単にアクセスするには敷居が高いと言えます。開発者としても、ブラウザで簡単に内容を確認できないのは歯痒いところです。
こうした問題点を受け、近年のWebサービスの潮流は、SOAPベースのものから、データを抽象化せず、直接XMLを扱うRESTスタイルのサービスへと向かいつつあります。
では、.NET Framework 3.5でサポートされたWebプログラミングモデルを使い、RESTスタイルのWebサービスを作成してみましょう。
変更の流れ
SOAPベースのWebサービスから、RESTスタイルのWebサービスに変更するには、以下の手順を踏みます。
- エンドポイントの設定変更
- HTTP GETのURIテンプレート指定
basicHttpBinding
から、WebプログラミングモデルのwebHttpBinding
に変更します。また、サービスビヘイビアとして、Webプログラミングモデルに必要なwebHttp
というビヘイビアを追加します。エンドポイントの設定変更
まずはABCの書き換えです。Microsoft Service Configuration Editorを起動し、WcfServiceTestプロジェクトのWeb.configファイルを開きましょう。
左上のConfigurationペインで[Advanced]-[Endpoint Behaviours]をクリックし、右上の[New Endpoint Behaviour Configuration]をクリックします。
[Add]ボタンを押し、ビヘイビア一覧ダイアログから[webHttp]を選択して[Add]ボタンを押します。
左上のConfigurationペインで[Services]-[WcfServiceTest.Service1]-[Endpoints]-[(Empty Name)]の下のアイテムをクリックします。ちなみに上のアイテムは前述のメタデータ交換用のエンドポイントです。
右ペインの[Behaviour Configuration]に先ほど作成したwebHttpBehavior
を、[Binding]にwebHttpBinding
を指定します。
これで、エンドポイントをSOAPベースからRESTスタイルのWebサービスに切り替えることができました。
HTTP GETのURIテンプレート指定
SOAPベースのWebサービスの場合、サービスのパラメータはPOSTで指定しますが、RESTスタイルのWebサービスの場合は、パラメータをHTTP GETリクエストのURIの中で指定します。従って、パラメータをURIでどのように表現するか(URIのテンプレート)を定義する必要があります。これはコントラクトと同様に属性として、ソースコード中に付加します。
次のように、公開するメソッドにWebGet
属性を追加し、UriTemplate
プロパティに引数名を{}に含める形でURIを記述します。
[OperationContract] [WebGet(UriTemplate = "Hello?name={name}")] string GetMessage(string name); [OperationContract] [WebGet(UriTemplate = "GetAddressBook/{id}")] AddressBookEntry GetAddressBookEntry(string id);
WebGet
属性のUriTemplate
プロパティで指定したURIは、そのサービスのAddressの後に付加されます。
従って、今回のAddressは
http://localhost/WcfTest/Service1.svc
ですので、その後にURIテンプレートを付加した
http://localhost/WcfTest/Service1.svc/Hello?name=doi
というアクセスは
IService1.GetMessage("doi")
という形式でメソッドを呼ぶことに対応します。
同様に
http://localhost/WcfTest/Service1.svc/GetAddressBookEntry/1
というアクセスは
IService1.GetAddressBookEntry("1")
という形式でメソッドを呼ぶことに対応します。
URIテンプレートにおいて、パスなどは自由に使用することができますので、それぞれの処理に意味のあるURIを割り当てることができます。今回は引数をクエリストリングやパスとして表現しました。
サンプル実行
では、再度IISへの発行を行い、実行してみましょう。
http://localhost/WcfTest/Service1.svc/Hello?name=doi
http://localhost/WcfTest/Service1.svc/GetAddressBookEntry/1
それぞれの結果が、直接XMLで表示されていることに注目してください。型名がルート要素となり、それ以下にフィールドが並んでいます。
こうしたシンプルなXMLであれば、クライアントでのパースも楽に行うことができるでしょう。
SOAPベースのWebサービスからRESTスタイルのWebサービスに書き換えるまで、ほんのわずかな手順しか掛からなかったことに注目してください。HTTP GETのURIテンプレートを記述する、という少しの手間以外は、ABCを書き換えるだけで切り替えを行うことができました。
サンプル3:JSONサポート
では、さらに対応形式を変えてみましょう。Ajaxで頻繁に使用されるJSON形式です。JSONはWebブラウザ上のJavaScriptで、文字列としてパースする必要がなく、直接扱うことのできるテキストベースのデータエンコード形式です。前述の通り、.NET Framework 3.5から、WCFでもJSONがサポートされるようになりました。
JSONはRESTスタイルのWebサービスと同様、WCFのWebプログラミングモデルでサポートされており、バインディングは共通のwebHttpBinding
を使用します。従って、ABCの変更は不要で、ごくごくわずかな設定の書き換えだけでJSONサポートを行うことができます。
WebGet属性の書き換え
JSONサポートに必要なのは、WebGet
属性のResponseFormat
プロパティを指定する、ただそれだけです。
次のように、「IService1.cs」内のサービス・コントラクトのWebGet
属性に、ResponseFormatとしてWebMessageFormat.Json
を指定します。
[OperationContract] [WebGet(UriTemplate = "/Hello?name={name}", ResponseFormat = WebMessageFormat.Json)] string GetMessage(string name); [OperationContract] [WebGet(UriTemplate = "/GetAddressBook/{id}", ResponseFormat = WebMessageFormat.Json)] AddressBookEntry GetAddressBookEntry(string id);
以上で書き換えは終了です。
JSONサポート確認
では、再度IISへの発行を行い、実行してみましょう。
それぞれ、次のような結果が返ってきます。
http://localhost/WcfTest/Service1.svc/Hello?name=doi
"Hello doi!"
http://localhost/WcfTest/Service1.svc/Hello?name=foo
"Hello foo!"
http://localhost/WcfTest/Service1.svc/GetAddressBookEntry/1
{"Address":"Tokyo","Id":1,"Name":"Doi"}
http://localhost/WcfTest/Service1.svc/GetAddressBookEntry/2
{"Address":"?","Id":0,"Name":"Anonymous"}
文字列を返すだけのGetMessage
ではよく分かりませんが、GetAddressBookEntry
の結果を見ると、フィールドと値が:や,で区切られた、JSON形式で正しく出力されていることが分かります。
切り替え所要時間は数十秒、といったところでしょうか。REST化以上にJSON化は簡単だったことが実感できたかと思います。
まとめ
WCFの概念と、Visual Studio 2008を使ったWebサービスの構築、RESTスタイルのWebサービス・JSONサポートについて、概観することができました。WCFの機能は非常に大きく、1つの記事ですべて説明することはできませんが、ここで基本的な概念を掴むことができましたので、他の通信方式や、さまざまなビヘイビアなどを扱う場合にも、MSDNのドキュメントを参照しながら理解を進めていけるでしょう。
実のところ、Visual Studio 2005+ExtensionsとVisual Studio 2008のWCFサポートは、特別な機能差はありません。これは、Visual Studio 2005+Extensionsの時点でMicrosoft Service Configuration Editorが組み込まれており、既に実装に十分な機能を提供していたためです。しかし、.NET Framework 3.5でWCFに加えられた機能は非常に強力で、これまでWCFを使うことのなかった、より多くの開発者が、RESTスタイルのWebサービスやJSONサポートなどの機能を使うため、WCFベースのWebサービス実装に取り組むことになります。そうした際に、.NET Framework 3.5とWCFを標準サポートしたVisual Studio 2008は、心強い味方となってくれることでしょう。
.NET Framework 3.0のWCFでは、通信方式を簡単に切り替えられる、共存できると言っても、現実的なユースケースが正直想像しづらかったのですが、.NET Framework 3.5のWCFでは、SOAPベースのWebサービス・RESTスタイルのWebサービス・JSON形式などを混在させながら同時に提供するなど、WCFがもともと持っていたポテンシャルを存分に発揮できるようになりました。今後さらに新しいデータの表現形式が出てきたとしても、WCFベースのサービスを構築しておけば、WCFでサポートされた時点ですぐに対応できます。あるいは新しいバインディングを開発すれば、WCFのバージョンアップを待つことなく、新しい形式に対応することもできます。Visual Studio 2008で正式にサポートされた強力な通信フレームワークであるWCFに、この機会にぜひ取り組んでみてください。
次回は、.NET Framework 3.0から導入されたワークフローフレームワークであるWFについて、Visual Studio 2008でどのように利用できるかを特集します。
参考資料
- WCF Webプログラミング モデル
- WCF(Windows Communication Foundation)チュートリアル 前編