【T2-310補足1】.NET における REST サービスのコンシューマ実装
環境 :
Visual Studio 2008 SP1
WCF REST Starter Kit (Preview 2)
こんにちは。
Tech Ed 2009 セッション T2-310 では、またまた時間がなく、大変失礼致しました。例により、説明割愛した箇所を補足致します。
まずは、デモでお見せした WCF REST Starter Kit によるコンシューマ実装についてです。 (ご説明した、「必要な事前設定」という点も記載します。)
その前に、コンシューマ実装の全体を少し復習しておきましょう。(この説明も、かなり駆け足になってしまいましたので。。。)
REST クライアント (コンシューマ) の実装方法 (全体)
例えば、ASP.NET においても jQuery がサポートされているため、ASP.NET MVC などビュー内で閉じた実装をおこなう場合には、こうしたライブラリを組み合わせてコンシューマ (クライアント) を構築することもできます。
MSDN マガジン : jQuery によるリッチなクライアント スクリプトについて
http://msdn.microsoft.com/ja-jp/magazine/dd453033.aspx
以下では、こうした実装方法を除き、Microsoft が提供しているテクノロジ (特に .NET 周り) を使用して REST のコンシューマを作成する数々の方法について整理しましょう。
HttpClient (WCF REST Starter Kit) を使用した接続
この方法は見ていただくように大変扱いやすい手法ですが、まだ日本で動かしている人は少ないかもしれないので (実は下記で記載するように一部に日本語の問題があります)、手順詳細を記載します。(セッションで説明しなかった事前設定についても記載します。)
まず、このあと使用する WCF REST Starter Kit (Preview 2) の [Paste Xml As Types] メニューですが、ソースに一部不備があるため、英語版以外の Visual Studio ではこのメニュー出て来ないでしょう。ですので、現状は、以下の通り修正してから使用してください。(まだ Preview 版ですので、今後修正されるのをお待ちください。)
-
%ProgramFiles%\Microsoft WCF REST\WCF REST Starter Kit Preview 2\WCF REST Starter Kit Preview 2.zip を展開します (ソースコードが展開されます)
-
PasteXmlAsType プロジェクトが入っているため、このプロジェクトを Visual Studio で開いて、Connect.cs の 80 行目を下記の通り修正してください。(この PasteXmlAsType プロジェクトは、本来、カスタマイズ用に提供されています。)
[現在]
CommandBarControl pasteControl = (CommandBarControl)toolsPopup.CommandBar.Controls["Paste"];
[日本語用の Fix]
CommandBarControl pasteControl = (CommandBarControl)toolsPopup.CommandBar.Controls["貼り付け"];
ビルドをおこない、Visual Studio をいったんすべて終了し、コンパイルされた .dll と、プロジェクト内にある PasteXmlAsType.AddIn を%MyDocuments%\Visual Studio 2008\Addins に配置します。(Addins フォルダがない場合は、新規作成してください。)
Visual Studio を起動すると、[編集] メニューの中に [Paste Xml As Types] メニューが追加されているはずです。(もし追加されない場合は、念のため、devenv.exe /resetaddin <プロジェクト> で起動してみてください。)
では、本題の、HttpClient を使用したプログラミングに入っていきましょう。
まず、REST のサービスをあらかじめ作成しておきましょう。WCF でも、ADO.NET Data Services でも、PHP や Java で構築したサービスでも、インターネット上のサービスでも何でも構いません。
クライアントとして、今回は、コンソールアプリケーションのプロジェクトを新規作成して、以下を参照追加します。
以下の名前空間を追加します。(2 つ目も必ず入れておいてください)
using Microsoft.Http;
using System.Xml.Serialization;
接続先の REST のデータをブラウザなどで表示し (下図)、そのソース (XML) をコピーします。

そして、Visual Studio の上記クライアントプロジェクト上で、メニュー [Paste Xml As Type] を選択して貼り付けます。

この「貼り付け」をおこなうと、素敵なことに、XML のデータがシリアライズ可能なクラスのコードとしてソースコード上に貼り付けられます。
例えば、上図の XML の場合、生成されるソースコードは以下の通りになります。
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.4016")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class OrderItems
{
private OrderItemsOrderItem[] orderItemField;
[System.Xml.Serialization.XmlElementAttribute("OrderItem")]
public OrderItemsOrderItem[] OrderItem
{
get { return this.orderItemField; }
set { this.orderItemField = value; }
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.4016")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class OrderItemsOrderItem
{
private byte idField;
private string nameField;
private ushort valueField;
public byte id
{
get { return this.idField; }
set { this.idField = value; }
}
public string name
{
get { return this.nameField; }
set { this.nameField = value; }
}
public ushort value
{
get { return this.valueField; }
set { this.valueField = value; }
}
}
このコードですが、.xsd なしでコード生成されているため、ある程度予測に基づいて生成される点に注意してください。例えば、本来文字列を返している要素でも、たまたま int 型しか返していない場合には int 型に設定されているかもしれません。ですので、生成された型などをチェックし、必要に応じて修正しておきましょう。(要は、.xsd でクラス生成を実行する手間を省いてくれている、と考えるべきでしょう。)
さいごに、生成されたコードにあわせて、下記の通り Main のコードを作成してみましょう。
static void Main(string[] args)
{
HttpClient client = new HttpClient();
HttpResponseMessage res = client.Get(@"http://localhost:25631/Service1.svc/orders");
OrderItems items = res.Content.ReadAsXmlSerializable<OrderItems>();
foreach (OrderItemsOrderItem item in items.OrderItem)
{
Console.WriteLine(item.name);
}
Console.ReadLine();
}
このように、デシリアライズ (逆シリアライズ) の手間も省き、GET、POST などの Verb もメソッドとしてそのまま呼び出せるため、意味的にわかりやすくクライアントを構築することができます。
ADO.NET Data Services のサービスについても、同様の手法でアクセスできます。
以下はそのサンプルですが、Data Services が返すフィードの構造を多少理解しておく必要があるという点に注意しておいてください。(Data Services が返すフィードでは、データは Content の中に XML として含まれています。)
static void Main(string[] args)
{
HttpClient client = new HttpClient();
HttpResponseMessage res = client.Get(@"http://localhost:9583/MatsuDataService.svc/TypeAInvoice");
feed feeds = res.Content.ReadAsXmlSerializable<feed>();
foreach (feedEntry entry in feeds.entry)
{
Console.WriteLine(entry.content.properties.name);
}
Console.ReadLine();
}
上述した Json.NET が .NET 上で Json を扱える汎用的な (実装技術などに依存しない) 仕組みであるのに対して、この HttpClient は、POX など XML 形式のリソースを汎用的に扱える .NET の仕組みであると整理しておくと良いでしょう。
なお、HttpClient は、現在 (Preview 2 では)、残念ながら Silverlight に未対応ですが、今後の対応状況などについては Silverlight Web Services チームブログをウォッチしておくと良いでしょう。
Silverlight Web Service チームブログ :
http://blogs.msdn.com/silverlightws/
WCF REST Starter Kit は、セミナーでも説明したように Visual Studio 2010 で標準で含まれる予定です。(ただし、どの機能が含まれるかは現時点では未定です。)