ASP.NET Core 的設定

作者 :Rick AndersonKirk Larkin

ASP.NET Core中的應用程式組態是使用一或多個組態提供者來執行。 設定提供者會使用各種組態來源,從機碼/值組讀取組態資料:

  • 設定檔案,例如 appsettings.json
  • 環境變數
  • Azure Key Vault
  • Azure 應用程式組態
  • 命令列引數
  • 自訂提供者、安裝或建立
  • 目錄檔案
  • 記憶體內部 .NET 物件

本文提供 ASP.NET Core 中的組態資訊。 如需在主控台應用程式中使用組態的資訊,請參閱 .NET 組態

應用程式和主機組態

ASP.NET Core應用程式設定並啟動主機。 主機負責應用程式啟動和存留期管理。 ASP.NET Core範本會 WebApplicationBuilder 建立包含主機的 。 雖然某些組態可以在主機和應用程式組態提供者中完成,但通常只有主機所需的組態才能在主機組態中完成。

應用程式設定是最高優先順序,在下一節中詳述。 主機組態 遵循應用程式組態,本文將說明。

預設應用程式組態來源

ASP.NET Core使用dotnet new或 Visual Studio 建立的 Web 應用程式會產生下列程式碼:

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder 會使用預先設定的 WebApplicationBuilder 預設值,初始化 類別的新實例。 初始化 WebApplicationBuilder (builder) 依下列順序提供應用程式的預設組態,從最高優先順序到最低優先順序:

  1. 使用命令列 組態提供者的命令列引數。
  2. 使用 非前置環境變數組態提供者的非前置環境變數。
  3. 應用程式在 Development 環境中執行時的使用者密碼
  4. appsettings.{Environment}.json使用ON 組 JS 態提供者。 例如,appsettings.Production.jsonappsettings.Development.json
  5. 使用ON 組態提供者的 JSappsettings.json
  6. 下一節所述的主機組態後援。

預設主機組態來源

下列清單包含最高優先順序到最低優先順序的預設主機組態來源:

  1. ASPNETCORE_使用 環境變數組態提供者的前置環境變數。
  2. 使用命令列組態提供者的命令列引數
  3. DOTNET_使用 環境變數組態提供者的前置環境變數。

在主機和應用程式組態中設定組態值時,會使用應用程式組態。

如需主機組態為何前置環境變數優先順序高於命令列引數的說明, ASPNETCORE_ 請參閱此 GitHub 批註中的說明。

主機變數

在初始化主機產生器時,會提早鎖定下列變數,且無法受到應用程式設定的影響:

其他每個主機設定都是從應用程式組態讀取,而不是主機設定。

URLS 是許多不是啟動程式設定的常見主機設定之一。 就像上一個清單中的其他主機設定一樣, URLS 稍後會從應用程式組態讀取。主機組態是應用程式組態的後援,因此可以使用主機組態來設定 URLS ,但會由應用程式組態中的任何組態來源覆寫,例如 appsettings.json

如需詳細資訊,請參閱 變更內容根目錄、應用程式名稱和環境以及依環境變數或命令列變更內容根目錄、應用程式名稱和環境

本文中的其餘各節會參考應用程式組態。

應用程式設定提供者

下列程式碼會依新增的順序顯示已啟用的組態提供者:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

上述 最高至最低優先順序的預設組態來源清單 會顯示提供者,其會以相反的順序新增至範本產生的應用程式。 例如,JS 在命令列組態提供者之前會新增 ON 組態提供者

稍後新增的組態提供者具有較高的優先順序,並覆寫先前的金鑰設定。 例如,如果在 MyKey 和 環境中設定 appsettings.json ,則會使用環境值。 使用預設組態提供者, 命令列組態提供者 會覆寫所有其他提供者。

如需 的詳細資訊 CreateBuilder ,請參閱 預設產生器設定

appsettings.json

請考慮下列 appsettings.json 檔案:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

範例 下載 中的下列程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

預設 JsonConfigurationProvider 會依下列順序載入組態:

  1. appsettings.json
  2. appsettings.{Environment}.json :例如, appsettings.Production.jsonappsettings.Development.json 檔案。 系統會根據 IHostingEnvironment.EnvironmentName 載入檔案的環境版本。 如需詳細資訊,請參閱在 ASP.NET Core 中使用多個環境

appsettings.{Environment}.json 值會覆寫 中的 appsettings.json 索引鍵。 例如,根據預設:

  • 在開發中, appsettings.Development.json 組態會覆寫 中找到 appsettings.json 的值。
  • 在生產環境中, appsettings.Production.json 組態會覆寫 中找到 appsettings.json 的值。 例如,將應用程式部署至 Azure 時。

如果必須保證組態值,請參閱 GetValue。 上述範例只會讀取字串,而且不支援預設值。

使用預設組態時, appsettings.json 會以reloadOnChange 啟用appsettings.{Environment}.json 檔案:true。 在應用程式啟動時對 和 appsettings.{Environment}.json檔案所做的appsettings.json 變更會由JS ON 組態提供者讀取。

使用選項模式系結階層式設定資料

讀取相關組態值的慣用方式是使用 選項模式。 例如,若要讀取下列組態值:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

建立下列 PositionOptions 類別:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

選項類別:

  • 必須是非抽象,且具有公用無參數建構函式。
  • 類型的所有公用讀寫屬性都會系結。
  • 欄位未系結。 在上述程式碼中, Position 未系結。 欄位 Position 是用來讓字串 "Position" 在將類別系結至組態提供者時,不需要在應用程式中硬式編碼。

下列程式碼:

  • 呼叫 ConfigurationBinder.Bind ,將 PositionOptions 類別系結至 區 Position 段。
  • 顯示組 Position 態資料。
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上述程式碼中,預設會在 JS 讀取應用程式之後變更 ON 組態檔。

ConfigurationBinder.Get<T> 系結並傳回指定的型別。 ConfigurationBinder.Get<T> 比使用 ConfigurationBinder.Bind 更方便。 下列程式碼示範如何搭配 PositionOptions 類別使用 ConfigurationBinder.Get<T>

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上述程式碼中,預設會在 JS 讀取應用程式之後變更 ON 組態檔。

使用 選項模式 時的替代方法是系結 區 Position 段,並將其新增至 相依性插入服務容器。 在下列程式碼中, PositionOptions 會新增至服務容器,並 Configure 系結至組態:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

使用上述程式碼,下列程式碼會讀取位置選項:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

在上述程式碼中,不會讀取應用程式啟動之後的 ON 組態檔變更 JS 。 若要在應用程式啟動之後讀取變更,請使用 IOptionsSnapshot

使用預設組態時, appsettings.json 會以reloadOnChange 啟用appsettings.{Environment}.json 檔案:true。 在應用程式啟動時對 和 appsettings.{Environment}.json檔案所做的appsettings.json 變更會由JS ON 組態提供者讀取。

如需新增其他 JS ON 組態檔的相關資訊,請參閱JS本檔中的 ON 組態提供者。

合併服務集合

請考慮下列專案來註冊服務和設定選項:

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

相關的註冊群組可以移至擴充方法以註冊服務。 例如,組態服務會新增至下列類別:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }
    }
}

其餘服務會註冊在類似的類別中。 下列程式碼會使用新的擴充方法來註冊服務:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

注意: 每個 services.Add{GROUP_NAME} 擴充方法都會新增並可能設定服務。 例如, AddControllersWithViews 新增具有檢視所需的 MVC 控制器服務,並 AddRazorPages 新增 Pages 所需的服務 Razor 。 我們建議應用程式遵循在命名空間中建立擴充方法的 Microsoft.Extensions.DependencyInjection 命名慣例。 在命名空間中 Microsoft.Extensions.DependencyInjection 建立擴充方法:

安全性和使用者密碼

設定資料指導方針:

  • 永遠不要將密碼或其他敏感性資料儲存在設定提供者程式碼或純文字設定檔中。 秘密管理員工具可用來將秘密儲存在開發中。
  • 不要在開發或測試環境中使用生產環境祕密。
  • 請在專案外部指定祕密,以防止其意外認可至開放原始碼存放庫。

根據 預設,使用者秘密組態來源會在 ON 組態來源之後 JS 註冊。 因此,使用者秘密金鑰的優先順序高於 和 appsettings.{Environment}.json 中的 appsettings.json 金鑰。

如需儲存密碼或其他敏感性資料的詳細資訊:

Azure Key Vault 可安全地儲存 ASP.NET Core 應用程式的應用程式祕密。 如需詳細資訊,請參閱ASP.NET Core 中的 Azure 金鑰保存庫組態提供者

非前置環境變數

非前置環境變數是 或 前置詞以外的 ASPNETCORE_DOTNET_ 環境變數。 例如,在 中 launchSettings.json 設定 "ASPNETCORE_ENVIRONMENT": "Development" 的 ASP.NET Core Web 應用程式範本。 如需 和 DOTNET_ 環境變數的詳細資訊 ASPNETCORE_ ,請參閱:

使用 預設 組態,會在 EnvironmentVariablesConfigurationProvider 讀取 appsettings.jsonappsettings.{Environment}.json 和 使用者密碼之後,從環境變數索引鍵/值組載入 組態。 因此,從環境讀取的索引鍵值會覆寫讀取自 appsettings.jsonappsettings.{Environment}.json 和 使用者密碼的值。

分隔 : 符不適用於所有平臺上的環境變數階層式索引鍵。 __,雙底線為:

  • 所有平臺都支援。 例如, :Bash不支援分隔符號,但 __ 是 。
  • 自動取代為 :

下列 set 命令:

  • 在 Windows 上設定 上述範例 的環境索引鍵和值。
  • 使用 範例下載時測試設定。 dotnet run命令必須在專案目錄中執行。
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

上述環境設定:

  • 只會在從所設定命令視窗啟動的進程中設定。
  • 不會由使用 Visual Studio 啟動的瀏覽器讀取。

下列 setx 命令可用來在 Windows 上設定環境索引鍵和值。 不同于 setsetx 會保存設定。 /M 會設定系統內容中的變數。 /M如果未使用參數,則會設定使用者環境變數。

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

若要測試上述命令覆寫 appsettings.jsonappsettings.{Environment}.json

  • 使用 Visual Studio:結束並重新啟動 Visual Studio。
  • 使用 CLI:啟動新的命令視窗,然後輸入 dotnet run

使用字串呼叫 AddEnvironmentVariables ,以指定環境變數的前置詞:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");

var app = builder.Build();

在上述程式碼中:

  • builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_") 會在 預設組態提供者之後新增。 如需排序設定提供者的範例,請參閱JS ON 組態提供者
  • 以前置詞設定的 MyCustomPrefix_ 環境變數會覆寫 預設組態提供者。 這包括不含前置詞的環境變數。

讀取組態索引鍵/值組時,會移除前置詞。

下列命令會測試自訂前置詞:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

預設組態會載入前面加上 和 ASPNETCORE_DOTNET_ 環境變數和命令列引數。 和 DOTNET_ASPNETCORE_ 前置詞是由主機和應用程式組態ASP.NET Core使用,但不適用於使用者設定。 如需主機和應用程式設定的詳細資訊,請參閱 .NET 泛型主機

