天天看點

Asp.Net Core 配置,各種讀取配置檔案的方式

作者:CShap新勢力

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 IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
        private readonly IConfiguration Configuration;
        public IndexModel(ILogger<IndexModel> logger, IConfiguration configuration)
        {
            _logger = logger;
            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(#34;MyKey value: {myKeyValue} \n" +
                           #34;Title: {title} \n" +
                           #34;Name: {name} \n" +
                           #34;Default Log Level: {defaultLogLevel}");
        }
    }           

運作結果

Asp.Net Core 配置,各種讀取配置檔案的方式

運作結果

預設的 JsonConfigurationProvider 會按以下順序加載配置:

  1. appsettings.json
  2. appsettings.{Environment}.json:例如,appsettings.Production.json 和 appsettings.Development.json 檔案。 檔案的環境版本是根據 IHostingEnvironment.EnvironmentName 加載的。

appsettings.{Environment}.json 值替代 appsettings.json 中的鍵。 例如,預設情況下:

  • 在開發環境中,appsettings.Development.json 配置會覆寫在 appsettings.json 中找到的值。
  • 在生産環境中,appsettings.Production.json 配置會覆寫在 appsettings.json 中找到的值。

使用選項模式綁定分層配置資料

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 将 類綁定到 Position 部分。
  • 顯示 Position 配置資料。

控制器代碼

public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
        private readonly IConfiguration Configuration;
        public IndexModel(ILogger<IndexModel> logger, IConfiguration configuration)
        {
            _logger = logger;
            Configuration = configuration;
        }

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

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

執行結果

Asp.Net Core 配置,各種讀取配置檔案的方式

執行結果

在上面的代碼中,預設讀取在應用啟動後對 JSON 配置檔案所做的更改。

ConfigurationBinder.Get<T> 綁定并傳回指定的類型。 使用 ConfigurationBinder.Get<T> 可能比使用 ConfigurationBinder.Bind 更友善。 下面的代碼示範如何将 ConfigurationBinder.Get<T> 與 PositionOptions 類配合使用:

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(#34;Title: {positionOptions.Title} \n" +
                       #34;Name: {positionOptions.Name}");
    }
}           

運作效果

Asp.Net Core 配置,各種讀取配置檔案的方式

啟動時的執行結果

看到上面結果了,我們修改下配置檔案,但不重新開機程式,再重新整理

Asp.Net Core 配置,各種讀取配置檔案的方式

重新整理後的結果

可以看出來。Get比Bind更加靈活

依賴關系注入使用選項模式

使用選項模式時的另一種方法是綁定 Position 部分,并将其添加到依賴關系注入服務容器中。 在以下代碼中,PositionOptions 已認證 Configure 被添加到了服務容器并已綁定到了配置:

