2012/02 追記 : 本投稿の 「WCF Web Api」 (Preview) は、2012 年末に終了予定です。この機能は、現在、「ASP.NET Web API」 としてリリースされています。(ASP.NET Web API は、ASP.NET MVC 4 Beta 以降に含まれています。)
環境 : Visual Studio 2010, WCF Web API Preview 5
こんにちは。
WCF Web API は、現在 プレビュー版として提供されている新しい Web API の開発フレームワークです。
この WCF Web API を使うと、要求や応答の細かな制御 (StatusCode, Headers, さまざまな Content-Type への対応, など)、クエリーや OData のサポート、より高度なシナリオへの対応など (非同期実行など)、REST 固有の細かなカスタマイズが大変容易になっています。(以前 こちら でも紹介しましたが、HttpClient クラスを使用したクライアント用の API や、JsonValue クラスなどを使用した動的な Json シリアライズなど、クライアント側も含め、より柔軟な開発が可能です。既に、NuGet からも取得できます。)
この WCF Web API を使った利点 (メリット) や特徴については、時間を見つけて、いずれ説明しますが、まずは、そのための準備として、基本的な起動方法について以下に説明しておきます。
HttpServiceHostFactory を使用した起動
この方法は、従来の WCF 開発者にとって馴染みのある手法です。ServiceHost クラスから継承された Factory クラスを使って、WCF Web API を使った REST サービスを起動することができます。
さっそく、手順を見てみましょう。
Visual Studio を起動し、[WCF サービス アプリケーション] を新規作成します。
プロジェクトに、下記の 4 つの dll を参照追加します。
WCF Web API のインストール ディレクトリー\WCFWebApi\Http\prototypes\Microsoft.ApplicationServer.HttpEnhancements\bin\Debug\ の下の
Microsoft.Net.Http.dll
Microsoft.Net.Http.Formatting.dll
Microsoft.ApplicationServer.Http.dll
補足 : Preview 6 では、Microsoft.Net.Http.dll の代わりに System.Net.Http.dll を使用してください。
「10 行でズバリ!! REST サービスの作成」ではインターフェイス (IService1.cs) を使用しましたが、今回は、面倒なので、インターフェイスは使用せず構築します。このため、IService1.cs をプロジェクトから削除します。
Service1.svc をマウスで右クリックして、[マークアップの表示] を選択すると、.svc ファイルのソースが表示されます。
このソースに、下記太字の通り、Factory として HttpServiceHostFactory を設定します。(「10 行でズバリ!! REST サービスの作成」で使用した WebServiceHostFactory ではありませんので、注意してください。)
<%@ ServiceHost Language="C#" Debug="true" Service="WcfService1.Service1" CodeBehind="Service1.svc.cs" Factory="Microsoft.ApplicationServer.Http.Activation.HttpServiceHostFactory" %>
補足 : ここでは HttpServiceHostFactory クラスを使用して、内部で HttpServiceHost インスタンスを作成 (および、Open) していますが、もちろん、HttpServiceHost クラスを使ってプログラミング (new と Open) しても構いません。
Web.config を開き、 <system.serviceModel /> 要素全体をすべて削除します。(上記の Factory を使えば、必要に応じ、構成を追加するだけで OK です。)
Service1.svc.cs を開き、今回は、下記の通り実装しましょう。
. . .using System.Net;using System.Net.Http;. . .[ServiceContract]public class Service1{ [OperationContract] [WebGet(UriTemplate = "Orders/{id}")] public HttpResponseMessage GetOne(string id) { // 下記は、new HttpResponseMessage<OrderItem>(resObj) としても OK です HttpResponseMessage resMsg = new HttpResponseMessage(); resMsg.StatusCode = HttpStatusCode.OK; OrderItem resObj = new OrderItem { Id = int.Parse(id), Time = TimeZoneInfo.ConvertTimeBySystemTimeZoneId( DateTime.UtcNow, "Tokyo Standard Time") }; resMsg.Content = new ObjectContent<OrderItem>(resObj); return resMsg; }}[DataContract(Namespace = "", Name = "OrderItem")]public class OrderItem{ [DataMember] public int Id; [DataMember] public DateTime Time;}. . .
以上で完了です。
このサービスでは、ブラウザーなどを使って http://%5Bアプリケーション URL]/Service1.svc/Orders/[番号] の URI フォーマットで接続すると、オブジェクト (OrderItem) を Plain XML で返します。
ここでは、単に、オブジェクト (OrderItem) を Plain XML で返すだけのサンプルであるため WCF Web API のメリット (これまでの WCF REST サービス開発との違い) が伝わらないかもしれませんが、上記の HttpRequestMessage / HttpResponseMessage などを使って、上記の StatusCode の設定 (201, 304 など) のように、細かな制御が可能です。
なお、ここでは詳述しませんが、上記の ObjectContent は、WCF Web API の HttpContnt クラスから継承されたクラスで、上記のようにオブジェクトをラッピングできます。(この他にも、HttpContnt クラスから継承されたクラスとして StringContent、ByteArrayContent、MultipartContent などがあり、さまざまなコンテンツを REST サービスの返り値として設定できます。)
こうしたメリットは、いづれ、このブログでも紹介したいと思います。
ASP.NET MapRoute テーブルを使用した起動
WCF Web API は、上述からわかる通り WCF をベースとしていますが、つぎの起動方法を見ていただくとわかる通り、ASP.NET (および、ASP.NET MVC) とも、より親和性 高く利用できるようになっています。
今回は、Visual Studio で、[ASP.NET MVC 3] のプロジェクトを新規作成します。
下記の 7 つの dll を参照追加します。(今度は、WCF 関連の dll も追加しておきます。また、Microsoft.ApplicationServer.HttpEnhancements.dll は、後述する MapServiceRoute 拡張メソッドで使用します。)
System.ServiceModel.dll
System.ServiceModel.Web.dll
System.Runtime.Serialization.dll
WCF Web API のインストール ディレクトリー\WCFWebApi\Http\prototypes\Microsoft.ApplicationServer.HttpEnhancements\bin\Debug\ の下の
Microsoft.Net.Http.dll
Microsoft.Net.Http.Formatting.dll
Microsoft.ApplicationServer.Http.dll
Microsoft.ApplicationServer.HttpEnhancements.dll
補足 : Preview 6 では、Microsoft.Net.Http.dll の代わりに System.Net.Http.dll を使用してください。
プロジェクトの [追加] – [新しい項目] で、[クラス] を追加します。(今回、追加したクラスを OrderService.cs とします。)
Global.asax.cs を開き、下記 太字の通りコードを追加し、上記のクラス (サービス, Api) をパスとしてマップします。
. . .using Microsoft.ApplicationServer.Http.Activation;. . .public static void RegisterRoutes(RouteCollection routes){ routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapServiceRoute<OrderService>("Orders"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults );}
また、WCF サービスで上記のルーティングを可能にするため、Web.config を開いて、下記の通り、ASP.NET Compatibility Mode に設定します。
<?xml version="1.0" encoding="utf-8"?><configuration> . . . <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> </system.serviceModel></configuration>
つぎに、上記で追加した OrderService.cs (クラス) に、下記の通りコードを記述します。
. . .using System.ServiceModel;using System.ServiceModel.Web;using System.Runtime.Serialization;using System.Net;using System.Net.Http;. . .[ServiceContract]public class OrderService{ [OperationContract] [WebGet(UriTemplate = "{id}")] public HttpResponseMessage GetOne(string id) { // 下記は、new HttpResponseMessage<OrderItem>(resObj) としても OK です HttpResponseMessage resMsg = new HttpResponseMessage(); resMsg.StatusCode = HttpStatusCode.OK; OrderItem resObj = new OrderItem { Id = int.Parse(id), Time = TimeZoneInfo.ConvertTimeBySystemTimeZoneId( DateTime.UtcNow, "Tokyo Standard Time") }; resMsg.Content = new ObjectContent<OrderItem>(resObj); return resMsg; }}[DataContract(Namespace = "", Name = "OrderItem")]public class OrderItem{ [DataMember] public int Id; [DataMember] public DateTime Time;}. . .
以上で完了です。
ブラウザーなどを使って、http://[アプリケーション URL]/Orders/[番号] の URI フォーマットで接続すると、同様に、オブジェクト (OrderItem) を Plain XML で返します。MVC らしく、URI では Service1.svc という余計なアドレスも取れて、きれいに統合されています。
「よーし、WCF を作るぞー!」ではなく、このように、普通に ASP.NET MVC のプロジェクトを構築し、API 部分 (サービス部分) を WCF Web API を使って部分的に構築できます。(無論、MVC の JsonResult なども使えますが、より専門的、かつ、より柔軟に、Api 部分を実装できます。)
なお、WCF Web API は、上述の通り、プレビュー版であり、これらの dll は現時点 (2011/09) の Windows Azure には入っていません。
このため、Windows Azure に配置する場合は、Visual Studio のプロジェクトで、挿入された上記の WCF Web API の dll (4 つ) のそれぞれを選択して、下図の通り、プロパティ画面の [ローカル コピー] を True、[特定バージョン] を False に設定しておきます。(Windows Azure のプロジェクトで作成すると、自動的にこれらのプロパティが設定されるとは思いますが . . .)
WCF Web API は、今後の .NET による REST 開発のメインストリームとなる可能性もあるので、今から Watch しておいても損はないでしょう。
この WCF Web API を使用した応用例 (フォーマットの変更方法、OData 対応の方法、など) については、下記に記載しましたので参考にしてください。
- Web Api (REST サービス) におけるクロス ドメイン接続 (JSONP, CORS 等) と諸注意
- Web Api (REST サービス) で Custom Basic 認証を使用してクラウド (Windows Azure) に配置する
- Web Api (REST サービス) の Custom HTTP Header (HTTP ヘッダー)
- Web Api (REST サービス) のサーバー サイド Cache
- Web Api (REST サービス) における同時実行制御 (Concurrency Management)
- Web Api (REST サービス) で Custom MIME タイプを処理する
- Web Api (REST サービス) を検索 (Query) 可能にする (および、OData への対応)
- Web Api (REST サービス) における IoC (関心事の分割)
- Web Api (REST サービス) における操作ごとの制御 (Validation, 認証/権限, Exception 処理 など)
Categories: Uncategorized
2 replies»