Azure App 服務上,選取 [設定 > 組態] 頁面上的 [新增應用程式設定]。 Azure App 服務應用程式設定如下:

  • 待用加密,並透過加密通道傳輸。
  • 公開為環境變數。

如需詳細資訊,請參閱 Azure App:使用 Azure 入口網站覆寫應用程式設定

如需 Azure 資料庫連接字串的相關資訊,請參閱 連接字串前置 詞。

環境變數的命名

環境變數名稱會反映檔案的結構 appsettings.json 。 階層中的每個元素都會以雙底線分隔, (最好) 或冒號。 當專案結構包含陣列時,陣列索引應該視為這個路徑中的其他專案名稱。 請考慮下列 appsettings.json 檔案及其表示為環境變數的對等值。

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

環境變數

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

在產生的 launchSettings.json 中設定的環境變數

在 中 launchSettings.json 設定的環境變數會覆寫系統內容中的環境變數。 例如,ASP.NET Core Web 範本會產生檔案 launchSettings.json ,將端點組態設定設為:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

applicationUrl設定 環境變數, ASPNETCORE_URLS 並覆寫環境中設定的值。

在 Linux 上逸出環境變數

在 Linux 上,URL 環境變數的值必須逸出,以便 systemd 剖析它。 使用會產生的 Linux 工具 systemd-escapehttp:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

顯示環境變數

下列程式碼會顯示應用程式啟動時的環境變數和值,在偵錯環境設定時可能會很有説明:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

命令列

使用 預設 組態,會在 CommandLineConfigurationProvider 下列組態來源之後,從命令列引數索引鍵/值組載入組態:

根據 預設,命令列上設定的組態值會覆寫以所有其他組態提供者所設定的組態值。

命令列引數

下列命令會使用 = 來設定索引鍵和值:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

下列命令會使用 / 來設定索引鍵和值:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

下列命令會使用 -- 來設定索引鍵和值:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

索引鍵值:

  • 必須遵循 = ,或索引鍵必須具有 前置詞 -- ,或 / 值在空格之後時。
  • 如果使用 = ,則不需要 。 例如: MySetting=

在相同的命令中,請勿混合命令列引數索引鍵/值組,這些組搭配 = 使用空格的索引鍵/值組。

切換對應

切換對應允許 金鑰 名稱取代邏輯。 提供 參數取代的字典給 AddCommandLine 方法。

使用切換對應字典時,會檢查字典中是否有任何索引鍵符合命令列引數所提供的索引鍵。 如果在字典中找到命令列索引鍵,則會將字典值傳回,以將機碼/值組設定為應用程式的組態。 所有前面加上單虛線 (-) 的命令列索引鍵都需要切換對應。

切換對應字典索引鍵規則:

  • 參數必須以 --- 開頭。
  • 切換對應字典不能包含重複索引鍵。

若要使用參數對應字典,請將它傳遞至 的 AddCommandLine 呼叫:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

執行下列命令可測試金鑰取代:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

下列程式碼顯示已取代索引鍵的索引鍵值:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

針對使用切換對應的應用程式,呼叫 CreateDefaultBuilder 不應傳遞引數。 方法 CreateDefaultBuilderAddCommandLine 呼叫不包含對應的參數,而且沒有任何方法可將參數對應字典傳遞至 CreateDefaultBuilder 。 解決方案不會將引數傳遞至 CreateDefaultBuilder ,而是允許 ConfigurationBuilder 方法 AddCommandLine 的 方法同時處理引數和參數對應字典。

使用 Visual Studio 設定環境和命令列引數

您可以從 [啟動設定檔] 對話方塊,在 Visual Studio 中設定環境和命令列引數:

  • 在 方案總管 中,以滑鼠右鍵按一下專案,然後選取 [屬性]。
  • 選取 [ 偵錯一般] > 索引標籤,然後選取 [開啟偵錯啟動設定檔 UI]。

階層式設定資料

組態 API 會透過在組態索引鍵中使用分隔符號來扁平化階層式資料,以讀取階層式設定資料。

範例下載包含下列 appsettings.json 檔案:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

下列 範例下載 程式碼會顯示數個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

讀取階層式設定資料的慣用方式是使用選項模式。 如需詳細資訊,請參閱本檔中的 系結階層式設定資料

GetSectionGetChildren 方法可用來在設定資料中隔離區段與區段的子系。 GetSection,、 GetChildren 與 Exists 中說明這些方法。

組態索引鍵和值

設定金鑰:

  • 不區分大小寫。 例如,ConnectionStringconnectionstring 會被視為相等的機碼。
  • 如果索引鍵和值是在多個組態提供者中設定,則會使用上一個新增提供者的值。 如需詳細資訊,請參閱 預設組態
  • 階層式機碼
    • 在設定 API 內,冒號分隔字元 (:) 可在所有平台上運作。
    • 在環境變數中,冒號分隔字元可能無法在所有平台上運作。 所有平臺都支援雙底線 __ ,且會自動轉換成冒號 :
    • 在 Azure 金鑰保存庫中,階層式索引鍵會用作 -- 分隔符號。 Azure 金鑰保存庫組態提供者會在將秘密載入應用程式組態時自動取代 --: 為 。
  • ConfigurationBinder 支援在設定機碼中使用陣列索引將陣列繫結到物件。 將陣列繫結到類別一節說明陣列繫結。

組態值:

  • 是字串。
  • Null 值無法存放在設定中或繫結到物件。

設定提供者

下表顯示可供 ASP.NET Core 應用程式使用的設定提供者。

提供者 從提供設定
Azure 金鑰保存庫組態提供者 Azure Key Vault
Azure App組態提供者 Azure 應用程式組態
命令列組態提供者 命令列參數
自訂設定提供者 自訂來源
環境變數組態提供者 環境變數
檔案組態提供者 INI、 JS ON 和 XML 檔案
每個檔案的金鑰組態提供者 目錄檔案
記憶體組態提供者 記憶體內集合
使用者祕密 使用者設定檔目錄中的檔案

設定來源會依其設定提供者的指定順序讀取。 排序程式代碼中的組態提供者,以符合應用程式所需的基礎組態來源優先順序。

典型的設定提供者順序是:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. 使用者祕密
  4. 使用 環境變數組態提供者的環境變數
  5. 使用命令列 組態提供者的命令列引數。

常見的做法是,在一系列提供者中最後新增命令列組態提供者,以允許命令列引數覆寫其他提供者所設定的組態。

上述提供者序列用於 預設組態中。

連接字串前置詞

組態 API 有四個連接字串環境變數的特殊處理規則。 這些連接字串涉及設定應用程式環境的 Azure 連接字串。 資料表中顯示的前置詞環境變數會載入具有 預設組態 的應用程式,或未提供前置詞給 AddEnvironmentVariables 時。

連接字串前置詞 提供者
CUSTOMCONNSTR_ 自訂提供者
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

當探索到具有下表所顯示之任何四個前置詞的環境變數並將其載入到設定中時:

  • 會透過移除環境變數前置詞並新增設定機碼區段 (ConnectionStrings) 來移除具有下表顯示之前置詞的環境變數。
  • 會建立新的設定機碼值組以代表資料庫連線提供者 (CUSTOMCONNSTR_ 除外,這沒有所述提供者)。
環境變數機碼 已轉換的設定機碼 提供者設定項目
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} 設定項目未建立。
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:System.Data.SqlClient

檔案組態提供者

FileConfigurationProvider 是用於從檔案系統載入設定的基底類別。 下列組態提供者衍生自 FileConfigurationProvider

INI 組態提供者

IniConfigurationProvider 會在執行階段從 INI 檔案機碼值組載入設定。

下列程式碼會清除所有組態提供者,並新增數個組態提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    var env = hostingContext.HostingEnvironment;

    config.AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
          .AddIniFile($"MyIniConfig.{env.EnvironmentName}.ini",
                         optional: true, reloadOnChange: true);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

在上述程式碼中,和 MyIniConfig.{Environment}.ini 檔案中的 MyIniConfig.ini 設定會由 中的設定覆寫:

範例下載包含下列 MyIniConfig.ini 檔案:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

範例 下載 中的下列程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

JSON 組態提供者

JsonConfigurationProvider 從 JS ON 檔案機碼/值組載入組態。

多載可以指定:

  • 檔案是否為選擇性。
  • 檔案變更時是否要重新載入設定。

請考慮下列程式碼:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MyConfig.json",
                       optional: true,
                       reloadOnChange: true);
});

builder.Services.AddRazorPages();

var app = builder.Build();

上述程式碼:

  • 設定 ON 組 JS 態提供者以使用下列選項載入 MyConfig.json 檔案:
    • optional: true:檔案是選擇性的。
    • reloadOnChange: true :儲存變更時會重載檔案。
  • 讀取檔案之前 MyConfig.json的預設組態提供者。 預設組態提供者中檔案覆寫設定中的 MyConfig.json 設定,包括 環境變數組態提供者命令列組態提供者

您通常 不希望 自訂 JS ON 檔案覆寫 環境變數組態提供者命令列組態提供者中設定的值。

XML 組態提供者

XmlConfigurationProvider 會在執行階段從 XML 檔案機碼值組載入設定。

下列程式碼會清除所有組態提供者,並新增數個組態提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    var env = hostingContext.HostingEnvironment;

    config.AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
          .AddXmlFile($"MyXMLFile.{env.EnvironmentName}.xml",
                         optional: true, reloadOnChange: true);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

在上述程式碼中,和 MyXMLFile.{Environment}.xml 檔案中的 MyXMLFile.xml 設定會由 中的設定覆寫:

範例下載包含下列 MyXMLFile.xml 檔案:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

範例 下載 中的下列程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

name 屬性是用來區別元素,則可以重複那些使用相同元素名稱的元素:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

下列程式碼會讀取先前的組態檔,並顯示索引鍵和值:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

屬性可用來提供值:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

先前的設定檔會使用 value 載入下列機碼:

  • key:attribute
  • section:key:attribute

每個檔案的金鑰組態提供者

KeyPerFileConfigurationProvider 使用目錄的檔案做為設定機碼值組。 機碼是檔案名稱。 值包含檔案的內容。 Docker 裝載案例中會使用金鑰個別檔案組態提供者。

若要啟用每個檔案機碼設定,請在 ConfigurationBuilder 的執行個體上呼叫 AddKeyPerFile 延伸模組方法。 檔案的 directoryPath 必須是絕對路徑。

多載允許指定:

  • 設定來源的 Action<KeyPerFileConfigurationSource> 委派。
  • 目錄是否為選擇性與目錄的路徑。

雙底線 (__) 是做為檔案名稱中的設定金鑰分隔符號使用。 例如,檔案名稱 Logging__LogLevel__System 會產生設定金鑰 Logging:LogLevel:System

建置主機時呼叫 ConfigureAppConfiguration 以指定應用程式的設定:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

記憶體組態提供者

MemoryConfigurationProvider 使用記憶體內集合做為設定機碼值組。

下列程式碼會將記憶體集合新增至組態系統:

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    config.AddInMemoryCollection(Dict);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

下列 範例下載 程式碼會顯示上述組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

在上述程式碼中, config.AddInMemoryCollection(Dict) 會在預設組 態提供者之後新增。 如需排序設定提供者的範例,請參閱JS ON 組態提供者

如需使用 MemoryConfigurationProvider 的其他範例,請參閱系結陣列

