ASP.Net Core で Nancy する その２


[前回](http://qiita.com/t-koyama/items/2cb9682967092f55abfd)は ASP.NET Core で Nancy するためのプロジェクト作成とかGETリクエストしたら JSON とか JSONP を返すとかやりました。

今回は GETリクエストされたら View を返してみます。

## View を作成
wwwroot フォルダに index.html を作成します。

```html:index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>ASP.Net Core で Nancy する</title>
</head>
<body>
    Hello World!
</body>
</html>
```

次はモジュールで 前回作成した "Hello World!" してたやつを View を返すように変更します。

```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()
        {
            // View を返す
            Get["/"] = _ => View["index"];

            // 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()
                );
        }
    }
}
```

この状態で実行すると HTTP 500 で内部サーバエラーになります。デフォルトの状態だとルートパスがプロジェクトの実行ディレクトリになっていますが ASP.NET Core のプロジェクトではビルド時にHTMLファイルがここに出力されないのでそんなファイルは見つからないよと言われてしまいます。今回は wwwroot フォルダ下を見てもらいたいのでルートパスを変更します。

## ルートパスを変更する

まずは Nancy.IRootPathProvider インターフェイスを継承したクラスを作成します。

```csharp:RootPathProvider.cs
using Nancy;
using System;
using System.IO;

namespace WebApplication1
{
    class RootPathProvider : IRootPathProvider
    {
        public string GetRootPath()
        {
            return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\..\wwwroot\");
        }
    }
}
```

GetRootPath() メソッドで wwwroot フォルダを ルートパスとして返すようにしています。

次は Nancy.DefaultNancyBootstrapper クラスを継承したクラスを作成します。

```csharp:BootStrapper.cs
using Nancy;

namespace WebApplication1
{
    public class BootStrapper : DefaultNancyBootstrapper
    {
        protected override IRootPathProvider RootPathProvider
        {
            get { return new RootPathProvider(); }
        }
    }
}
```

RootPathProvider プロパティをオーバーライドして先ほど作成した RootPathProvider のインスタンスを返すようにします。

最後に Startup.cs の UseNancy しているところで作成した Bootstrapperを使うようにします。

```csharp:Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Nancy;
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(options => options.Bootstrapper = new BootStrapper()));
        }
    }
}
```

実行すると 先ほど作成したHTMLファイルの内容が表示されます。