WCF Web API その2 クライアントコード

※ご注意
WCF Web APIはマイクロソフトにより現在開発はキャンセルされ、ASP.NET MVC 4のASP.NET Web APIとして制作・公開されています。

.NET Framework/ASP.NETでRESTfulなAPI構築を目的に記事を探されている方は是非以下のリンクからASP.NET Web APIについてご確認下さい。
http://opcdiary.net/?page_id=5981


WCF Web APIその2として、クライアントサイドでのWeb APIの使用方法です。

WCF Web APIには昨日投稿したサーバーサイドでのライブラリの他に、クライアントサイドで使用するライブラリも用意されています。またWeb APIとなってからの特徴として、各HTTPコマンドの実行が.NET 4のTaskライブラリを使用した非同期実行になっていることが上げられます。

コンソールアプリケーションプロジェクトの作成

新規、もしくは昨日のソリューションに追加する形でWindowsコンソールアプリケーションのプロジェクトを作成します。

プロジェクトファイルを右クリックしてプロパティを選択し、表示させます。

アプリケーションタグを開いて、対象のフレームワークとして「.NET Framework 4」もしくは「.NET Framework 4.02」を選択します。つまり、クライアントプロファイルは選択せずに、フルセットの.NET Frameworkを選択します。(下図参照)

NuGetを利用して、サーバー側のときと同じくWebApi.Allを追加します。

using句の追加

Program.csを開いて、以下のusing句を追加します。

//以下を追記
using System.Threading.Tasks;

using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Net.Http;

データクラスの追加

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

public class Hero 
{
    public int HeroId { get; set; }
    public string Name { get; set; }
}

HTTP GETリクエスト

/// 
/// GETコマンドの実行
/// 
static void ListAllHeroes() {
    //HttpClientのインスタンスを作成する。
    var client = new HttpClient();
    //JSONでデータを取得するようにHTTPヘッダを設定する。
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    //GETコマンドを非同期で実行する。
    client.GetAsync("http://localhost:9000/api/heroes").ContinueWith(r => {
        if (r.Result.IsSuccessStatusCode) {
            //非同期でメッセージを取得する。
            r.Result.Content.ReadAsAsync>().ContinueWith(l => {
                Console.WriteLine("--GET result--");
                l.Result.ForEach(h => {
                    Console.WriteLine("{0} : {1}", h.HeroId, h.Name);
                });
                id = l.Result.OrderByDescending(h => h.HeroId).First().HeroId;
            });
        }
                
    }).Wait();
    client.Dispose();
}

ヒーローのリストをサービスから取得して、コンソールに表示させます。コードの説明についてはコード内のコメントを参考にしてください。
WCF RESTと決定的に違うのはGETもその先の結果の取得も非同期に行われる点で、具体的な結果の使用は継続を利用して記述します。

HTTP POSTリクエストの送信

/// 
/// POSTコマンドの実行
/// 
static void AddHeroes() {
    //HttpClientのインスタンスを作成する。
    var client = new HttpClient();
    //データフォーマットとしてJSONを指定する。
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    //追加するデータの作成
    List heroes = new List() { new Hero() {Name = "Bad Man"} };
    //POSTコマンドの非同期実行
    //JSONにデータを変換するように指定している。
    client.PostAsync("http://localhost:9000/api/heroes", 
        new ObjectContent>(heroes, JsonMediaTypeFormatter.DefaultMediaType)).ContinueWith(r => {
            //ステータスコードの表示
            Console.WriteLine("-- POST Result Status Code --");
            Console.WriteLine("Status: {0}", (int)r.Result.StatusCode);
            if (r.Result.IsSuccessStatusCode) {
                //リザルトの内容を表示
                r.Result.Content.ReadAsStringAsync().ContinueWith(m => {
                    Console.WriteLine("-- POST result --");
                    Console.WriteLine(m.Result);
                });
            }
    }).Wait();
    client.Dispose();
}

サービスにヒーローを追加し、応答のステータスコードと結果の内容をコンソールに表示させます。コードの説明についてはコード内のコメントを参考にしてください。

このコードで(14行目)使用しているObjectContent(T)はCLRのオブジェクトをシリアライズするために使用しています。また2番目の引数でメディアタイプを指定することができ、このコードではJSONへのシリアライズを指定しています。

HTTP DELETEリクエスト

/// 
/// DELETEコマンドの実行
/// 
/// 削除するヒーローのID番号
static void DeleteHero(int id) {
    var client = new HttpClient();
    //DELETEコマンドの非同期実行
    Console.WriteLine("== Delete Hero ID : {0} ==", id);
    client.DeleteAsync(String.Format("http://localhost:9000/api/heroes/{0}", id)).ContinueWith(r => {
        //ステータスコードの表示
        Console.WriteLine("--DELETE Result Status Code--");
        Console.WriteLine("Status: {0}", (int)r.Result.StatusCode);
    }).Wait();
    client.Dispose();
}

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

HTTP PUTリクエスト