Kestrel 端點組態

Kestrel 特定端點組態會覆寫所有 跨伺服器端 點組態。 跨伺服器端點組態包括:

請考慮在 ASP.NET Core Web 應用程式中使用的下列 appsettings.json 檔案:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

當上述醒目提示標記用於 ASP.NET Core Web 應用程式,應用程式會在命令列上啟動,並具有下列跨伺服器端點組態:

dotnet run --urls="https://localhost:7777"

Kestrel 系結至檔案中特別針對 Kestrel 設定的 appsettings.json 端點, () https://localhost:9999 ,而不是 https://localhost:7777

請考慮設定 Kestrel 為環境變數的特定端點:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

在上述環境變數中, Https 是特定端點的名稱 Kestrel 。 上述 appsettings.json 檔案也會定義 Kestrel 名為 Https 的特定端點。 根據 預設,使用 環境變數組態提供者 的環境變數會在 之後 appsettings.{Environment}.json 讀取,因此會針對 Https 端點使用上述環境變數。

GetValue

ConfigurationBinder.GetValue 從具有指定索引鍵的組態中擷取單一值,並將它轉換成指定的類型:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

在上述程式碼中,如果在 NumberKey 組態中找不到 ,則會使用 的 99 預設值。

GetSection、GetChildren 與 Exists

針對下列範例,請考慮下列 MySubsection.json 檔案:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

下列程式碼會將 新增 MySubsection.json 至組態提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MySubsection.json",
                       optional: true,
                       reloadOnChange: true);
});

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection 會傳回具有指定子區段索引鍵的組態子區段。

下列程式碼會傳 section1 回 的值:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

下列程式碼會傳 section2:subsection0 回 的值:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection 絕不會傳回 null。 若找不到相符的區段,會傳回空的 IConfigurationSection

GetSection 傳回相符區段時,未填入 Value。 當區段存在時,會傳回 KeyPath

GetChildren 和 Exists

下列程式碼會呼叫 IConfiguration.GetChildren 並傳回 的值 section2:subsection0

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

上述程式碼會呼叫 ConfigurationExtensions.Exists 以確認區段存在:

系結陣列

ConfigurationBinder.Bind 支援在設定機碼中使用陣列索引將陣列繫結到物件。 任何公開數值索引鍵區段的陣列格式,都能夠將陣列系結至 POCO 類別陣列。

請考慮 MyArray.json範例下載

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

下列程式碼會將 新增 MyArray.json 至組態提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MyArray.json",
                        optional: true,
                        reloadOnChange: true); ;
});

builder.Services.AddRazorPages();

var app = builder.Build();

下列程式碼會讀取組態並顯示值:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

上述程式碼會傳回下列輸出:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

在上述輸出中,索引 3 具有 值 value40 ,對應至 "4": "value40", 中的 MyArray.json 。 系結陣列索引是連續的,而且不會系結至組態索引鍵索引。 組態系結器無法系結 Null 值,或是在系結物件中建立 Null 專案。

自訂設定提供者

範例應用程式示範如何建立會使用 Entity Framework (EF) 從資料庫讀取設定機碼值組的基本設定提供者。

提供者具有下列特性:

  • EF 記憶體內資料庫會用於示範用途。 若要使用需要連接字串的資料庫,請實作第二個 ConfigurationBuilder 以從另一個設定提供者提供連接字串。
  • 啟動時,該提供者會將資料庫資料表讀入到設定中。 該提供者不會以個別機碼為基礎查詢資料庫。
  • 未實作變更時重新載入,因此在應用程式啟動後更新資料庫對應用程式設定沒有影響。

定義 EFConfigurationValue 實體來在資料庫中存放設定值。

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

新增 EFConfigurationContext 以存放及存取已設定的值。

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

建立會實作 IConfigurationSource 的類別。

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

透過繼承自 ConfigurationProvider 來建立自訂設定提供者。 若資料庫是空的,設定提供者會初始化資料庫。 由於組態索引鍵不區分大小寫,因此用來初始化資料庫的字典會以不區分大小寫的比較子建立, (StringComparer.OrdinalIgnoreCase) 。

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

AddEFConfiguration 擴充方法允許新增設定來源到 ConfigurationBuilder

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

下列程式碼示範如何使用 中的 Program.cs 自訂 EFConfigurationProvider

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

使用相依性插入 (DI) 存取設定

設定可藉由解析 IConfiguration 服務,使用相依性插入 (DI) 插入服務:

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

如需如何使用 存取值 IConfiguration 的資訊,請參閱本文中的 GetValueGetSection、GetChildren 和 Exists

存取頁面中的組態 Razor

下列程式碼會在 Page 中顯示組 Razor 態資料:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

在下列程式碼中, MyOptions 會新增至服務容器,並系 Configure 結至組態:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

下列標記會使用 @injectRazor 指示詞來解析及顯示選項值:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

存取 MVC 檢視檔案中的組態

下列程式碼會在 MVC 檢視中顯示組態資料:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

使用委派設定選項

在組態提供者中設定的委派覆寫值中所設定的選項。

在下列程式碼中, IConfigureOptions<TOptions> 服務會新增至服務容器。 它會使用委派來設定 的值 MyOptions

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

下列程式碼會顯示選項值:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

在上述範例中,和 Option2 的值 Option1 是在 中 appsettings.json 指定,然後由已設定的委派覆寫。

主機與應用程式組態的比較

設定及啟動應用程式之前,會先設定及啟動「主機」。 主機負責應用程式啟動和存留期管理。 應用程式與主機都是使用此主題中所述的設定提供者來設定的。 主機組態機碼/值組也會包含在應用程式的組態中。 如需在建置主機時如何使用組態提供者,以及設定來源如何影響主機設定的詳細資訊,請參閱ASP.NET Core基本概觀

預設主機組態

如需使用 Web 主機時預設組態的詳細資料,請參閱本主題的 ASP.NET Core 2.2 版本

  • 主機組態的提供來源:
    • 環境變數前面加上 DOTNET_ (,例如, DOTNET_ENVIRONMENT 使用 環境變數組態提供者) 。 載入設定機碼值組時,會移除前置詞 (DOTNET_)。
    • 使用命令列組 態提供者的命令列引數。
  • 已建立 Web 主機預設組態 (ConfigureWebHostDefaults):
    • Kestrel 會當做 Web 服務器使用,並使用應用程式的組態提供者進行設定。
    • 新增主機篩選中介軟體。
    • 如果 ASPNETCORE_FORWARDEDHEADERS_ENABLED 環境變數設定為 true,則會新增轉接的標頭中介軟體。
    • 啟用 IIS 整合。

其他設定

本主題僅適用于 應用程式設定。 執行和裝載 ASP.NET Core應用程式的其他層面是使用本主題未涵蓋的組態檔來設定:

中設定的 launchSettings.json 環境變數會覆寫系統內容中的環境變數。

如需從舊版 ASP.NET 移轉應用程式組態的詳細資訊,請參閱從 ASP.NET 移轉至 ASP.NET Core

從外部組件新增設定

IHostingStartup 實作允許在啟動時從應用程式 Startup 類別外部的外部組件,針對應用程式新增增強功能。 如需詳細資訊,請參閱在 ASP.NET Core 中使用裝載啟動元件

其他資源

ASP.NET Core中的應用程式組態是使用一或多個組態提供者來執行。 組態提供者會使用各種組態來源,從機碼/值組讀取組態資料:

  • 設定檔案,例如 appsettings.json
  • 環境變數
  • Azure Key Vault
  • Azure 應用程式組態
  • 命令列引數
  • 自訂提供者、安裝或建立
  • 目錄檔案
  • 記憶體內部 .NET 物件

本文提供 ASP.NET Core 中的組態資訊。 如需在主控台應用程式中使用組態的資訊,請參閱 .NET 組態

應用程式和主機組態

ASP.NET Core應用程式設定並啟動主機。 主機負責應用程式啟動和存留期管理。 ASP.NET Core範本會建立 WebApplicationBuilder 包含主機的 。 雖然某些組態可以在主機和應用程式組態提供者中完成,但通常只有主機所需的組態才能在主機組態中完成。

應用程式組態是最高優先順序,下一節會詳細說明。 主機組態 會遵循應用程式設定,本文會說明。

預設應用程式組態來源

ASP.NET Core使用dotnet new或 Visual Studio 建立的 Web 應用程式會產生下列程式碼:

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder 會使用預先設定的預設值,初始化 類別的新實例 WebApplicationBuilder 。 初始化 WebApplicationBuilder 的 (builder) 會以下列順序提供應用程式的預設設定,從最高優先順序到最低:

  1. 使用命令列組 態提供者的命令列引數。
  2. 使用非前置詞 環境變數組態提供者的非前置環境變數
  3. 應用程式在 Development 環境中執行時的使用者密碼
  4. appsettings.{Environment}.json使用 ON 組JS 態提供者。 例如,appsettings.Production.jsonappsettings.Development.json
  5. appsettings.json使用 ON 組JS 態提供者
  6. 一節所述的主機組態後援。

預設主機組態來源

下列清單包含從最高優先順序到最低優先順序的預設主機組態來源:

  1. ASPNETCORE_使用 環境變數組態提供者的前置環境變數。
  2. 使用命令列組態提供者的命令列引數
  3. DOTNET_使用 環境變數組態提供者的前置環境變數。

在主機和應用程式組態中設定組態值時,會使用應用程式組態。

如需主機設定為何前置環境變數優先順序高於命令列引數的說明, ASPNETCORE_ 請參閱此 GitHub 批註中的說明

主機變數

在初始化主機產生器時,下列變數會提早鎖定,且無法受到應用程式組態的影響:

所有其他主機設定都是從應用程式組態讀取,而不是主機組態。

URLS 是許多不是啟動程式設定的常見主機設定之一。 如同上一個清單中的其他每個主機設定, URLS 稍後會從應用程式組態讀取。主機組態是應用程式組態的後援,因此可以使用主機組態來設定 URLS ,但會由應用程式組態中的任何組態來源覆寫,例如 appsettings.json

如需詳細資訊,請參閱 變更內容根目錄、應用程式名稱和環境 ,以及 依環境變數或命令列變更內容根目錄、應用程式名稱和環境

本文的其餘章節會參考應用程式組態。

應用程式設定提供者

下列程式碼會依新增的順序顯示啟用的組態提供者:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

上述 最高優先順序到最低優先順序的預設組態來源清單 會以相反的順序顯示提供者新增至範本產生的應用程式。 例如,ON 組 JS 態提供者會在命令列組態提供者之前新增。

稍後新增的組態提供者具有較高的優先順序,並覆寫先前的金鑰設定。 例如,如果在 MyKey 和 環境中設定 appsettings.json ,則會使用環境值。 使用預設組態提供者, 命令列組態提供者 會覆寫所有其他提供者。

如需 的詳細資訊 CreateBuilder ,請參閱 預設產生器設定

appsettings.json

請考慮下列 appsettings.json 檔案:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

下列來自 範例下載 的程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

預設 JsonConfigurationProvider 會依下列順序載入組態:

  1. appsettings.json
  2. appsettings.{Environment}.json :例如 和 appsettings.Production.jsonappsettings.Development.json 檔案。 檔案的環境版本會根據 IHostingEnvironment.EnvironmentName 載入。 如需詳細資訊,請參閱在 ASP.NET Core 中使用多個環境