Program 代碼

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 IndexModel : PageModel
    {
        private readonly PositionOptions _options;

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

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

執行效果

Asp.Net Core 配置,各種讀取配置檔案的方式

依賴關系注入使用選項模式

在上面的代碼中,不會讀取在應用啟動後對 JSON 配置檔案所做的更改。

檔案配置提供程式

FileConfigurationProvider 是從檔案系統加載配置的基類。 以下配置提供程式派生自 FileConfigurationProvider:

  • INI 配置提供程式
  • JSON 配置提供程式
  • XML 配置提供程式

INI 配置提供程式

IniConfigurationProvider 在運作時從 INI 檔案鍵值對加載配置。

以下代碼添加多個配置提供程式:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
    .AddIniFile(#34;MyIniConfig.{builder.Environment.EnvironmentName}.ini",
                optional: true, reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();           

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 IndexModel : PageModel
    {
        private readonly IConfiguration Configuration;


        public IndexModel(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(#34;MyKey value: {myKeyValue} \n" +
                           #34;Title: {title} \n" +
                           #34;Name: {name} \n" +
                           #34;Default Log Level: {defaultLogLevel}");
        }
    }           

執行結果

Asp.Net Core 配置,各種讀取配置檔案的方式

讀取ini檔案

JSON 配置提供程式

JsonConfigurationProvider 從 JSON 檔案鍵值對加載配置。

重載可以指定:

  • 檔案是否可選。
  • 如果檔案更改,是否重載配置。
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();           

通過以下選項将 JSON 配置提供程式配置為加載 MyConfig.json 檔案

optional: true:檔案是可選的。

reloadOnChange: true:儲存更改後會重載檔案。

MyConfig.json代碼

{
	"People": [
		{
			"FirstName": "Brett",
			"LastName": "McLaughlin"
		},
		{
			"FirstName": "Jason",
			"LastName": "Hunter"
		}
	]
}           

控制器代碼

public class IndexModel : PageModel
    {
        private readonly IConfiguration Configuration;

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

        public ContentResult OnGet()
        {
            var peoples = Configuration.GetSection("People").Get<List<PeopleOptions>>();
            return Content(JsonConvert.SerializeObject(peoples));
        }
    }           

運作效果

Asp.Net Core 配置,各種讀取配置檔案的方式

讀取自定義json檔案

XML 配置提供程式

XmlConfigurationProvider 在運作時從 XML 檔案鍵值對加載配置。

以下代碼添加多個配置提供程式:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile(#34;MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();           

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 IndexModel : PageModel
    {
        private readonly IConfiguration Configuration;

        public IndexModel(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(#34;MyKey value: {myKeyValue} \n" +
                           #34;Title: {title} \n" +
                           #34;Name: {name} \n" +
                           #34;Default Log Level: {defaultLogLevel}");
        }
    }           

運作效果

Asp.Net Core 配置,各種讀取配置檔案的方式

讀取xml檔案

如果使用 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(#34;{key00} value: {val00} \n" +
                           #34;{key01} value: {val01} \n" +
                           #34;{key10} value: {val10} \n" +
                           #34;{key10} value: {val11} \n"
                           );
        }
    }           

執行結果

Asp.Net Core 配置,各種讀取配置檔案的方式

使用 name 屬性來區分元素

讀書xml的屬性

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

控制器代碼

public class IndexModel : PageModel
    {
        private readonly IConfiguration Configuration;

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

        public ContentResult OnGet()
        {
            var key1 = "key:attribute";
            var key2 = "section:key:attribute1";

            var attributeval1 = Configuration[key1];
            var attributeval2 = Configuration[key2];

            return Content(#34;{key1} value: {attributeval1} \n" +
                           #34;{key2} value: {attributeval2} \n" 
                           );
        }
    }           

運作效果

Asp.Net Core 配置,各種讀取配置檔案的方式

讀取xml的屬性

記憶體配置提供程式

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.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();           

控制器代碼

public class IndexModel : PageModel
    {
        private readonly IConfiguration Configuration;

        public IndexModel(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(#34;MyKey value: {myKeyValue} \n" +
                           #34;Title: {title} \n" +
                           #34;Name: {name} \n" +
                           #34;Default Log Level: {defaultLogLevel}");
        }
    }           

執行效果

Asp.Net Core 配置,各種讀取配置檔案的方式

執行效果

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(#34;{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"
    }
  }
}           
var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();           

控制器代碼

public class IndexModel : PageModel
    {
        private readonly IConfiguration Configuration;

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

        public ContentResult OnGet()
        {
            IConfigurationSection configurationSection = Configuration.GetSection("section1");

            return Content(
                #34;section1:key0: '{configurationSection["key0"]}'\n" +
                #34;section1:key1: '{configurationSection["key1"]}'");
        }
    }           

運作效果

Asp.Net Core 配置,各種讀取配置檔案的方式

運作效果

以下代碼将傳回 section2:subsection0 的值:

public class IndexModel : PageModel
    {
        private readonly IConfiguration Configuration;

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

        public ContentResult OnGet()
        {
            IConfigurationSection configurationSection = Configuration.GetSection("section2:subsection0");

            return Content(
               #34;section2:subsection0:key0: '{configurationSection["key0"]}'\n" +
                #34;section2:subsection0:key1: '{configurationSection["key1"]}'");
        }
    }           

運作效果

Asp.Net Core 配置,各種讀取配置檔案的方式

運作效果

GetChildren 和 Exists

以下代碼将調用 IConfiguration.GetChildren 并傳回 section2:subsection0 的值:

public class IndexModel : PageModel
    {
        private readonly IConfiguration Configuration;

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

        public ContentResult OnGet()
        {

            string s = "";
            var selection = Configuration.GetSection("section2");
            if (!selection.Exists())
            {
                throw new Exception("section2 does not exist.");
            }
            IEnumerable<IConfigurationSection> children = selection.GetChildren();

            foreach (IConfigurationSection 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);
        }
    }           

運作效果

Asp.Net Core 配置,各種讀取配置檔案的方式

運作效果

綁定數組

ConfigurationBinder.Bind 支援使用配置鍵中的數組索引将數組綁定到對象

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

以下代碼将 MyArray.json 添加到配置提供程式

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();           

綁定類代碼

public class ArrayExample
    {
        public string[]? Entries { get; set; }
    }           

控制器代碼

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

        public IndexModel(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 += #34;Index: {j}  Value:  {_array.Entries[j]} \n";
            }

            return Content(s);
        }
    }           

執行效果

Asp.Net Core 配置,各種讀取配置檔案的方式

執行效果

繼續閱讀