スポンサーリンク

ASP.NET Web API クライアント編

サーバー編に続き、クライアント側についてもWCF Web APIの場合と同様にコンソールアプリケーションでクライアントライブラリの使用方法を見ていきます。

全体的な話

WCF Web APIではREST API向けのクライアントライブラリが用意されていましたが、ASP.NET APIでも同様にクライアントライブラリが用意されており、基本的にHttpClientクラスの各メソッドを通してこのライブラリを使用します。

MSDNライブラリ HttpClientクラス:
http://msdn.microsoft.com/ja-jp/library/system.net.http.httpclient(v=vs.110).aspx

HttpClientクラスのHTTPリクエストを実行する各メソッドが特徴的なのは、それらがすべて非同期な点です。ですのでGUIで使用する場合には特にこれらが別スレッドで動作すると意識してコードを書く必要があるでしょう。

ライブラリの追加

必要なライブラリを追加済ます。Web APIのクライアントに必要ライブラリは基本的にASP.NET MVC 4に含まれていますが、依存関係もそれなりにあるので、NuGetを使用した方が楽です。

GUIを使用する場合には下図のように”Microsoft ASP.NET Web API Client Libraries”を選択します。

パッケージマネージャのコンソールからインストールする場合には以下のようにインストールします。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
PM> Install-Package Microsoft.AspNet.WebApi.Client
PM> Install-Package Microsoft.AspNet.WebApi.Client
PM> Install-Package Microsoft.AspNet.WebApi.Client

using句の追加

Program.csを開いて以下のコードを追加します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Formatting;
using System.Net.Http; using System.Net.Http.Headers; using System.Net.Http.Formatting;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Formatting;

データクラスの追加

クライアントサイドで使用するためのデータクラスを追加します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//ヒーローのクラスを作成
public class Hero
{
public int Id { get; set; }
public string Name { get; set; }
}
//ヒーローのクラスを作成 public class Hero { public int Id { get; set; } public string Name { get; set; } }
//ヒーローのクラスを作成
public class Hero
{
    public int Id { get; set; }
    public string Name { get; set; }
}

データ格納用のクラスのフィールド名と型はJSONと同じ名前、データ変更可能な型にしておく必要があります。JSONは数値に関してJavaScriptの仕様通り整数、浮動小数点を区別しないので、仕様を良く確認しましょう。

HTTP Getリクエスト

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//Getコマンドの実行
static async void ListAllHeroes() {
//HttpClientのインスタンスを作成する。
var client = new HttpClient();
//↓ ASP.NET Web APIのライブラリではHTTPヘッダでJSONの指定がいらない
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//GETコマンドを非同期で実行する。
HttpResponseMessage response = await client.GetAsync("http://localhost:35833/api/heroes");
if (response.IsSuccessStatusCode) {
Console.WriteLine("--Get Result--");
//コンテンツの取得を非同期で実行
var heroes = await response.Content.ReadAsAsync<list>();
foreach (var hero in heroes) {
Console.WriteLine("{0}\t: {1}", hero.Id, hero.Name);
}
id = heroes.OrderByDescending(h => h.Id).First().Id;
}
client.Dispose();
}</list
//Getコマンドの実行 static async void ListAllHeroes() { //HttpClientのインスタンスを作成する。 var client = new HttpClient(); //↓ ASP.NET Web APIのライブラリではHTTPヘッダでJSONの指定がいらない //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //GETコマンドを非同期で実行する。 HttpResponseMessage response = await client.GetAsync("http://localhost:35833/api/heroes"); if (response.IsSuccessStatusCode) { Console.WriteLine("--Get Result--"); //コンテンツの取得を非同期で実行 var heroes = await response.Content.ReadAsAsync<list>(); foreach (var hero in heroes) { Console.WriteLine("{0}\t: {1}", hero.Id, hero.Name); } id = heroes.OrderByDescending(h => h.Id).First().Id; } client.Dispose(); }</list
//Getコマンドの実行
static async void ListAllHeroes() {
    //HttpClientのインスタンスを作成する。
    var client = new HttpClient();
    //↓ ASP.NET Web APIのライブラリではHTTPヘッダでJSONの指定がいらない
    //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    //GETコマンドを非同期で実行する。
    HttpResponseMessage response = await client.GetAsync("http://localhost:35833/api/heroes");
    if (response.IsSuccessStatusCode) {
        Console.WriteLine("--Get Result--");
        //コンテンツの取得を非同期で実行
        var heroes = await response.Content.ReadAsAsync<list>();
        foreach (var hero in heroes) {
            Console.WriteLine("{0}\t: {1}", hero.Id, hero.Name);
        }
        id = heroes.OrderByDescending(h => h.Id).First().Id;
    }
    client.Dispose();
}</list