appsettings.{Environment}.json 值會覆寫 中的 appsettings.json 索引鍵。 例如,根據預設:

  • 在開發中, appsettings.Development.json 組態會覆寫 中找到 appsettings.json 的值。
  • 在生產環境中, appsettings.Production.json 組態會覆寫 中找到 appsettings.json 的值。 例如,將應用程式部署至 Azure 時。

如果必須保證組態值,請參閱 GetValue。 上述範例只會讀取字串,且不支援預設值。

使用預設組態, appsettings.json 會使用reloadOnChange啟用 和 appsettings.{Environment}.json 檔案:true。 ON 組態提供者會讀取 JS應用程式啟動之後對 和 appsettings.{Environment}.json 檔案所做的 appsettings.json 變更。

使用選項模式系結階層式設定資料

讀取相關組態值的慣用方式是使用 選項模式。 例如,若要讀取下列組態值:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

建立下列 PositionOptions 類別:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

選項類別:

  • 必須是非抽象的公用無參數建構函式。
  • 類型的所有公用讀寫屬性都會系結。
  • 欄位 系結。 在上述程式碼中, Position 未系結。 使用 Position 欄位,因此將類別系結至組態提供者時,不需要在應用程式中硬式編碼字串 "Position"

下列程式碼:

  • 呼叫 ConfigurationBinder.Bind ,將 PositionOptions 類別系結至 區 Position 段。
  • 顯示組 Position 態資料。
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上述程式碼中,根據預設,會在讀取應用程式之後變更 JS ON 組態檔。

ConfigurationBinder.Get<T> 會系結並傳回指定的型別。 ConfigurationBinder.Get<T>比使用 更方便。 ConfigurationBinder.Bind 下列程式碼示範如何搭配 PositionOptions 類別使用 ConfigurationBinder.Get<T>

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上述程式碼中,根據預設,會在讀取應用程式之後變更 JS ON 組態檔。

使用 選項模式 時的替代方法是系結 Position 區段,並將其新增至 相依性插入服務容器。 在下列程式碼中, PositionOptions 會新增至服務容器,並系 Configure 結至組態:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

使用上述程式碼,下列程式碼會讀取位置選項:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

在上述程式碼中,不會讀取應用程式啟動後的 ON 組態檔變更 JS 。 若要在應用程式啟動之後讀取變更,請使用 IOptionsSnapshot

使用預設組態, appsettings.json 會使用reloadOnChange啟用 和 appsettings.{Environment}.json 檔案:true。 ON 組態提供者會讀取 JS應用程式啟動之後對 和 appsettings.{Environment}.json 檔案所做的 appsettings.json 變更。

如需新增其他 JS ON 組態檔的資訊,請參閱JS本檔中的 ON 組態提供者。

結合服務集合

請考慮下列專案來註冊服務和設定選項:

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

相關的註冊群組可以移至擴充方法以註冊服務。 例如,組態服務會新增至下列類別:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }
    }
}

其餘服務會在類似的類別中註冊。 下列程式碼會使用新的擴充方法來註冊服務:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

注意: 每個 services.Add{GROUP_NAME} 擴充方法都會新增並可能設定服務。 例如, AddControllersWithViews 新增具有檢視所需的 MVC 控制器服務,並 AddRazorPages 新增頁面所需的服務 Razor 。 我們建議應用程式遵循在 命名空間中建立擴充方法的 Microsoft.Extensions.DependencyInjection 命名慣例。 在 Microsoft.Extensions.DependencyInjection 命名空間中建立擴充方法:

安全性和使用者密碼

設定資料指導方針:

  • 永遠不要將密碼或其他敏感性資料儲存在設定提供者程式碼或純文字設定檔中。 秘密管理員工具可用來在開發中儲存秘密。
  • 不要在開發或測試環境中使用生產環境祕密。
  • 請在專案外部指定祕密,以防止其意外認可至開放原始碼存放庫。

根據 預設,使用者密碼設定來源會在 ON 設定來源之後 JS 註冊。 因此,使用者秘密金鑰的優先順序高於 和 appsettings.{Environment}.json 中的 appsettings.json 金鑰。

如需儲存密碼或其他敏感性資料的詳細資訊:

Azure Key Vault 可安全地儲存 ASP.NET Core 應用程式的應用程式祕密。 如需詳細資訊,請參閱ASP.NET Core 中的 Azure 金鑰保存庫組態提供者

非前置詞環境變數

非前置詞環境變數是 或 前置詞以外的 ASPNETCORE_DOTNET_ 環境變數。 例如,在 中 launchSettings.json 設定 "ASPNETCORE_ENVIRONMENT": "Development" ASP.NET Core Web 應用程式範本。 如需 和 DOTNET_ 環境變數的詳細資訊 ASPNETCORE_ ,請參閱:

使用 預設 組態,會在 EnvironmentVariablesConfigurationProvider 讀取 appsettings.jsonappsettings.{Environment}.json 和 使用者密碼之後,從環境變數索引鍵/值組載入 組態。 因此,從環境讀取的索引鍵值會覆寫讀取自 appsettings.jsonappsettings.{Environment}.json 和 使用者密碼的值。

分隔 : 符不適用於所有平臺上的環境變數階層式索引鍵。 __,雙底線為:

  • 所有平臺都支援。 例如, :Bash不支援分隔符號,但 __ 是 。
  • 自動取代為 :

下列 set 命令:

  • 在 Windows 上設定 上述範例 的環境索引鍵和值。
  • 使用 範例下載時測試設定。 dotnet run命令必須在專案目錄中執行。
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

上述環境設定:

  • 只會在從所設定命令視窗啟動的進程中設定。
  • 不會由使用 Visual Studio 啟動的瀏覽器讀取。

下列 setx 命令可用來在 Windows 上設定環境索引鍵和值。 不同于 setsetx 會保存設定。 /M 會設定系統內容中的變數。 /M如果未使用參數,則會設定使用者環境變數。

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

若要測試上述命令覆寫 appsettings.jsonappsettings.{Environment}.json

  • 使用 Visual Studio:結束並重新啟動 Visual Studio。
  • 使用 CLI:啟動新的命令視窗,然後輸入 dotnet run

使用字串呼叫 AddEnvironmentVariables ,以指定環境變數的前置詞:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");

var app = builder.Build();

在上述程式碼中:

  • builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_") 會在 預設組態提供者之後新增。 如需排序設定提供者的範例,請參閱JS ON 組態提供者
  • 以前置詞設定的 MyCustomPrefix_ 環境變數會覆寫 預設組態提供者。 這包括不含前置詞的環境變數。

讀取組態索引鍵/值組時,會移除前置詞。

下列命令會測試自訂前置詞:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

預設組態會載入前面加上 和 ASPNETCORE_DOTNET_ 環境變數和命令列引數。 和 DOTNET_ASPNETCORE_ 前置詞是由主機和應用程式組態ASP.NET Core使用,但不適用於使用者設定。 如需主機和應用程式設定的詳細資訊,請參閱 .NET 泛型主機

Azure App 服務上,選取 [設定 > 組態] 頁面上的 [新增應用程式設定]。 Azure App 服務應用程式設定如下:

  • 待用加密,並透過加密通道傳輸。
  • 公開為環境變數。

如需詳細資訊,請參閱 Azure App:使用 Azure 入口網站覆寫應用程式設定

如需 Azure 資料庫連接字串的相關資訊,請參閱 連接字串前置 詞。

環境變數的命名

環境變數名稱會反映檔案的結構 appsettings.json 。 階層中的每個元素都會以雙底線分隔, (最好) 或冒號。 當專案結構包含陣列時,陣列索引應該視為這個路徑中的其他專案名稱。 請考慮下列 appsettings.json 檔案及其表示為環境變數的對等值。

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

環境變數

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

在產生的 launchSettings.json 中設定的環境變數

在 中 launchSettings.json 設定的環境變數會覆寫系統內容中的環境變數。 例如,ASP.NET Core Web 範本會產生檔案 launchSettings.json ,將端點組態設定設為:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

applicationUrl設定 環境變數, ASPNETCORE_URLS 並覆寫環境中設定的值。

在 Linux 上逸出環境變數

在 Linux 上,URL 環境變數的值必須逸出,以便 systemd 剖析它。 使用會產生的 Linux 工具 systemd-escapehttp:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

顯示環境變數

下列程式碼會顯示應用程式啟動時的環境變數和值,在偵錯環境設定時可能會很有説明:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

命令列

使用 預設 組態,會在 CommandLineConfigurationProvider 下列組態來源之後,從命令列引數索引鍵/值組載入組態:

根據 預設,命令列上設定的組態值會覆寫以所有其他組態提供者所設定的組態值。

命令列引數

下列命令會使用 = 來設定索引鍵和值:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

下列命令會使用 / 來設定索引鍵和值:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

下列命令會使用 -- 來設定索引鍵和值:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

索引鍵值:

  • 必須遵循 = ,或索引鍵必須具有 前置詞 -- ,或 / 值在空格之後時。
  • 如果使用 = ,則不需要 。 例如: MySetting=

在相同的命令中,請勿混合命令列引數索引鍵/值組,這些組搭配 = 使用空格的索引鍵/值組。

切換對應

切換對應允許 金鑰 名稱取代邏輯。 提供 參數取代的字典給 AddCommandLine 方法。

使用切換對應字典時,會檢查字典中是否有任何索引鍵符合命令列引數所提供的索引鍵。 如果在字典中找到命令列索引鍵,則會將字典值傳回,以將機碼/值組設定為應用程式的組態。 所有前面加上單虛線 (-) 的命令列索引鍵都需要切換對應。

切換對應字典索引鍵規則:

  • 參數必須以 --- 開頭。
  • 切換對應字典不能包含重複索引鍵。

若要使用參數對應字典,請將它傳遞至 的 AddCommandLine 呼叫:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

執行下列命令可測試金鑰取代:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

下列程式碼顯示已取代索引鍵的索引鍵值:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

針對使用切換對應的應用程式,呼叫 CreateDefaultBuilder 不應傳遞引數。 方法 CreateDefaultBuilderAddCommandLine 呼叫不包含對應的參數,而且沒有任何方法可將參數對應字典傳遞至 CreateDefaultBuilder 。 解決方案不會將引數傳遞至 CreateDefaultBuilder ,而是允許 ConfigurationBuilder 方法 AddCommandLine 的 方法同時處理引數和參數對應字典。

使用 Visual Studio 設定環境和命令列引數

您可以從 [啟動設定檔] 對話方塊,在 Visual Studio 中設定環境和命令列引數:

  • 在 方案總管 中,以滑鼠右鍵按一下專案,然後選取 [屬性]。
  • 選取 [ 偵錯一般] > 索引標籤,然後選取 [開啟偵錯啟動設定檔 UI]。

階層式設定資料

組態 API 會透過在組態索引鍵中使用分隔符號來扁平化階層式資料,以讀取階層式設定資料。

範例下載包含下列 appsettings.json 檔案:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

下列 範例下載 程式碼會顯示數個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

讀取階層式設定資料的慣用方式是使用選項模式。 如需詳細資訊,請參閱本檔中的 系結階層式設定資料

