其實我們在透過 dotnet publish
發行 ASP․NET Core 網站時,預設都會自動發佈一個 web.config
檔案,但是事實上這個檔案跟 Kestrel 完全沒關係,這個檔案主要是給 IIS 看的,當你想部署 ASP․NET Core 到 IIS 的時候,就一定需要這個檔案。今天這篇文章我就來說說,如何在執行 dotnet publish
命令的時候,自動調整 ASP․NET Core 部署到 IIS 的 web.config
內容。
預設的 Web.config 內容
預設的發行任務,搭配 -o DIR
可以將發行後的檔案輸出到指定路徑下:
dotnet publish -o dist
上述命令等同於加上了 -c Debug
組態設定,是一樣意思:
dotnet publish -c Debug -o dist
注意: -c Debug
與 -c DEBUG
到最後都會轉大寫,你用 C# 條件式編譯時,使用 #if Debug
是錯誤的寫法,用 #if DEBUG
才是正確的寫法!詳見 C# 前置處理器指示詞 文件。
其輸出路徑下的 web.config
內容長這樣:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\api1.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
這個設定檔,其實缺少了一組重要的「環境變數」名為 ASPNETCORE_ENVIRONMENT
,而該環境變數的預設值為 Production
,這個變數決定了 ASP․NET Core 跑在什麼樣的環境下,不同的環境可以註冊不同的 Middleware 與程式邏輯,因此學習到環境的切換技巧非常重要,本文稍後會特別強調如何調整環境定義。
除此之外,你也可以發行 Release
組態,而這兩種組態的差別,主要影響的範圍是 C# 條件式編譯的結果!
dotnet publish -c Release -o dist
注意: -c Release
與 -c RELEASE
到最後都會轉大寫,你用 #if Release
是錯誤的寫法,用 #if RELEASE
才是正確的寫法!
發佈到測試環境(Development)
你可以在執行 dotnet publish
時,透過 -p:EnvironmentName=Development
明確指定「環境名稱」到發行的結果中:
dotnet publish -c Debug -p:EnvironmentName=Development
實際上會影響的地方,主要是輸出的 web.config
會自動內建環境變數的設定,非常方便!
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\api1.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
發佈到正式環境(Production)
相對的,你也可以在執行 dotnet publish
時,透過 -p:EnvironmentName=Production
明確指定 Production
這個「環境名稱」到發行的結果中:
dotnet publish -c Release -p:EnvironmentName=Production
以下是輸出的 web.config
內容,一樣內建包含了環境變數的設定!
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\api1.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
發佈時不要發佈 web.config 檔案
由於我們很有可能對 web.config
進行調整,下次在部署時可能會蓋掉 web.config
的內容,針對這個問題,你只要在執行 dotnet publish
時加上 -p:IsTransformWebConfigDisabled=true
參數,即可停用 web.config
輸出,發行目錄中就不會有 web.config
這個檔案存在!👍
dotnet publish -c Release -p:IsTransformWebConfigDisabled=true
發佈時不要發佈 web.config 檔案但必要時透過參數指定輸出
除此之外,你也可以直接在 *.csproj
加入一個 IsTransformWebConfigDisabled
Property 並設定為 true
,就可以變更預設的輸出不要包含 web.config
檔案,我個人比較喜歡這樣的設定方式:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
</Project>
之後你輸入 dotnet publish -c Release
預設就不會輸出 web.config
檔案:
dotnet publish -c Release
不過你依然可以從 CLI 設定 -p:IsTransformWebConfigDisabled=false
參數,讓該次發行輸出 web.config
檔案:
dotnet publish -c Release -p:IsTransformWebConfigDisabled=false
如果要連同輸出環境名稱,就可以這樣執行:
dotnet publish -c Release -p:IsTransformWebConfigDisabled=false -p:EnvironmentName=Production
相關連結