ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

OWIN で Nancy を使うときに必要な追加実装

今更感がありますが、OWIN で Nancy を使って Web API を実装してみました。その際に、少しハマったことがありますので、共有しておきます。

プロジェクトの作成

空の WebApplication プロジェクトに NuGet パッケージをインストールします。

  • Install-Package Nancy.Owin
  • Install-package Microsoft.Owin.Host.SystemWeb
  • Install-Package Nancy.Serialization.JsonNet

最後のパッケージは必須ではありませんが、Json.NET を使いたかったので、追加しています。このパッケージを追加しなければ、Nancy 独自の Json シリアライザが使われます。

Module の実装

"/api/person" の URL にリクエストすると、Json 形式の Person オブジェクトを返す Web API を実装します。

#PersonModule.cs
using Nancy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Nancy.ModelBinding;
 
namespace WebApplication2
{
    public class Person
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
 
    public class PersonModule : NancyModule
    {
        public PersonModule()
            : base("/api/person")
        {
            Get["/"] = _ =>
            {
                var result = new List<Person>();
                result.Add(new Person { ID = 10, Name = "Jack Wilshere" });
                result.Add(new Person { ID = 16, Name = "Aaron Ramsey" });
                return Response.AsJson(result);
            };
 
            Get["/{id}"] = parameters =>
            {
                var person = new Person { ID = parameters.id, Name = "Aaron Ramsey" };
                return Response.AsJson(person);
            };
 
            Post["/"] = _ =>
            {
                var person = this.Bind<Person>();
                return Response.AsJson(person);
            };
 
            Put["/{id}"] = parameters =>
            {
                var person = this.Bind<Person>();
                return Response.AsJson(person);
            };
 
            Delete["/{id}"] = parameters =>
            {
                var id = parameters.id;
                return HttpStatusCode.OK;
            };
        }
    }
}

OWIN パイプラインに Nancy を追加

Startup クラスで、OWIN パイプラインに Nancy を追加します。

#Startup.cs
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
 
[assembly: OwinStartup(typeof(WebApplication2.Startup))]
 
namespace WebApplication2
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseNancy();
        }
    }
}

ここまでの実装で動作確認すると、GET と POST は成功するのですが、PUT と DELETE で 404 エラーが返されてしまいます。

GitHub の Wiki をよく読むと、OWIN 上で Nancy を動かすには、追加実装が必要でした。

  • Startup クラスに、Microsoft.Owin.Extensions 名前空間の UseStageMarker メソッドを追加
  • Web.config に、runAllManagedModulesForAllRequests を追加
#Startup.cs
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseNancy();
        app.UseStageMarker(PipelineStage.MapHandler);
    }
}
#Web.config
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

上記の実装を追加することで、PUT と DELETE のリクエストが成功します。