GetSectionGetChildren 方法可用來在設定資料中隔離區段與區段的子系。 GetSection,、 GetChildren 與 Exists 中說明這些方法。

組態索引鍵和值

設定金鑰:

  • 不區分大小寫。 例如,ConnectionStringconnectionstring 會被視為相等的機碼。
  • 如果索引鍵和值是在多個組態提供者中設定,則會使用上一個新增提供者的值。 如需詳細資訊,請參閱 預設組態
  • 階層式機碼
    • 在設定 API 內,冒號分隔字元 (:) 可在所有平台上運作。
    • 在環境變數中,冒號分隔字元可能無法在所有平台上運作。 所有平臺都支援雙底線 __ ,而且會自動轉換成冒號 :
    • 在 Azure 金鑰保存庫中,階層式索引鍵會作為分隔符號使用 -- 。 當秘密載入應用程式組態時,Azure 金鑰保存庫組態提供者會自動將 取代 --: 為 。
  • ConfigurationBinder 支援在設定機碼中使用陣列索引將陣列繫結到物件。 將陣列繫結到類別一節說明陣列繫結。

組態值:

  • 是字串。
  • Null 值無法存放在設定中或繫結到物件。

設定提供者

下表顯示可供 ASP.NET Core 應用程式使用的設定提供者。

提供者 從提供設定
Azure 金鑰保存庫設定提供者 Azure Key Vault
Azure App設定提供者 Azure 應用程式組態
命令列組態提供者 命令列參數
自訂設定提供者 自訂來源
環境變數組態提供者 環境變數
檔案組態提供者 INI、 JS ON 和 XML 檔案
每個檔案的金鑰組態提供者 目錄檔案
記憶體設定提供者 記憶體內集合
使用者祕密 使用者設定檔目錄中的檔案

設定來源會依其設定提供者的指定順序來讀取。 排序程式代碼中的組態提供者,以符合應用程式所需的基礎組態來源優先順序。

典型的設定提供者順序是:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. 使用者祕密
  4. 使用 環境變數組態提供者的環境變數
  5. 使用命令列組 態提供者的命令列引數。

常見的作法是在一系列提供者中最後新增命令列組態提供者,以允許命令列引數覆寫其他提供者所設定的組態。

上述提供者序列用於 預設組態中。

連接字串前置詞

組態 API 有四個連接字串環境變數的特殊處理規則。 這些連接字串牽涉到為應用程式環境設定 Azure 連接字串。 資料表中所顯示前置詞的環境變數會以 預設組態 載入至應用程式,或未提供前置詞給 AddEnvironmentVariables 時。

連接字串前置詞 提供者
CUSTOMCONNSTR_ 自訂提供者
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

當探索到具有下表所顯示之任何四個前置詞的環境變數並將其載入到設定中時:

  • 會透過移除環境變數前置詞並新增設定機碼區段 (ConnectionStrings) 來移除具有下表顯示之前置詞的環境變數。
  • 會建立新的設定機碼值組以代表資料庫連線提供者 (CUSTOMCONNSTR_ 除外,這沒有所述提供者)。
環境變數機碼 已轉換的設定機碼 提供者設定項目
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} 設定項目未建立。
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:System.Data.SqlClient

檔案組態提供者

FileConfigurationProvider 是用於從檔案系統載入設定的基底類別。 下列組態提供者衍生自 FileConfigurationProvider

INI 設定提供者

IniConfigurationProvider 會在執行階段從 INI 檔案機碼值組載入設定。

下列程式碼會清除所有組態提供者,並新增數個組態提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    var env = hostingContext.HostingEnvironment;

    config.AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
          .AddIniFile($"MyIniConfig.{env.EnvironmentName}.ini",
                         optional: true, reloadOnChange: true);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

在上述程式碼中 MyIniConfig.ini ,和 MyIniConfig.{Environment}.ini 檔案中的設定會由 下列中的設定覆寫:

範例下載包含下列 MyIniConfig.ini 檔案:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

下列來自 範例下載 的程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

JSON 設定提供者

JsonConfigurationProvider 從 JS ON 檔案機碼/值組載入組態。

多載可以指定:

  • 檔案是否為選擇性。
  • 檔案變更時是否要重新載入設定。

請考慮下列程式碼:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MyConfig.json",
                       optional: true,
                       reloadOnChange: true);
});

builder.Services.AddRazorPages();

var app = builder.Build();

上述程式碼:

  • 設定 ON 組 JS 態提供者以使用下列選項載入 MyConfig.json 檔案:
    • optional: true:檔案是選擇性的。
    • reloadOnChange: true :儲存變更時會重載檔案。
  • 讀取檔案之前 MyConfig.json的預設組態提供者。 預設組態提供者中 MyConfig.json 檔案覆寫設定中的設定,包括 環境變數組態提供者命令列組態提供者

您通常 不希望 自訂 JS ON 檔案覆寫 環境變數組態提供者命令列組態提供者中所設定的值。

XML 組態提供者

XmlConfigurationProvider 會在執行階段從 XML 檔案機碼值組載入設定。

下列程式碼會清除所有組態提供者,並新增數個組態提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    var env = hostingContext.HostingEnvironment;

    config.AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
          .AddXmlFile($"MyXMLFile.{env.EnvironmentName}.xml",
                         optional: true, reloadOnChange: true);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

在上述程式碼中 MyXMLFile.xml ,和 MyXMLFile.{Environment}.xml 檔案中的設定會由 下列中的設定覆寫:

範例下載包含下列 MyXMLFile.xml 檔案:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

下列來自 範例下載 的程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

name 屬性是用來區別元素,則可以重複那些使用相同元素名稱的元素:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

下列程式碼會讀取先前的組態檔,並顯示索引鍵和值:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

屬性可用來提供值:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

先前的設定檔會使用 value 載入下列機碼:

  • key:attribute
  • section:key:attribute

每個檔案的金鑰組態提供者

KeyPerFileConfigurationProvider 使用目錄的檔案做為設定機碼值組。 機碼是檔案名稱。 值包含檔案的內容。 Docker 裝載案例中會使用每個檔案的金鑰組態提供者。

若要啟用每個檔案機碼設定,請在 ConfigurationBuilder 的執行個體上呼叫 AddKeyPerFile 延伸模組方法。 檔案的 directoryPath 必須是絕對路徑。

多載允許指定:

  • 設定來源的 Action<KeyPerFileConfigurationSource> 委派。
  • 目錄是否為選擇性與目錄的路徑。

雙底線 (__) 是做為檔案名稱中的設定金鑰分隔符號使用。 例如,檔案名稱 Logging__LogLevel__System 會產生設定金鑰 Logging:LogLevel:System

建置主機時呼叫 ConfigureAppConfiguration 以指定應用程式的設定:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

記憶體設定提供者

MemoryConfigurationProvider 使用記憶體內集合做為設定機碼值組。

下列程式碼會將記憶體集合新增至組態系統:

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    config.AddInMemoryCollection(Dict);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

下列來自 範例下載 的程式碼會顯示上述組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

在上述程式碼中, config.AddInMemoryCollection(Dict) 會在預設組 態提供者之後新增。 如需排序設定提供者的範例,請參閱JS ON 組態提供者

如需使用 的另一個範例 MemoryConfigurationProvider,請參閱系結陣列

Kestrel 端點組態

Kestrel 特定端點組態會覆寫所有 跨伺服器端 點組態。 跨伺服器端點組態包括:

請考慮 ASP.NET Core Web 應用程式中使用的下列 appsettings.json 檔案:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

當上述反白顯示的標記用於 ASP.NET Core Web 應用程式,應用程式會在命令列上啟動,並具有下列跨伺服器端點組態:

dotnet run --urls="https://localhost:7777"

Kestrel 系結至檔案中特別針對 Kestrel 設定的 appsettings.json 端點 () https://localhost:9999 ,而不是 https://localhost:7777

請考慮設定 Kestrel 為環境變數的特定端點:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

在上述環境變數中, Https 是特定端點的名稱 Kestrel 。 上述 appsettings.json 檔案也會定義 Kestrel 名為 Https 的特定端點。 根據 預設,使用 環境變數組態提供者的環境變數 會在 之後 appsettings.{Environment}.json 讀取,因此會針對 Https 端點使用上述環境變數。

GetValue

ConfigurationBinder.GetValue 從具有指定索引鍵的組態中擷取單一值,並將它轉換成指定的類型:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

在上述程式碼中,如果在 NumberKey 組態中找不到 ,則會使用 的 99 預設值。

GetSection、GetChildren 與 Exists

針對下列範例,請考慮下列 MySubsection.json 檔案:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

下列程式碼會新增 MySubsection.json 至組態提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MySubsection.json",
                       optional: true,
                       reloadOnChange: true);
});

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection 會傳回具有指定之子區段索引鍵的組態子區段。

下列程式碼會傳回 的值 section1

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

下列程式碼會傳回 的值 section2:subsection0

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection 絕不會傳回 null。 若找不到相符的區段,會傳回空的 IConfigurationSection

GetSection 傳回相符區段時,未填入 Value。 當區段存在時,會傳回 KeyPath

GetChildren 和 Exists

下列程式碼會呼叫 IConfiguration.GetChildren 並傳回 的值 section2:subsection0

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

上述程式碼會呼叫 ConfigurationExtensions.Exists 以確認 區段存在:

系結陣列

ConfigurationBinder.Bind 支援在設定機碼中使用陣列索引將陣列繫結到物件。 公開數值索引鍵區段的任何陣列格式都能夠系結至 POCO 類別陣列。

請考慮 MyArray.json範例下載

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

下列程式碼會新增 MyArray.json 至組態提供者:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MyArray.json",
                        optional: true,
                        reloadOnChange: true); ;
});

builder.Services.AddRazorPages();

var app = builder.Build();

下列程式碼會讀取組態並顯示值:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

上述程式碼會傳回下列輸出:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

在上述輸出中,索引 3 具有值 value40 ,對應至 "4": "value40", 中的 MyArray.json 。 系結陣列索引是連續的,而且不會系結至組態索引鍵索引。 組態系結器無法系結 Null 值,或是在系結物件中建立 Null 專案。

自訂設定提供者

範例應用程式示範如何建立會使用 Entity Framework (EF) 從資料庫讀取設定機碼值組的基本設定提供者。

提供者具有下列特性:

  • EF 記憶體內資料庫會用於示範用途。 若要使用需要連接字串的資料庫,請實作第二個 ConfigurationBuilder 以從另一個設定提供者提供連接字串。
  • 啟動時,該提供者會將資料庫資料表讀入到設定中。 該提供者不會以個別機碼為基礎查詢資料庫。
  • 未實作變更時重新載入,因此在應用程式啟動後更新資料庫對應用程式設定沒有影響。

定義 EFConfigurationValue 實體來在資料庫中存放設定值。

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

新增 EFConfigurationContext 以存放及存取已設定的值。

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

建立會實作 IConfigurationSource 的類別。

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

透過繼承自 ConfigurationProvider 來建立自訂設定提供者。 若資料庫是空的,設定提供者會初始化資料庫。 由於組態索引鍵不區分大小寫,因此用來初始化資料庫的字典會以不區分大小寫的比較子建立, (StringComparer.OrdinalIgnoreCase) 。

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

