静的ファイルを wwwroot 以外のフォルダに配置する
現在表示しているページは選択中の表示言語には対応しておりません。
環境
- Visual Studio
-
- Visual Studio 2019
- ASP.NET Core
-
- 3.1 (Razor ページ, MVC)
静的ファイルの既定の配置場所について
静的ファイル (.js や .css, .png など) は既定では wwwroot フォルダの下に置くことが決まっています。 これにより Web サイト利用者は HTML と一緒に .js ファイルや .css ファイルを直接参照することができ画面に反映させることができます。
この静的ファイルの既定配置フォルダが wwwroot になっているのは Startup.Configure
メソッドに記述されている以下の app.UseStaticFiles
メソッドを呼んでいるからです。
public class Startup
{
// 省略
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 省略
app.UseStaticFiles();
// 省略
}
}
物理フォルダ「wwwroot」のパスは、URL でいうと「https://<ホスト名>/」の箇所にあたり、 例として「wwwroot\image\sample.png」にあるファイルは URL では「https://<ホスト名>/image/sample.png」で参照できます。
wwwroot フォルダ以外に配置したファイルは基本的に Web 上で URL から参照することはできません。
wwwroot フォルダ以外に静的ファイルを配置する方法と URL での参照パスの変更
フォルダ構成
今回は wwwroot フォルダの機能は残しつつ、別フォルダに画像ファイルを配置し Web で参照できるようにしたいと思います。
プロジェクトのフォルダ構成は以下のようにし、Areas 内にある各サイトの Content フォルダ内にある画像ファイルを参照できるようにします。
この状態だと sample1.png にあるファイルを参照する URL は
- https://<ホスト名>/areas/site1/content/image/sample1.png
や
- https://<ホスト名>/site1/content/image/sample1.png
になるように思えるかもしれませんが、ここでは
- https://<ホスト名>/site1/image/sample1.png
で参照できるようにします。
ちなみに wwwroot フォルダ以外に静的ファイルを配置した場合、ファイルのビルドアクションが なし になっている場合があります。 このままだと発行してもファイルが配置されませんので、必ず コンテンツ に設定しなおしてください。
プログラムの追加
wwwroot 以外のフォルダで静的ファイルを参照できるようにするには、以下のように Startup.Configure
メソッド内で app.UseStaticFiles
メソッドを追加で呼び出します。
// 追加
using Microsoft.Extensions.FileProviders;
using System.IO;
// 省略
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 省略
// wwwroot フォルダで静的ファイル参照を有効にする
app.UseStaticFiles();
// Site1 用の物理コンテンツフォルダと参照 URL を紐づける
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Areas/Site1/Content")),
RequestPath = "/Site1",
});
// Site2 用の物理コンテンツフォルダと参照 URL を紐づける
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Areas/Site2/Content")),
RequestPath = "/Site2",
});
// 省略
}
app.UseStaticFiles
メソッドを引数なしで呼び出すと wwwroot フォルダが有効になりますが、
第一引数に StaticFileOptions
を渡すと追加設定が可能です。
StaticFileOptions.FileProvider
プロパティには PhysicalFileProvider
のインスタンスを渡しつつ、静的ファイルとして参照させたい物理フォルダを指定します。
ここで指定したパス配下のファイルが Web で参照できるファイルになります。
また、次の RequestPath
プロパティの URL のルートにもなります。
env.ContentRootPath
プロパティには Web プログラムのルートパス(物理パス)が含まれていますので、
これと対象フォルダへの相対パスを結合するとよいでしょう。
StaticFileOptions.RequestPath
プロパティには静的ファイルを参照する URL のルートパスを記述します。
デフォルトの wwwroot では https://<ホスト名>
が基準となっていますが、
上記コードのように RequestPath = "/Site1"
と記述すると
https://<ホスト名>/Site1
がルートとなります。
これにより Areas/Site1/Content/xxxx
の物理パスと https://<ホスト名>/Site1/xxxx
の URL が紐づきます。
sample1.png を例とすると Areas/Site1/Content/image/sample.png
のファイルは https://<ホスト名>/Site1/image/sample.png
のパスで参照できるというわけです。
動作確認
index.html
に以下のように画像を参照できるように img タグを配置します。
パスは定義にそって site1 や site2 の画像も参照します。
<!-- 省略 -->
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<!-- ここから追加 -->
<img src="~/image/sample.png" />
<img src="~/site1/image/sample1.png" />
<img src="~/site2/image/sample2.png" />
<!-- ここまで追加 -->
実行して画像が見えていれば成功です。