ヒーローのリストをサービスから取得して、コンソールに表示させます。

HttpClientクラスのGetAsyncメソッドがGetリクエストを行うメソッドで、非同期で実行されます。(つまりTaskが返されます)

WCF Web APIからの違いは実際にほとんどありません。しかし、C# 5.0のasyc/awaitによってコードがだいぶすっきりして、手続き言語的に見やすいコードになっていますいます。

HTTP POSTリクエスト

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//POSTコマンドの実行
static async void AddHero() {
var client = new HttpClient();
string name = "仮面ライダーアギト";
//POSTコマンドをJSONを指定して非同期で実行
HttpResponseMessage response = await client.PostAsJsonAsync("http://localhost:35833/api/heroes", name);
Console.WriteLine("--POST resut--");
Console.WriteLine("Status: {0}", (int)response.StatusCode);
if (response.IsSuccessStatusCode) {
string m = await response.Content.ReadAsStringAsync();
Console.WriteLine(m);
}
client.Dispose();
}
//POSTコマンドの実行 static async void AddHero() { var client = new HttpClient(); string name = "仮面ライダーアギト"; //POSTコマンドをJSONを指定して非同期で実行 HttpResponseMessage response = await client.PostAsJsonAsync("http://localhost:35833/api/heroes", name); Console.WriteLine("--POST resut--"); Console.WriteLine("Status: {0}", (int)response.StatusCode); if (response.IsSuccessStatusCode) { string m = await response.Content.ReadAsStringAsync(); Console.WriteLine(m); } client.Dispose(); }
//POSTコマンドの実行
static async void AddHero() {
    var client = new HttpClient();
    string name = "仮面ライダーアギト";
    //POSTコマンドをJSONを指定して非同期で実行
    HttpResponseMessage response = await client.PostAsJsonAsync("http://localhost:35833/api/heroes", name);
    Console.WriteLine("--POST resut--");
    Console.WriteLine("Status: {0}", (int)response.StatusCode);
    if (response.IsSuccessStatusCode) {
        string m = await response.Content.ReadAsStringAsync();
        Console.WriteLine(m);
    }
    client.Dispose();
}

サービスにヒーローを追加し、応答のステータスコードと結果の内容をコンソールに表示させます。

6行目にあるHttpClietクラスのPostAsJsonAsync(T)メソッドでPOSTしています。このメソッドはJSONでPOSTするようにヘッダを調整し、データをJSONデシリアライズします。