AddEFConfiguration 擴充方法允許新增設定來源到 ConfigurationBuilder

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

下列程式碼示範如何使用 中的 Program.cs 自訂 EFConfigurationProvider

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

使用相依性插入 (DI) 存取設定

設定可藉由解析 IConfiguration 服務,使用相依性插入 (DI) 插入服務:

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

如需如何使用 存取值 IConfiguration 的資訊,請參閱本文中的 GetValueGetSection、GetChildren 和 Exists

存取頁面中的組態 Razor

下列程式碼會在 Page 中顯示組 Razor 態資料:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

在下列程式碼中, MyOptions 會新增至服務容器,並系 Configure 結至組態:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

下列標記會使用 @injectRazor 指示詞來解析及顯示選項值:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

存取 MVC 檢視檔案中的組態

下列程式碼會在 MVC 檢視中顯示組態資料:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

使用委派設定選項

在組態提供者中設定的委派覆寫值中所設定的選項。

在下列程式碼中, IConfigureOptions<TOptions> 服務會新增至服務容器。 它會使用委派來設定 的值 MyOptions

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

下列程式碼會顯示選項值:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

在上述範例中,和 Option2 的值 Option1 是在 中 appsettings.json 指定,然後由已設定的委派覆寫。

主機與應用程式組態的比較

設定及啟動應用程式之前,會先設定及啟動「主機」。 主機負責應用程式啟動和存留期管理。 應用程式與主機都是使用此主題中所述的設定提供者來設定的。 主機組態機碼/值組也會包含在應用程式的組態中。 如需在建置主機時如何使用組態提供者,以及設定來源如何影響主機設定的詳細資訊,請參閱ASP.NET Core基本概觀

預設主機組態

如需使用 Web 主機時預設組態的詳細資料,請參閱本主題的 ASP.NET Core 2.2 版本

  • 主機組態的提供來源:
    • 環境變數前面加上 DOTNET_ (,例如, DOTNET_ENVIRONMENT 使用 環境變數組態提供者) 。 載入設定機碼值組時,會移除前置詞 (DOTNET_)。
    • 使用命令列組 態提供者的命令列引數。
  • 已建立 Web 主機預設組態 (ConfigureWebHostDefaults):
    • Kestrel 會當做 Web 服務器使用,並使用應用程式的組態提供者進行設定。
    • 新增主機篩選中介軟體。
    • 如果 ASPNETCORE_FORWARDEDHEADERS_ENABLED 環境變數設定為 true,則會新增轉接的標頭中介軟體。
    • 啟用 IIS 整合。

其他設定

本主題僅適用于 應用程式設定。 執行和裝載 ASP.NET Core應用程式的其他層面是使用本主題未涵蓋的組態檔來設定:

中設定的 launchSettings.json 環境變數會覆寫系統內容中的環境變數。

如需從舊版 ASP.NET 移轉應用程式組態的詳細資訊,請參閱從 ASP.NET 移轉至 ASP.NET Core

從外部組件新增設定

IHostingStartup 實作允許在啟動時從應用程式 Startup 類別外部的外部組件,針對應用程式新增增強功能。 如需詳細資訊,請參閱在 ASP.NET Core 中使用裝載啟動元件

其他資源

ASP.NET Core中的設定是使用一或多個組態提供者來執行。 組態提供者會使用各種組態來源,從機碼/值組讀取組態資料:

  • 設定檔案,例如 appsettings.json
  • 環境變數
  • Azure Key Vault
  • Azure 應用程式組態
  • 命令列引數
  • 自訂提供者、安裝或建立
  • 目錄檔案
  • 記憶體內部 .NET 物件

本主題提供 ASP.NET Core中的組態資訊。 如需在主控台應用程式中使用組態的資訊,請參閱 .NET 組態

檢視或下載範例程式碼 (如何下載)

預設組態

ASP.NET Core使用dotnet new或 Visual Studio 建立的 Web 應用程式會產生下列程式碼:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

CreateDefaultBuilder 會以下列順序提供應用程式的預設組態:

  1. ChainedConfigurationProvider :將現有的 IConfiguration 新增為來源。 在預設組態案例中,新增 主機 組態,並將它設定為 應用程式 組態的第一個來源。
  2. appsettings.json使用 ON 組JS 態提供者
  3. appsettings.{Environment}.json使用 ON 組JS 態提供者。 例如,appsettings.Production.jsonappsettings.Development.json
  4. 應用程式Development 環境中執行時的應用程式秘密。
  5. 使用 環境變數組態提供者的環境變數
  6. 使用命令列組 態提供者的命令列引數。

稍後新增的組態提供者會覆寫先前的金鑰設定。 例如,如果在 MyKey 和 環境中設定 appsettings.json ,則會使用環境值。 使用預設組態提供者, 命令列組態提供者 會覆寫所有其他提供者。

如需 的詳細資訊 CreateDefaultBuilder ,請參閱 預設產生器設定

下列程式碼會依新增的順序顯示啟用的組態提供者:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

appsettings.json

請考慮下列 appsettings.json 檔案:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey":  "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

下列來自 範例下載 的程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

預設 JsonConfigurationProvider 會依下列順序載入組態:

  1. appsettings.json
  2. appsettings.{Environment}.json :例如 和 appsettings.Production.jsonappsettings.Development.json 檔案。 檔案的環境版本會根據 IHostingEnvironment.EnvironmentName 載入。 如需詳細資訊,請參閱在 ASP.NET Core 中使用多個環境

appsettings.{Environment}.json 值會覆寫 中的 appsettings.json 索引鍵。 例如,根據預設:

  • 在開發中, appsettings.Development.json 組態會覆寫 中找到 appsettings.json 的值。
  • 在生產環境中, appsettings.Production.json 組態會覆寫 中找到 appsettings.json 的值。 例如,將應用程式部署至 Azure 時。

如果必須保證組態值,請參閱 GetValue。 上述範例只會讀取字串,且不支援預設值。

使用預設組態, appsettings.json 會使用reloadOnChange啟用 和 appsettings.{Environment}.json 檔案:true。 ON 組態提供者會讀取 JS應用程式啟動之後對 和 appsettings.{Environment}.json 檔案所做的 appsettings.json 變更。

使用選項模式系結階層式設定資料

讀取相關組態值的慣用方式是使用 選項模式。 例如,若要讀取下列組態值:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

建立下列 PositionOptions 類別:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; }
    public string Name { get; set; }
}

選項類別:

  • 必須是非抽象的公用無參數建構函式。
  • 類型的所有公用讀寫屬性都會系結。
  • 欄位 系結。 在上述程式碼中, Position 未系結。 使用 Position 屬性,因此將類別系結至組態提供者時,不需要在應用程式中硬式編碼字串 "Position"

下列程式碼:

  • 呼叫 ConfigurationBinder.Bind ,將 PositionOptions 類別系結至 區 Position 段。
  • 顯示組 Position 態資料。
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上述程式碼中,根據預設,會在讀取應用程式之後變更 JS ON 組態檔。

ConfigurationBinder.Get<T> 會系結並傳回指定的型別。 ConfigurationBinder.Get<T>比使用 更方便。 ConfigurationBinder.Bind 下列程式碼示範如何搭配 PositionOptions 類別使用 ConfigurationBinder.Get<T>

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上述程式碼中,根據預設,會在讀取應用程式之後變更 JS ON 組態檔。

使用 選項模式 時的替代方法是系結 Position 區段,並將其新增至 相依性插入服務容器。 在下列程式碼中, PositionOptions 會新增至服務容器,並系 Configure 結至組態:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(Configuration.GetSection(
                                        PositionOptions.Position));
    services.AddRazorPages();
}

使用上述程式碼,下列程式碼會讀取位置選項:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

在上述程式碼中,不會讀取應用程式啟動之後的 ON 組態檔變更 JS 。 若要在應用程式啟動之後讀取變更,請使用 IOptionsSnapshot

使用預設組態時, appsettings.json 會以reloadOnChange 啟用appsettings.{Environment}.json 檔案:true。 在應用程式啟動時對 和 appsettings.{Environment}.json檔案所做的appsettings.json 變更會由JS ON 組態提供者讀取。

如需新增其他 JS ON 組態檔的相關資訊,請參閱JS本檔中的 ON 組態提供者。

合併服務集合

請考慮下列 ConfigureServices 方法,其會註冊服務和設定選項:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(
        Configuration.GetSection(PositionOptions.Position));
    services.Configure<ColorOptions>(
        Configuration.GetSection(ColorOptions.Color));

    services.AddScoped<IMyDependency, MyDependency>();
    services.AddScoped<IMyDependency2, MyDependency2>();

    services.AddRazorPages();
}

相關的註冊群組可以移至擴充方法以註冊服務。 例如,組態服務會新增至下列類別:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }
    }
}

其餘服務會註冊在類似的類別中。 下列 ConfigureServices 方法會使用新的擴充方法來註冊服務:

public void ConfigureServices(IServiceCollection services)
{
    services.AddConfig(Configuration)
            .AddMyDependencyGroup();

    services.AddRazorPages();
}

注意: 每個 services.Add{GROUP_NAME} 擴充方法都會新增並可能設定服務。 例如, AddControllersWithViews 新增具有檢視所需的 MVC 控制器服務,並 AddRazorPages 新增 Pages 所需的服務 Razor 。 我們建議應用程式遵循在命名空間中建立擴充方法的 Microsoft.Extensions.DependencyInjection 命名慣例。 在命名空間中 Microsoft.Extensions.DependencyInjection 建立擴充方法:

安全性和使用者密碼

設定資料指導方針:

  • 永遠不要將密碼或其他敏感性資料儲存在設定提供者程式碼或純文字設定檔中。 秘密管理員工具可用來將秘密儲存在開發中。
  • 不要在開發或測試環境中使用生產環境祕密。
  • 請在專案外部指定祕密,以防止其意外認可至開放原始碼存放庫。

根據 預設,使用者秘密組態來源會在 ON 組態來源之後 JS 註冊。 因此,使用者秘密金鑰的優先順序高於 和 appsettings.{Environment}.json 中的 appsettings.json 金鑰。

如需儲存密碼或其他敏感性資料的詳細資訊:

Azure Key Vault 可安全地儲存 ASP.NET Core 應用程式的應用程式祕密。 如需詳細資訊,請參閱ASP.NET Core 中的 Azure 金鑰保存庫組態提供者

環境變數

使用 預設 組態,會在 EnvironmentVariablesConfigurationProvider 讀取 appsettings.jsonappsettings.{Environment}.json 和 使用者密碼之後,從環境變數索引鍵/值組載入 組態。 因此,從環境讀取的索引鍵值會覆寫讀取自 appsettings.jsonappsettings.{Environment}.json 和 使用者密碼的值。

分隔 : 符不適用於所有平臺上的環境變數階層式索引鍵。 __,雙底線為:

  • 所有平臺都支援。 例如, :Bash不支援分隔符號,但 __ 是 。
  • 自動取代為 :

下列 set 命令:

  • 在 Windows 上設定 上述範例 的環境索引鍵和值。
  • 使用 範例下載時測試設定。 dotnet run命令必須在專案目錄中執行。
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

上述環境設定:

  • 只會在從所設定命令視窗啟動的進程中設定。
  • 不會由使用 Visual Studio 啟動的瀏覽器讀取。

