ASP.NET Coreで静的コンテンツを提供する


## はじめに

今回は、HTML、CSS、画像、および、JavaScript などの静的ファイルはアプリケーションで扱う方法について調べてみました。
扱わないアプリなんてほぼ皆無だと思いますので、これは必須な知識のはず。

なお、環境を.NET Core 3.1に上げました。

## wwwroot内のファイルの場合


Startup.csの`Configure`メソッドにある、UseStaticFilesメソッドの呼び出しをすることで、wwwrootフォルダ以下にあるファイルを提供することができます。

```c#
app.UseStaticFiles();
```

view側で、ここにあるファイルにアクセスする際は、以下のような記述をします。

```html
<img src="~/images/sample.jpeg" alt="サンプル画像" />
```



`~/` が `wwwroot` を指します。ですからこれで、wwwroot/images/example.jpg を参照することになります。


## wwwroot外のファイルの場合

wwwroot内のファイルに加えて、別のフォルダ内の静的ファイルも提供したい場合は、Configureメソッドで、以下のようなコードを書きます。

```cs
  app.UseStaticFiles(); 

  app.UseStaticFiles(new StaticFileOptions
  {
      FileProvider = new PhysicalFileProvider(
          Path.Combine(Directory.GetCurrentDirectory(), "StaticFiles")),
        RequestPath = "/StaticFiles"
  });
```

上の例は、StaticFiles フォルダの例です。最初の "StaticFiles" は、物理フォルダの名前で、2番目の"/StaticFiles"は、ルーティングのパスを指定します。
ここでは同じ名前にしましたが、別の名前でもかまいません。

では、試してみます。プロジェクトの直下に、StaticFiles フォルダを作成し、その下に Images フォルダを作成します。
このフォルダの下に、任意の画像ファイルを入れます。

チュートリアルで作成したindex.cshtml に以下のタグを追加します。

```html
<img src="/staticfiles/images/sample.jpeg" alt="サンプル画像" />
```

実行してみます。
無事、画像が表示されました。

![スクリーンショット 2019-12-19 21.18.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29415/069fbe5c-415c-5636-1262-78dec6e3bf4f.png "スクリーンショット 2019-12-19 21.18.16.png")


試しに、

```c#
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "StaticFiles")),
    RequestPath = "/StaticFiles"
});
```

の部分をコメントアウトしてみます。

画像は表示されません。staticsfiles フォルダにはアクセスできないのが確認できます。


![スクリーンショット 2019-12-19 21.19.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29415/6cad1510-a45b-fa8f-a9b5-a4b5ffcd9650.png "スクリーンショット 2019-12-19 21.19.56.png")



## HTTP 応答ヘッダーの設定

まず、以下のコマンドで、Microsoft.AspNetCore.Httpパッケージをインストールします。

```
dotnet add package Microsoft.AspNetCore.Http --version 2.2.2
```


次に、StartUp.cs の`Configure`メソッドを書き換えます。

```c#
using Microsoft.AspNetCore.Http;

…

	var  cachePeriod = 600;
	app.UseStaticFiles(new StaticFileOptions
	{
	    OnPrepareResponse = ctx =>
	    {
	        ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={cachePeriod}");
	    }
	});
```

こうすると、Response Headerに`Cache-Control`の値を設定できます。この例では、600秒間キャッシュを有効にしています。


ブラウザで確認すると、確かにCache-Control が設定されているのが確認できます。

![スクリーンショット 2019-12-21 13.32.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29415/22921a7d-223e-b0e9-e9c5-366abf42f2ef.png "スクリーンショット 2019-12-21 13.32.36.png")

上の例では、`PhysicalFileProvider`での指定がないので、`wwwroot`配下のファイルに限定されます。

## ディレクトリ参照の有効化

通常のWebアプリではこの機能は不要ですが、時には、ディレクトリの参照を有効にしたい場合があります。

Startup.Configure で `UseDirectoryBrowser` メソッドを呼び出すと、ディレクトリの参照を有効にできます。

```cs
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "myimages")),
    RequestPath = "/images"
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "myimages")),
    RequestPath = "/images"
});
```

上のコードでは、`app.UseStaticFiles `で、/wwwroot/myimages フォルダ配下の静的ファイルを提供し、`app.UseDirectoryBrowser`で、ディレクトリの参照を有効化することで、ブラウザ上でフィルを閲覧できるようになります。
"/images"がルーティングのパスを指定です。

以下、ブラウザの表示例です。

![スクリーンショット 2019-12-21 14.15.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29415/64bf791b-a2a6-1363-5508-e89e6607ba97.png "スクリーンショット 2019-12-21 14.15.08.png")