かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

ASP.NET WebAPIをセルフホストして…

ASP.NET WebAPIってexeとかでセルフホスト出来るんですね!しかも簡単に。ということでやってみようと思います。VS2012を管理者権限で実行して、コンソールアプリケーションを新規作成します。

参照設定にSystem.Net.HttpとSystem.Web.HttpとSystem.Web.Http.SelfHostというアセンブリを追加します。そして、NuGetでJson.NETをインストールします。

参照設定が完了したので、Web APIのコントローラを作ります。今回は、セルフホストを試すことが目的なので、シンプルなGETに応答するだけのコントローラにしました。

// APIから返すための適当なデータ
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// とりあえず、単純なGETリクエストに応答するだけのシンプルなコントローラ
public class PeopleController : ApiController
{
    public IEnumerable<Person> Get()
    {
        return Enumerable.Range(1, 10).Select(i => new Person { Id = i, Name = "田中 太郎" + i });
    }
}

あとは、MainメソッドでHttpSelfHostConfigurationクラスとHttpSelfHostServerクラスを使ってルートの設定と、サーバーの立ち上げのコードを書いてやればOKです。

// セルフホスト用の設定
var config = new HttpSelfHostConfiguration("http://localhost:8080/");
// とりあえず、WebAPIのお約束的なルートの設定
config.Routes.MapHttpRoute(
    "DefaultApi",
    "{controller}/{id}",
    new { id = RouteParameter.Optional });

// サーバー起動!!
using (var server = new HttpSelfHostServer(config))
{
    server.OpenAsync().Wait();
    Console.WriteLine("起動完了");
    Console.Read();
}

HttpServerを起動するためのメソッドが非同期版しかないあたりに時代を感じます。

Fiddler2でテスト

Fiddlerを使ってAPIを叩いてみます。Fiddlerを起動して、Composerでhttp://localhost:8080/PeopleにGETリクエストを飛ばします。

Executeボタンを押してリクエストを飛ばしたらInspectorsでリクエストとレスポンスの中身を確認します。ばっちりJSONが取れてますね。

コード全体

コード全体でもこんなもんです。シンプルにREST APIを作れますね。

namespace SelfHostSample
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http;
    using System.Web.Http.SelfHost;

    class Program
    {
        static void Main(string[] args)
        {
            // セルフホスト用の設定
            var config = new HttpSelfHostConfiguration("http://localhost:8080/");
            // とりあえず、WebAPIのお約束的なルートの設定
            config.Routes.MapHttpRoute(
                "DefaultApi",
                "{controller}/{id}",
                new { id = RouteParameter.Optional });

            // サーバー起動!!
            using (var server = new HttpSelfHostServer(config))
            {
                server.OpenAsync().Wait();
                Console.WriteLine("起動完了");
                Console.Read();
            }
        }
    }

    // APIから返すための適当なデータ
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    // とりあえず、単純なGETリクエストに応答するだけのシンプルなコントローラ
    public class PeopleController : ApiController
    {
        public IEnumerable<Person> Get()
        {
            return Enumerable.Range(1, 10).Select(i => new Person { Id = i, Name = "田中 太郎" + i });
        }
    }
}

Windows ストア アプリから呼び出し

ついでなんで、Windows ストア アプリから呼び出してみようと思います。ストアに公開するアプリではあり得ませんけどね…。企業内アプリなら、こういう風にするのもありなのかな。

ソリューションにWindows ストア アプリを追加してNuGetからリリース前パッケージの中のMicrosoft ASP.NET Web API Client Librariesを追加します。別に追加しなくても、HttpClientクラス使って呼べるのですが、こいつを追加すると何かと楽なので…。

画面にGridViewを置いて、Nameプロパティを表示するテンプレートを適当に作ります。GridViewの詳しいところについては以下を参照してみてください。

そして、ページのOnNavigateToをオーバーライドして以下のコードを書きます。

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    var client = new HttpClient
    {
        BaseAddress = new Uri("http://localhost:8080/")
    };
    using (var result = await client.GetAsync("People"))
    {
        if (!result.IsSuccessStatusCode) {
            return;
        }
        // ReadAsAsyncが便利!!
        var people = await result.Content.ReadAsAsync<IEnumerable<Person>>();
        this.gridView.ItemsSource = new ObservableCollection<Person>(people);
    }
}

ReadAsAsyncメソッドが便利すぎてやばいですね。簡単にHttpClientの結果をオブジェクトにしてくれる。

実行して結果確認

さて、実行するまえにソリューションのプロパティからセルフホストのプロジェクトを起動してWindows ストア アプリを起動するように構成します。

実行してみると、ちゃんとデータが取れてますね!!

まとめ

セルフホスト+クライアントアプリで、色々楽しいアプリがつくれそうな気がします。今回はセルフホストですがAzure上とかにWeb APIを置くような使い方でも簡単お手軽にデータのやり取りが出来ますというか普通はこっちですね…!!

プロジェクトは、以下からDLできます。
セルフホストWeb APIをWindows ストア アプリから呼び出すサンプル