HTTP DELETEリクエスト

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//DELETEコマンドの実行
static async void DeleteHero(int id) {
var client = new HttpClient();
//DELETEコマンドを非同期で実行
Console.WriteLine("== Delete Hero ID : {0} ==", id);
var url = string.Format("http://localhost:35833/api/heroes?id={0}", id);
var response = await client.DeleteAsync(url);
Console.WriteLine("--DELETE Result Status Code--");
Console.WriteLine("Status: {0}", (int)response.StatusCode);
client.Dispose();
}
//DELETEコマンドの実行 static async void DeleteHero(int id) { var client = new HttpClient(); //DELETEコマンドを非同期で実行 Console.WriteLine("== Delete Hero ID : {0} ==", id); var url = string.Format("http://localhost:35833/api/heroes?id={0}", id); var response = await client.DeleteAsync(url); Console.WriteLine("--DELETE Result Status Code--"); Console.WriteLine("Status: {0}", (int)response.StatusCode); client.Dispose(); }
//DELETEコマンドの実行
static async void DeleteHero(int id) {
    var client = new HttpClient();
    //DELETEコマンドを非同期で実行
    Console.WriteLine("== Delete Hero ID : {0} ==", id);
    var url = string.Format("http://localhost:35833/api/heroes?id={0}", id);
    var response = await client.DeleteAsync(url);
    Console.WriteLine("--DELETE Result Status Code--");
    Console.WriteLine("Status: {0}", (int)response.StatusCode);
    client.Dispose();
}

引数idで指定されたヒーローを削除します。

HttpClientクラスのDeleteAsyncメソッドがDELETEを発行します。

HTTP PUTリクエスト

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//PUTコマンドの実行
static async void UpdateHero() {
string url = "http://localhost:35833/api/heroes?id=2";
string name = "モロボシダン";
var client = new HttpClient();
//PUTコマンドをJSONを指定して非同期で実行
var response = await client.PutAsJsonAsync(url, name);
Console.WriteLine("-- PUT Result Status Code --");
Console.WriteLine("Status: {0}", (int)response.StatusCode);
if (response.IsSuccessStatusCode) {
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine("-- PUT result --");
Console.WriteLine(content);
}
client.Dispose();
}
//PUTコマンドの実行 static async void UpdateHero() { string url = "http://localhost:35833/api/heroes?id=2"; string name = "モロボシダン"; var client = new HttpClient(); //PUTコマンドをJSONを指定して非同期で実行 var response = await client.PutAsJsonAsync(url, name); Console.WriteLine("-- PUT Result Status Code --"); Console.WriteLine("Status: {0}", (int)response.StatusCode); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); Console.WriteLine("-- PUT result --"); Console.WriteLine(content); } client.Dispose(); }
//PUTコマンドの実行
static async void UpdateHero() {
    string url = "http://localhost:35833/api/heroes?id=2";
    string name = "モロボシダン";
    var client = new HttpClient();
    //PUTコマンドをJSONを指定して非同期で実行
    var response = await client.PutAsJsonAsync(url, name);
    Console.WriteLine("-- PUT Result Status Code --");
    Console.WriteLine("Status: {0}", (int)response.StatusCode);
    if (response.IsSuccessStatusCode) {
        var content = await response.Content.ReadAsStringAsync();
        Console.WriteLine("-- PUT result --");
        Console.WriteLine(content);
    }
    client.Dispose();
}

Idが2のヒーローの名前を変更しています。

7行目のPutAsJsonAsyncメソッドでPUTを発行しています。これも非同期です。

まとめ

C# 5.0の非同期関連機能の向上でコードがだいぶすっきりしています。手続き的な書き方に慣れている方にとってはこちらの方が見やすいと感じるでしょう。
クライアントに関してはWCF Web APIからの大きな違いはありませんが、必ずしもそのままというわけでも無いので、良くドキュメントを読んでおきましょう。また、JSON/XMLのシリアリアライズとヘッダ設定を行ってくれるPUT/POST用のメソッドが用意されています。

まずは製品版のクラスライブラリに入ってきたことが一番大きいと思いますので、いろいろと縛りがある人でも使用しやすくなってきたと思いますので、皆さんも是非使ってみて下さい。

コードの公開

サーバー編と同じくGitHubで全体のコードを公開しています。

GitHub - ishisaka/superhero2: SuperHero2
SuperHero2. Contribute to ishisaka/superhero2 development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました