ASP.Net Core で Nancy する 


ASP.Net Core で Nancy を使ってみる。

### 開発環境
Windows 10 Pro
Visual Studio 2015 Community
.NET Framework 4.6.1

## Nancy とは
[Nancy](http://nancyfx.org/) は Ruby の [Sinatra](http://www.sinatrarb.com/) に影響を受けた非MS製の軽量なASP.NET フレームワークです。

## プロジェクトの作成
まず、プロジェクトの作成から

[新しいプロジェクト] - [Web] - [APS.NET Core Web Application(.NET Framework)] を選択して
テンプレートは空を選択します。

## パッケージのインストール

作成したプロジェクトに必要なパッケージを NuGet からインストールします。  

今回は Nancy.Owin を使います。  
また Owin を使うので Microsoft.AspNetCore.Owin も一緒にインストールします。

Install-Package Nancy.Owin  
Install-Package Microsoft.AspNetCore.Owin -Pre

## Startup.cs の変更

Startup.cs を Owin と Nancy を使うように変更します。

```csharp:Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Nancy.Owin;

namespace WebApplication1
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            app.UseOwin(pipeline => pipeline.UseNancy());
        }
    }
}
```

## モジュールを定義する

とりあえず、モジュール を定義して Hello World してみます。
Nancy.NancyModule を継承したクラスを作成して、GETリクエストされたら "Hello World!" を返すようにルートを定義します。

```csharp:SampleModule.cs
using Nancy;

namespace WebApplication1
{
    public class SampleModule : NancyModule
    {
        public SampleModule()
        {
            Get["/"] = _ => "Hello World!";
        }
    }
}
```

実行するとブラウザ上に "Hello World!" が表示されると思います。

## JSON を返す

Nancy で JSON を返す場合は Nancy.Response.AsJson() メソッドを呼んであげればOKです。
試しに ID と Name をプロパティに持った Person クラスを定義して、Module にスタブのリストを用意して Get されたら JSON に変換して返してみます。

```csharp:SampleModule.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Nancy;

namespace WebApplication1
{
    class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class SampleModule : NancyModule
    {
        //TODO: スタブ
        List<Person> _values = new List<Person>
        {
            new Person { Id = 1, Name = "Francis" },
            new Person { Id = 2, Name = "Nancy" },
        };

        public SampleModule()
        {
            Get["/"] = _ => View["index"];//"Hello World!";

            // JSON に変換して返す
            Get["/api/person"] = _ => Response.AsJson(_values);

            // 指定された ID の Person を JSON に変換して返す
            Get["/api/person/{id}"] = p => Response.AsJson(
                _values
                .Where(x => x.Id == p.id)
                .FirstOrDefault()
                );
        }
    }
}
```

/api/person を実行すると以下の JSON が取得できると思います。

```json
[{"id":1,"name":"Francis"},{"id":2,"name":"Nancy"}]
```

/api/person/1 を実行してみます。

```json
{"id":1,"name":"Francis"}
```

指定された id = 1 のものが返ってきました。

### JSONP を返す

Nancy は JSONP もいける口らしいので試してみます。
JSON を返すパスに対してクエリパラメータに callback を付けてあげればOKです。

/api/person/?callback=test を実行すると

```javascript
test([{"id":1,"name":"Francis"},{"id":2,"name":"Nancy"}]);
```

という javascript が返却されます。