最近更新: 2019-03-26

.NET 筆記 - ASP.NET Core appsettings.json 與執行環境

一般進行程式開發工作時,至少會分成兩個階段,或說兩個工作會期。開發期/Development/Debug 和 發布期/Production/Release 。並針對這兩個階段,設定不同的執行環境。

例如設定開發期執行環境的資料庫來源是 SQLite ,而發布期執行環境則用客戶指定的資料庫來源 SQL Server 。如此一來,開發人員僅須切換組態檔,就能改變程式的執行環境與參數。方便應付開發、測試、正式部署等工作。

ASP.NET Core 選擇用 DevelopmentProduction 這兩個稱呼區分兩階段。

兩個 appsettings

為什麼 .NET Core 新建 Web 專案時,會有 appsettings.jsonappsettings.Development.json 兩個內容很相似的檔案?程式啟動時會用哪一個?

這兩個檔案其實都是 Web 專案啟動時的組態設定。它們的組態值,也會傳給 Controller 元件的建構參數 config

Web 專案啟動時,將依據執行環境決定只讀取 appsettings.json 或是兩個都讀。

若執行環境為 Production ,只讀 appsettings.json

若執行環境為 Development ,先讀取 appsettings.json 再讀取 appsettings.Development.json 。並合併兩檔的組態。若組態項目重複,則以後來者覆蓋先前設定,亦即以 appsettings.Development.json 為準。

例如 appsettings.jsonappsettings.Development.json 兩個檔案皆設定 Logging:LogLevel:Default 組態時,將以 appsettings.Development.json 之設定為準。

如何決定執行環境

執行環境由環境變數之值決定,預設是看 ASPNETCORE_ENVIRONMENT 之值。

你可以為執行環境取任何名稱。但 ASP.NET core 主要使用以下三個環境名稱:

  • Development 代表開發環境。
  • Staging 代表測試環境。
  • Production 代表產品環境 (公開發表的作品)。

如果沒有指定 ASPNETCORE_ENVIRONMENT 環境變數,則預設的執行環境是 Production 。因此 appsettings.jsonProduction 執行環境的組態,而 appsettings.Development.json 就是 Development 執行環境的組態。

為何本機專案目錄的執行環境是 Development ?

上一段說未指定執行環境時,預設為 Production 。但你會發現在本機的專案目錄下,以指令 dotnet run 啟動時,儘管未指定執行環境,但執行環境卻是 Development

指令 dotnet new 建立新 Web 專案時,會產生 Properties\launchSettings.json 。在 launchSettings.json 預設必有一段:

    "commandName": "Project",
    "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
    }

指令 dotnet run 不加參數時,會找第一個 commandName 為 “Project” 的 profile 項目。 dotnet run 便按此項目的預設內容設定環境變數 ASPNETCORE_ENVIRONMENTDevelopment ,再執行你的程式。這就是在本機專案目錄下啟動程式時,執行環境是 Development 的原因。

還有 2 件事:

  • 可用 dotnet run --launch-profile [profile] 指定使用 launchSettings.json 的哪一組設定資料。
  • 對 Web 專案,指令 dotnet run -c Release 並不會改變預設的執行環境。

部署在目標主機

dotnet publish 部署在目標主機的內容不會包含 Properties\launchSettings.json ,也就不會設定環境變數 ASPNETCORE_ENVIRONMENT 。故採用預設的 Production 執行環境。因此你部署在目標主機的程式啟動時只會讀取 appsettings.json

你可以在不同的目標主機上,設定不同的 Properties\launchSettings.json 並指定自訂的執行環境名稱,配合 appsettings.{ENVIRONMENT}.json ,讓每個目標主機擁有各自的執行環境。

但反過來說,你也要自己記得不同目標主機可能擁有各自的組態檔。我曾碰到有人問為什麼已經修改 appsettings.json 並上傳到目標主機了,卻依然使用舊的組態?那是因為他忘記目標主機上還擺了一組 launchSettings.json/appsettings.Custom.json 。而這組自訂的執行環境組態將覆蓋他修改過的組態。

再舉一個應用範例。如果你有一台專門負責自動測試的虛擬主機,你可以在那台主機的環境變數中設定 ASPNETCORE_ENVIRONMENT=Testing ,那麼所有部署到這台自動測試主機上的 Web 專案都會進一步嘗試讀取 appsettings.Testing.json ,套用自動測試環境的組態。