下列 setx 命令可用來在 Windows 上設定環境索引鍵和值。 不同于 setsetx 會保存設定。 /M 會設定系統內容中的變數。 /M如果未使用參數,則會設定使用者環境變數。

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

若要測試上述命令覆寫 appsettings.jsonappsettings.{Environment}.json

  • 使用 Visual Studio:結束並重新啟動 Visual Studio。
  • 使用 CLI:啟動新的命令視窗,然後輸入 dotnet run

使用字串呼叫 AddEnvironmentVariables ,以指定環境變數的前置詞:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在上述程式碼中:

讀取組態索引鍵/值組時,會移除前置詞。

下列命令會測試自訂前置詞:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

預設組態會載入前面加上 和 ASPNETCORE_DOTNET_ 環境變數和命令列引數。 和 DOTNET_ASPNETCORE_ 前置詞是由主機和應用程式組態ASP.NET Core使用,但不適用於使用者設定。 如需主機和應用程式設定的詳細資訊,請參閱 .NET 泛型主機

Azure App 服務上,選取 [設定 > 組態] 頁面上的 [新增應用程式設定]。 Azure App 服務應用程式設定如下:

  • 待用加密,並透過加密通道傳輸。
  • 公開為環境變數。

如需詳細資訊,請參閱 Azure App:使用 Azure 入口網站覆寫應用程式設定

如需 Azure 資料庫連接字串的相關資訊,請參閱 連接字串前置 詞。

環境變數的命名

環境變數名稱會反映檔案的結構 appsettings.json 。 階層中的每個元素都會以雙底線分隔, (最好) 或冒號。 當專案結構包含陣列時,陣列索引應該視為這個路徑中的其他專案名稱。 請考慮下列 appsettings.json 檔案及其表示為環境變數的對等值。

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

環境變數

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

在產生的 launchSettings.json 中設定的環境變數

在 中 launchSettings.json 設定的環境變數會覆寫系統內容中的環境變數。 例如,ASP.NET Core Web 範本會產生檔案 launchSettings.json ,將端點組態設定設為:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

applicationUrl設定 環境變數, ASPNETCORE_URLS 並覆寫環境中設定的值。

在 Linux 上逸出環境變數

在 Linux 上,URL 環境變數的值必須逸出,以便 systemd 剖析它。 使用會產生的 Linux 工具 systemd-escapehttp:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

顯示環境變數

下列程式碼會顯示應用程式啟動時的環境變數和值,在偵錯環境設定時可能會很有説明:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var config = host.Services.GetRequiredService<IConfiguration>();

    foreach (var c in config.AsEnumerable())
    {
        Console.WriteLine(c.Key + " = " + c.Value);
    }
    host.Run();
}

命令列

使用 預設 組態,會在 CommandLineConfigurationProvider 下列組態來源之後,從命令列引數索引鍵/值組載入組態:

根據 預設,命令列上設定的組態值會覆寫以所有其他組態提供者所設定的組態值。

命令列引數

下列命令會使用 = 來設定索引鍵和值:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

下列命令會使用 / 來設定索引鍵和值:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

下列命令會使用 -- 來設定索引鍵和值:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

索引鍵值:

  • 必須遵循 = ,或索引鍵必須具有 前置詞 -- ,或 / 值在空格之後時。
  • 如果使用 = ,則不需要 。 例如: MySetting=

在相同的命令中,請勿混合命令列引數索引鍵/值組,這些組搭配 = 使用空格的索引鍵/值組。

切換對應

切換對應允許 金鑰 名稱取代邏輯。 提供 參數取代的字典給 AddCommandLine 方法。

使用切換對應字典時,會檢查字典中是否有任何索引鍵符合命令列引數所提供的索引鍵。 如果在字典中找到命令列索引鍵,則會將字典值傳回,以將機碼/值組設定為應用程式的組態。 所有前面加上單虛線 (-) 的命令列索引鍵都需要切換對應。

切換對應字典索引鍵規則:

  • 參數必須以 --- 開頭。
  • 切換對應字典不能包含重複索引鍵。

若要使用參數對應字典,請將它傳遞至 的 AddCommandLine 呼叫:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddCommandLine(args, switchMappings);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

下列程式碼顯示已取代索引鍵的索引鍵值:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

下列命令適用于測試金鑰取代:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

針對使用切換對應的應用程式,呼叫 CreateDefaultBuilder 不應傳遞引數。 方法 CreateDefaultBuilderAddCommandLine 呼叫不包含對應的參數,而且沒有任何方法可將參數對應字典傳遞至 CreateDefaultBuilder 。 解決方案不會將引數傳遞至 CreateDefaultBuilder ,而是允許 ConfigurationBuilder 方法 AddCommandLine 的 方法同時處理引數和參數對應字典。

使用 Visual Studio 設定環境和命令列引數

下圖顯示使用 Visual Studio 設定環境和命令列引數:

VS 的 [偵錯] 索引標籤

在 Visual Studio 2019 16.10 版 Preview 4 和更新版本中,從啟動設定檔 UI 完成設定環境和命令列引數:

啟動設定檔 UI

階層式設定資料

組態 API 會透過在組態索引鍵中使用分隔符號來扁平化階層式資料,以讀取階層式設定資料。

範例下載包含下列 appsettings.json 檔案:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey":  "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

下列 範例下載 程式碼會顯示數個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

讀取階層式設定資料的慣用方式是使用選項模式。 如需詳細資訊,請參閱本檔中的 系結階層式設定資料

GetSectionGetChildren 方法可用來在設定資料中隔離區段與區段的子系。 GetSection,、 GetChildren 與 Exists 中說明這些方法。

組態索引鍵和值

設定金鑰:

  • 不區分大小寫。 例如,ConnectionStringconnectionstring 會被視為相等的機碼。
  • 如果索引鍵和值是在多個組態提供者中設定,則會使用上一個新增提供者的值。 如需詳細資訊,請參閱 預設組態
  • 階層式機碼
    • 在設定 API 內,冒號分隔字元 (:) 可在所有平台上運作。
    • 在環境變數中,冒號分隔字元可能無法在所有平台上運作。 所有平臺都支援雙底線 __ ,且會自動轉換成冒號 :
    • 在 Azure 金鑰保存庫中,階層式索引鍵會用作 -- 分隔符號。 Azure 金鑰保存庫組態提供者會在將秘密載入應用程式組態時自動取代 --: 為 。
  • ConfigurationBinder 支援在設定機碼中使用陣列索引將陣列繫結到物件。 將陣列繫結到類別一節說明陣列繫結。

組態值:

  • 是字串。
  • Null 值無法存放在設定中或繫結到物件。

設定提供者

下表顯示可供 ASP.NET Core 應用程式使用的設定提供者。

提供者 從提供設定
Azure 金鑰保存庫組態提供者 Azure Key Vault
Azure App組態提供者 Azure 應用程式組態
命令列組態提供者 命令列參數
自訂設定提供者 自訂來源
環境變數組態提供者 環境變數
檔案組態提供者 INI、 JS ON 和 XML 檔案
每個檔案的金鑰組態提供者 目錄檔案
記憶體組態提供者 記憶體內集合
使用者祕密 使用者設定檔目錄中的檔案

設定來源會依其設定提供者的指定順序讀取。 排序程式代碼中的組態提供者,以符合應用程式所需的基礎組態來源優先順序。

典型的設定提供者順序是:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. 使用者祕密
  4. 使用 環境變數組態提供者的環境變數
  5. 使用命令列 組態提供者的命令列引數。

常見的做法是,在一系列提供者中最後新增命令列組態提供者,以允許命令列引數覆寫其他提供者所設定的組態。

上述提供者序列用於 預設組態中。

連接字串前置詞

組態 API 有四個連接字串環境變數的特殊處理規則。 這些連接字串涉及設定應用程式環境的 Azure 連接字串。 資料表中顯示的前置詞環境變數會載入具有 預設組態 的應用程式,或未提供前置詞給 AddEnvironmentVariables 時。

連接字串前置詞 提供者
CUSTOMCONNSTR_ 自訂提供者
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

當探索到具有下表所顯示之任何四個前置詞的環境變數並將其載入到設定中時:

  • 會透過移除環境變數前置詞並新增設定機碼區段 (ConnectionStrings) 來移除具有下表顯示之前置詞的環境變數。
  • 會建立新的設定機碼值組以代表資料庫連線提供者 (CUSTOMCONNSTR_ 除外,這沒有所述提供者)。
環境變數機碼 已轉換的設定機碼 提供者設定項目
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} 設定項目未建立。
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} 機碼:ConnectionStrings:{KEY}_ProviderName
值:System.Data.SqlClient

檔案組態提供者

FileConfigurationProvider 是用於從檔案系統載入設定的基底類別。 下列組態提供者衍生自 FileConfigurationProvider

INI 設定提供者

IniConfigurationProvider 會在執行階段從 INI 檔案機碼值組載入設定。

下列程式碼會清除所有組態提供者,並新增數個組態提供者:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
                      .AddIniFile($"MyIniConfig.{env.EnvironmentName}.ini",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在上述程式碼中 MyIniConfig.ini ,和 MyIniConfig.{Environment}.ini 檔案中的設定會由 下列中的設定覆寫:

範例下載包含下列 MyIniConfig.ini 檔案:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

下列來自 範例下載 的程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

JSON 設定提供者

JsonConfigurationProvider 從 JS ON 檔案機碼/值組載入組態。

多載可以指定:

  • 檔案是否為選擇性。
  • 檔案變更時是否要重新載入設定。

請考慮下列程式碼:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MyConfig.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上述程式碼:

  • 設定 ON 組 JS 態提供者以使用下列選項載入 MyConfig.json 檔案:
    • optional: true:檔案是選擇性的。
    • reloadOnChange: true :儲存變更時會重載檔案。
  • 讀取檔案之前 MyConfig.json的預設組態提供者。 預設組態提供者中 MyConfig.json 檔案覆寫設定中的設定,包括 環境變數組態提供者命令列組態提供者

您通常 不希望 自訂 JS ON 檔案覆寫 環境變數組態提供者命令列組態提供者中所設定的值。

下列程式碼會清除所有組態提供者,並新增數個組態提供者:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", 
                                     optional: true, reloadOnChange: true);

                config.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"MyConfig.{env.EnvironmentName}.json",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在上述程式碼中 MyConfig.json ,設定 和 MyConfig. Environmentjson 檔案:

範例下載包含下列 MyConfig.json 檔案:

{
  "Position": {
    "Title": "My Config title",
    "Name": "My Config Smith"
  },
  "MyKey":  "MyConfig.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

下列來自 範例下載 的程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

XML 組態提供者

XmlConfigurationProvider 會在執行階段從 XML 檔案機碼值組載入設定。

下列程式碼會清除所有組態提供者,並新增數個組態提供者:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
                      .AddXmlFile($"MyXMLFile.{env.EnvironmentName}.xml",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在上述程式碼中 MyXMLFile.xml ,和 MyXMLFile.{Environment}.xml 檔案中的設定會由 下列中的設定覆寫:

範例下載包含下列 MyXMLFile.xml 檔案:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

下列來自 範例下載 的程式碼會顯示上述幾個組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

name 屬性是用來區別元素,則可以重複那些使用相同元素名稱的元素:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

下列程式碼會讀取先前的組態檔,並顯示索引鍵和值:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

屬性可用來提供值:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

先前的設定檔會使用 value 載入下列機碼:

  • key:attribute
  • section:key:attribute

每個檔案的金鑰組態提供者

KeyPerFileConfigurationProvider 使用目錄的檔案做為設定機碼值組。 機碼是檔案名稱。 值包含檔案的內容。 Docker 裝載案例中會使用每個檔案的金鑰組態提供者。

若要啟用每個檔案機碼設定,請在 ConfigurationBuilder 的執行個體上呼叫 AddKeyPerFile 延伸模組方法。 檔案的 directoryPath 必須是絕對路徑。

多載允許指定:

  • 設定來源的 Action<KeyPerFileConfigurationSource> 委派。
  • 目錄是否為選擇性與目錄的路徑。

雙底線 (__) 是做為檔案名稱中的設定金鑰分隔符號使用。 例如,檔案名稱 Logging__LogLevel__System 會產生設定金鑰 Logging:LogLevel:System

建置主機時呼叫 ConfigureAppConfiguration 以指定應用程式的設定:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

記憶體設定提供者

MemoryConfigurationProvider 使用記憶體內集合做為設定機碼值組。

下列程式碼會將記憶體集合新增至組態系統:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(Dict);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

下列來自 範例下載 的程式碼會顯示上述組態設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

在上述程式碼中, config.AddInMemoryCollection(Dict) 會在預設組 態提供者之後新增。 如需排序設定提供者的範例,請參閱JS ON 組態提供者

如需使用 的另一個範例 MemoryConfigurationProvider,請參閱系結陣列

Kestrel 端點組態

Kestrel 特定端點組態會覆寫所有 跨伺服器端 點組態。 跨伺服器端點組態包括:

請考慮 ASP.NET Core Web 應用程式中使用的下列 appsettings.json 檔案:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

當上述反白顯示的標記用於 ASP.NET Core Web 應用程式,應用程式會在命令列上啟動,並具有下列跨伺服器端點組態:

dotnet run --urls="https://localhost:7777"

Kestrel 系結至檔案中特別針對 Kestrel 設定的 appsettings.json 端點 () https://localhost:9999 ,而不是 https://localhost:7777

請考慮設定 Kestrel 為環境變數的特定端點:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

在上述環境變數中, Https 是特定端點的名稱 Kestrel 。 上述 appsettings.json 檔案也會定義 Kestrel 名為 Https 的特定端點。 根據 預設,使用 環境變數組態提供者的環境變數 會在 之後 appsettings.{Environment}.json 讀取,因此會針對 Https 端點使用上述環境變數。

GetValue

ConfigurationBinder.GetValue 從具有指定索引鍵的組態中擷取單一值,並將它轉換成指定的類型。 這個方法是 的 IConfiguration 擴充方法:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

在上述程式碼中,如果在 NumberKey 組態中找不到 ,則會使用 的 99 預設值。

GetSection、GetChildren 與 Exists

針對下列範例,請考慮下列 MySubsection.json 檔案:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

下列程式碼會新增 MySubsection.json 至組態提供者:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MySubsection.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

GetSection

IConfiguration.GetSection 會傳回具有指定之子區段索引鍵的組態子區段。

下列程式碼會傳回 的值 section1

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

下列程式碼會傳回 的值 section2:subsection0

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection 絕不會傳回 null。 若找不到相符的區段,會傳回空的 IConfigurationSection

GetSection 傳回相符區段時,未填入 Value。 當區段存在時,會傳回 KeyPath

GetChildren 和 Exists

下列程式碼會呼叫 IConfiguration.GetChildren 並傳回 的值 section2:subsection0

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = null;
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new System.Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

上述程式碼會呼叫 ConfigurationExtensions.Exists 以確認 區段存在:

系結陣列

ConfigurationBinder.Bind 支援在設定機碼中使用陣列索引將陣列繫結到物件。 公開數值索引鍵區段的任何陣列格式都能夠系結至 POCO 類別陣列。

請考慮 MyArray.json範例下載

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

下列程式碼會將 新增 MyArray.json 至組態提供者:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MyArray.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

下列程式碼會讀取組態並顯示值:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

上述程式碼會傳回下列輸出:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

在上述輸出中,索引 3 具有 值 value40 ,對應至 "4": "value40", 中的 MyArray.json 。 系結陣列索引是連續的,而不是系結至組態索引鍵索引。 組態系結器無法系結 Null 值或在系結物件中建立 Null 專案

下列程式碼會使用 AddInMemoryCollection 擴充方法載入組 array:entries 態:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            //              3   Skipped
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

下列程式碼會讀取 中的 arrayDictDictionary 組態,並顯示值:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

上述程式碼會傳回下列輸出:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value4
Index: 4  Value: value5

系結物件中的 Index #3 會保存組 array:4 態索引鍵的組態資料及其值 value4 。 當包含陣列的組態資料系結時,組態索引鍵中的陣列索引會用來在建立物件時逐一查看組態資料。 設定資料中不能保留 Null 值,當設定機碼中的陣列略過一或多個索引時,不會在繫結物件中建立 Null 值項目。

任何讀取索引 #3 索引鍵/值組的組態提供者都可以在系結至 ArrayExample 實例之前提供遺漏的組態專案。 從範例下載考慮下列 Value3.json 檔案:

{
  "array:entries:3": "value3"
}

下列程式碼包含 和 的 Value3.jsonarrayDictDictionary 組態:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            //              3   Skipped
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
                config.AddJsonFile("Value3.json",
                                    optional: false, reloadOnChange: false);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

下列程式碼會讀取上述組態,並顯示值:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

上述程式碼會傳回下列輸出:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value3
Index: 4  Value: value4
Index: 5  Value: value5

自訂設定提供者不需要實作陣列繫結。

自訂設定提供者

範例應用程式示範如何建立會使用 Entity Framework (EF) 從資料庫讀取設定機碼值組的基本設定提供者。

提供者具有下列特性:

  • EF 記憶體內資料庫會用於示範用途。 若要使用需要連接字串的資料庫,請實作第二個 ConfigurationBuilder 以從另一個設定提供者提供連接字串。
  • 啟動時,該提供者會將資料庫資料表讀入到設定中。 該提供者不會以個別機碼為基礎查詢資料庫。
  • 未實作變更時重新載入,因此在應用程式啟動後更新資料庫對應用程式設定沒有影響。

定義 EFConfigurationValue 實體來在資料庫中存放設定值。

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; }
    public string Value { get; set; }
}

新增 EFConfigurationContext 以存放及存取已設定的值。

EFConfigurationProvider/EFConfigurationContext.cs:

// using Microsoft.EntityFrameworkCore;

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values { get; set; }
}

建立會實作 IConfigurationSource 的類別。

EFConfigurationProvider/EFConfigurationSource.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
    {
        _optionsAction = optionsAction;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new EFConfigurationProvider(_optionsAction);
    }
}

透過繼承自 ConfigurationProvider 來建立自訂設定提供者。 若資料庫是空的,設定提供者會初始化資料庫。 因為組態索引鍵不區分大小寫,所以用來初始化資料庫的字典會以不區分大小寫的比較子建立, (StringComparer.OrdinalIgnoreCase) 。

EFConfigurationProvider/EFConfigurationProvider.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues = 
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                { "quote1", "I aim to misbehave." },
                { "quote2", "I swallowed a bug." },
                { "quote3", "You can't stop the signal, Mal." }
            };

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue 
                {
                    Id = kvp.Key,
                    Value = kvp.Value
                })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

AddEFConfiguration 擴充方法允許新增設定來源到 ConfigurationBuilder

Extensions/EntityFrameworkExtensions.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
        this IConfigurationBuilder builder, 
        Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

下列程式碼示範如何使用 中的 Program.cs 自訂 EFConfigurationProvider

// using Microsoft.EntityFrameworkCore;

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddEFConfiguration(
                options => options.UseInMemoryDatabase("InMemoryDb"));
        })

啟動中的存取組態

下列程式碼會在 方法中 Startup 顯示組態資料:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        Console.WriteLine($"MyKey : {Configuration["MyKey"]}");
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        Console.WriteLine($"Position:Title : {Configuration["Position:Title"]}");

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

如需使用啟動方便方法來存取設定的範例,請參閱應用程式啟動:方便方法

存取頁面中的 Razor 組態

下列程式碼會在 Page 中顯示組 Razor 態資料:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

在下列程式碼中, MyOptions 會新增至服務容器,並 Configure 系結至組態:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));

    services.AddRazorPages();
}

下列標記會 @injectRazor 使用 指示詞來解析及顯示選項值:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

存取 MVC 檢視檔案中的組態

下列程式碼會在 MVC 檢視中顯示組態資料:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

使用委派設定選項

在委派中設定的選項會覆寫組態提供者中設定的值。

使用委派設定選項會在範例應用程式中示範為範例 2。

在下列程式碼中, IConfigureOptions<TOptions> 服務會新增至服務容器。 它會使用委派來設定 的值 MyOptions

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(myOptions =>
    {
        myOptions.Option1 = "Value configured in delegate";
        myOptions.Option2 = 500;
    });

    services.AddRazorPages();
}

下列程式碼會顯示選項值:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

在上述範例中,和 Option2 的值 Option1 會在 中 appsettings.json 指定,然後由設定的委派覆寫。

主機與應用程式組態的比較

設定及啟動應用程式之前,會先設定及啟動「主機」。 主機負責應用程式啟動和存留期管理。 應用程式與主機都是使用此主題中所述的設定提供者來設定的。 主機組態機碼/值組也會包含在應用程式的組態中。 如需在主機建置時如何使用設定提供者,以及組態來源如何影響主機設定的詳細資訊,請參閱ASP.NET Core基本概觀

預設主機組態

如需使用 Web 主機時預設組態的詳細資料,請參閱本主題的 ASP.NET Core 2.2 版本

  • 主機組態的提供來源:
    • 例如,環境變數前面加上 DOTNET_ (, DOTNET_ENVIRONMENT) 使用 環境變數組態提供者。 載入設定機碼值組時,會移除前置詞 (DOTNET_)。
    • 使用命令列組態提供者的命令列引數。
  • 已建立 Web 主機預設組態 (ConfigureWebHostDefaults):
    • Kestrel 會當做 Web 服務器使用,並使用應用程式的組態提供者進行設定。
    • 新增主機篩選中介軟體。
    • 如果 ASPNETCORE_FORWARDEDHEADERS_ENABLED 環境變數設定為 true,則會新增轉接的標頭中介軟體。
    • 啟用 IIS 整合。

其他設定

本主題僅適用于 應用程式設定。 執行和裝載 ASP.NET Core應用程式的其他層面是使用本主題未涵蓋的組態檔進行設定:

在 中 launchSettings.json 設定的環境變數會覆寫系統內容中的環境變數。

如需從舊版 ASP.NET 移轉應用程式組態的詳細資訊,請參閱從 ASP.NET 移轉至 ASP.NET Core

從外部組件新增設定

IHostingStartup 實作允許在啟動時從應用程式 Startup 類別外部的外部組件,針對應用程式新增增強功能。 如需詳細資訊,請參閱在 ASP.NET Core 中使用裝載啟動元件

其他資源