static void UpdateHero() {
    //変更するデータの作成
    var hero = new Hero() { HeroId = 2, Name = "中の人などいない" };
    var client = new HttpClient();
    //データフォーマットとしてJSONを指定する。
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    //PUTコマンドの非同期実行
    client.PutAsync("http://localhost:9000/api/heroes", 
        new ObjectContent(hero, JsonMediaTypeFormatter.DefaultMediaType)).ContinueWith(r => {
            //ステータスコードの表示
            Console.WriteLine("-- PUT Result Status Code --");
            Console.WriteLine("Status: {0}", (int)r.Result.StatusCode);
            if (r.Result.IsSuccessStatusCode) {
                //リザルトの内容を表示
                r.Result.Content.ReadAsStringAsync().ContinueWith(m => {
                    Console.WriteLine("-- PUT result --");
                    Console.WriteLine(m.Result);
                });
            }
    }).Wait();
    client.Dispose();
}

HeroIdが2のヒーロー名を変更します。

全体コード


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//以下を追記
using System.Threading.Tasks;

using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Net.Http;

namespace HeroClient
{
    
    /// 
    /// ヒーロー
    /// 
    public class Hero 
    {
        public int HeroId { get; set; }
        public string Name { get; set; }
    }
    
    
    /// 
    /// WCF Web APIクライアントのサンプル。
    /// 
    class Program
    {
        static int id = 0;
        
        static void Main(string[] args) {
            Console.WriteLine("GETコマンドの実行");
            ListAllHeroes();
            Console.WriteLine("POSTコマンドの実行");
            AddHeroes();
            Console.WriteLine("DELETEコマンドの実行");
            DeleteHero(id);
            Console.WriteLine("PUTコマンドの実行");
            UpdateHero();
            Console.Read();
        }

        /// 
        /// GETコマンドの実行
        /// 
        static void ListAllHeroes() {
            //HttpClientのインスタンスを作成する。
            var client = new HttpClient();
            //JSONでデータを取得するようにHTTPヘッダを設定する。
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            //GETコマンドを非同期で実行する。
            client.GetAsync("http://localhost:9000/api/heroes").ContinueWith(r => {
                if (r.Result.IsSuccessStatusCode) {
                    //非同期でメッセージを取得する。
                    r.Result.Content.ReadAsAsync>().ContinueWith(l => {
                        Console.WriteLine("--GET result--");
                        l.Result.ForEach(h => {
                            Console.WriteLine("{0} : {1}", h.HeroId, h.Name);
                        });
                        id = l.Result.OrderByDescending(h => h.HeroId).First().HeroId;
                    });
                }
                
            }).Wait();
            client.Dispose();
        }

        /// 
        /// POSTコマンドの実行
        /// 
        static void AddHeroes() {
            //HttpClientのインスタンスを作成する。
            var client = new HttpClient();
            //データフォーマットとしてJSONを指定する。
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            //追加するデータの作成
            List heroes = new List() { new Hero() {Name = "Bad Man"} };
            //POSTコマンドの非同期実行
            //JSONにデータを変換するように指定している。
            client.PostAsync("http://localhost:9000/api/heroes", 
                new ObjectContent>(heroes, JsonMediaTypeFormatter.DefaultMediaType)).ContinueWith(r => {
                    //ステータスコードの表示
                    Console.WriteLine("-- POST Result Status Code --");
                    Console.WriteLine("Status: {0}", (int)r.Result.StatusCode);
                    if (r.Result.IsSuccessStatusCode) {
                        //リザルトの内容を表示
                        r.Result.Content.ReadAsStringAsync().ContinueWith(m => {
                            Console.WriteLine("-- POST result --");
                            Console.WriteLine(m.Result);
                        });
                    }
            }).Wait();
            client.Dispose();
        }

        /// 
        /// DELETEコマンドの実行
        /// 
        /// 削除するヒーローのID番号
        static void DeleteHero(int id) {
            var client = new HttpClient();
            //DELETEコマンドの非同期実行
            Console.WriteLine("== Delete Hero ID : {0} ==", id);
            client.DeleteAsync(String.Format("http://localhost:9000/api/heroes/{0}", id)).ContinueWith(r => {
                //ステータスコードの表示
                Console.WriteLine("--DELETE Result Status Code--");
                Console.WriteLine("Status: {0}", (int)r.Result.StatusCode);
            }).Wait();
            client.Dispose();
        }

        /// 
        /// PUTコマンドの実行
        /// 
        static void UpdateHero() {
            //変更するデータの作成
            var hero = new Hero() { HeroId = 2, Name = "中の人などいない" };
            var client = new HttpClient();
            //データフォーマットとしてJSONを指定する。
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            //PUTコマンドの非同期実行
            client.PutAsync("http://localhost:9000/api/heroes", 
                new ObjectContent(hero, JsonMediaTypeFormatter.DefaultMediaType)).ContinueWith(r => {
                    //ステータスコードの表示
                    Console.WriteLine("-- PUT Result Status Code --");
                    Console.WriteLine("Status: {0}", (int)r.Result.StatusCode);
                    if (r.Result.IsSuccessStatusCode) {
                        //リザルトの内容を表示
                        r.Result.Content.ReadAsStringAsync().ContinueWith(m => {
                            Console.WriteLine("-- PUT result --");
                            Console.WriteLine(m.Result);
                        });
                    }
            }).Wait();
            client.Dispose();
        }
    }
}

ファイル名:Program.cs

全体ダウンロード

2 thoughts on “WCF Web API その2 クライアントコード”

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください