ASP.NET Core 2 發行時封裝整個靜態檔案資料夾

在某些狀況,可能會想把 wwwroot 包起來,以防止遇到不預期的修改,雖然以下方式也只是簡易的防君子不防小人的方式。
首先以 ASP.NET Core 使用者入門的範例為例,建立一個新專案並直接發行它:

1
dotnet new razor -o aspnetcoreapp

將此專案發行到 out 資料夾中:

1
dotnet publish -c release -o out

完成後進到 out 資料夾中,可以看到以下檔案:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ ls -l
total 408
-rw-r--r-- 1 North 1049089 178 Mar 28 14:14 appsettings.Development.json
-rw-r--r-- 1 North 1049089 113 Mar 28 14:14 appsettings.json
-rwxr-xr-x 1 North 1049089 68096 Mar 28 14:37 aspnetcoreapp.PrecompiledViews.dll*
-rw-r--r-- 1 North 1049089 42496 Mar 28 14:37 aspnetcoreapp.PrecompiledViews.pdb
-rw-r--r-- 1 North 1049089 280120 Mar 28 14:37 aspnetcoreapp.deps.json
-rwxr-xr-x 1 North 1049089 7168 Mar 28 14:36 aspnetcoreapp.dll*
-rw-r--r-- 1 North 1049089 1668 Mar 28 14:36 aspnetcoreapp.pdb
-rw-r--r-- 1 North 1049089 221 Mar 28 14:37 aspnetcoreapp.runtimeconfig.json
-rw-r--r-- 1 North 1049089 628 Mar 28 14:14 bundleconfig.json
-rw-r--r-- 1 North 1049089 387 Mar 28 14:37 web.config
drwxr-xr-x 1 North 1049089 0 Mar 28 14:37 wwwroot/

可以執行,驗證結果是否正確:

1
dotnet aspnetcoreapp.dll

接著就開始改 code 了,首先於 aspnetcoreapp.csproj 的 <Project> 內加上這些內容:

1
2
3
4
5
6
<ItemGroup>
<Content Remove=".\wwwroot\**\*" />
<EmbeddedResource Include=".\wwwroot\**\*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
</EmbeddedResource>
</ItemGroup>

把 out 資料夾清空後再重新發行後,可以看到 wwwroot 資料夾不見了,且aspnetcoreapp.dll 的檔案大小大了不少:

1
2
3
4
5
6
7
8
9
10
11
12
$ ls -l
total 2420
-rw-r--r-- 1 North 1049089 178 Mar 28 14:14 appsettings.Development.json
-rw-r--r-- 1 North 1049089 113 Mar 28 14:14 appsettings.json
-rwxr-xr-x 1 North 1049089 68096 Mar 28 14:59 aspnetcoreapp.PrecompiledViews.dll*
-rw-r--r-- 1 North 1049089 42496 Mar 28 14:59 aspnetcoreapp.PrecompiledViews.pdb
-rw-r--r-- 1 North 1049089 280120 Mar 28 14:59 aspnetcoreapp.deps.json
-rwxr-xr-x 1 North 1049089 2068480 Mar 28 14:59 aspnetcoreapp.dll*
-rw-r--r-- 1 North 1049089 1672 Mar 28 14:59 aspnetcoreapp.pdb
-rw-r--r-- 1 North 1049089 221 Mar 28 14:59 aspnetcoreapp.runtimeconfig.json
-rw-r--r-- 1 North 1049089 628 Mar 28 14:14 bundleconfig.json
-rw-r--r-- 1 North 1049089 387 Mar 28 14:59 web.config

此時若執行 dotnet aspnetcoreapp.dll 會發現所有靜態檔案都沒被載入,因為 UseStaticFiles() 預設只載入 wwwroot 資料夾內的內容,因此要再做些修改。
開啟 Startup.cs,於開頭加上:

1
2
using System.Reflection;
using Microsoft.Extensions.FileProviders;

並於 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 內加上,加的位置端看於對 Middleware 想做什麼操作,在這裡不多加描述:

1
2
3
4
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
app.UseStaticFiles(new StaticFileOptions {
FileProvider = embeddedProvider
});

接著再執行 dotnet aspnetcoreapp.dll,理應可得到正確的結果。以上範例存放於此 aspnetcoreappEmbedStaticFiles

不過若用 Hex Editor 或直接用文字編輯器打開 aspnetcoreapp.dll 後可以看到內部還是可以看到 css, js 等內容,且可以被修改(若字元長度沒變的話),因此只是一個簡易的防範而已。

參考資料:

  1. Visual Studio publish profiles for ASP.NET Core app deployment | Microsoft Docs
  2. Common MSBuild Project Items
  3. How can I have an entire folder be an embedded resource in a Visual Studio project? - Stack Overflow
  4. Include Files using Wildcard into a folder in Visual Studio - Stack Overflow