今更感がありますが、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 のリクエストが成功します。