在 ASP.NET 開發中,配置文件是應用程式靈活性的關鍵。透過配置文件,開發人員無需重新編譯即可修改應用程式設定。本文將系統性地介紹從基礎到進階的各種配置文件讀取技巧,幫助你掌握 System.Configuration 命名空間的核心用法。
適用於讀取自定義配置節或特定類型的配置集合:
System.Collections.Specialized.NameValueCollection nvc =
(System.Collections.Specialized.NameValueCollection)
System.Configuration.ConfigurationManager.GetSection(sectionName);
string keyValue = nvc.GetValues(keyName)[0].ToString();
最常用的簡便方式,適用於標準 <appSettings> 節點:
string value = System.Web.Configuration.WebConfigurationManager.AppSettings[keyName].ToString();
配置文件是標準 XML 文件,根節點為 <configuration>。常見結構如下:
<configuration>
<configSections>
<section name="MySection" type="System.Configuration.NameValueSectionHandler" />
<sectionGroup name="MyGroup">
<section name="NestedSection" type="System.Configuration.DictionarySectionHandler" />
</sectionGroup>
</configSections>
<appSettings>
<add key="ConnectionString" value="Server=.;Database=Test;Uid=sa;Pwd=;" />
</appSettings>
<MySection>
<add key="Setting1" value="Value1" />
</MySection>
<MyGroup>
<NestedSection>
<add key="NestedKey" value="NestedValue" />
</NestedSection>
</MyGroup>
</configuration>
| 處理器類型 | 返回類型 | 適用場景 |
|---|---|---|
| SingleTagSectionHandler | System.Collections.IDictionary | 單標籤、多屬性結構 |
| DictionarySectionHandler | System.Collections.IDictionary | 鍵值對集合 |
| NameValueSectionHandler | System.Collections.Specialized.NameValueCollection | 名稱/值集合,支援多值 |
在 <configSections> 中聲明,然後在配置文件中直接使用:
<configuration>
<configSections>
<section name="Test1" type="System.Configuration.SingleTagSectionHandler"/>
<section name="Test2" type="System.Configuration.DictionarySectionHandler"/>
<section name="Test3" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<Test1 setting1="Hello" setting2="World"/>
<Test2>
<add key="Hello" value="World" />
</Test2>
<Test3>
<add key="Hello" value="World" />
</Test3>
</configuration>
// 讀取 SingleTagSectionHandler
IDictionary test1 = (IDictionary)ConfigurationSettings.GetConfig("Test1");
string result = (string)test1["setting1"] + " " + (string)test1["setting2"]; // Hello World
// 讀取 DictionarySectionHandler
IDictionary test2 = (IDictionary)ConfigurationSettings.GetConfig("Test2");
string key = (string)test2.Keys.Cast<string>().First();
string value = (string)test2[key];
// 讀取 NameValueSectionHandler
NameValueCollection test3 = (NameValueCollection)ConfigurationSettings.GetConfig("Test3");
string value3 = test3["Hello"]; // World
將相關配置節歸組管理,路徑格式為 "GroupName/SectionName":
<configSections>
<sectionGroup name="TestGroup">
<section name="Test" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<TestGroup>
<Test>
<add key="Hello" value="World"/>
</Test>
</TestGroup>
// 讀取
NameValueCollection nc = (NameValueCollection)ConfigurationSettings.GetConfig("TestGroup/Test");
建立強型別配置類別,利用 ConfigurationProperty 屬性映射 XML 屬性:
public class ConfigSectionData : ConfigurationSection
{
[ConfigurationProperty("id", IsRequired = true)]
public int Id
{
get { return (int)this["id"]; }
set { this["id"] = value; }
}
[ConfigurationProperty("time", IsRequired = true)]
public DateTime Time
{
get { return (DateTime)this["time"]; }
set { this["time"] = value; }
}
[ConfigurationProperty("custom")]
[TypeConverter(typeof(CustomConverter))]
public CustomData Custom { get; set; }
}
支援複雜類型序列化至配置文件:
public class CustomConverter : ConfigurationConverterBase
{
public override bool CanConvertFrom(ITypeDescriptorContext ctx, Type type)
=> type == typeof(string);
public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
=> new CustomData((string)data);
public override object ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci, object value, Type type)
=> ((CustomData)value).S;
}
// 開啟預設 exe.config
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// 開啟指定配置文件
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "custom.config";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
// 開啟 Machine.config
Configuration machineConfig = ConfigurationManager.OpenMachineConfiguration();
// ASP.NET 專用
Configuration webConfig = WebConfigurationManager.OpenWebConfiguration("/");
ConfigSectionData data = new ConfigSectionData();
data.Id = 1000;
data.Time = DateTime.Now;
data.Custom = new CustomData("自定義資料");
// 寫入根節點
config.Sections.Add("mySection", data);
// 寫入配置節組
if (config.SectionGroups["group1"] == null)
config.SectionGroups.Add("group1", new ConfigurationSectionGroup());
config.SectionGroups["group1"].Sections.Add("mySection", data);
config.Save(ConfigurationSaveMode.Minimal);
// 從根節點讀取
ConfigSectionData data = config.Sections["mySection"] as ConfigSectionData;
// 從配置節組讀取
ConfigSectionData data = config.SectionGroups["group1"].Sections["mySection"] as ConfigSectionData;
if (data != null)
{
Console.WriteLine($"ID: {data.Id}, Time: {data.Time}, Custom: {data.Custom.S}");
}
// 刪除根節點區段
config.Sections.Remove("sectionName");
// 刪除配置節組
config.SectionGroups.Remove("groupName");
// 刪除節組中的區段
if (config.SectionGroups["group1"] != null)
config.SectionGroups["group1"].Sections.Remove("sectionName");
config.Save(ConfigurationSaveMode.Minimal);
*.vshost.exe.config,需直接執行 *.exe 驗證結果。Configuration 物件非執行緒安全,建議採用 Singleton 模式管理。Configuration 實例修改,儲存會拋出例外,需捕獲處理。ConfigurationProperty 的名稱必須與 XML 屬性大小寫完全一致。ASP.NET 配置系統提供了從簡單的 AppSettings 到複雜的強型別配置節的完整支援。根據專案需求選擇適當層級的抽象:簡單場景用 AppSettings,結構化資料用自定義配置節,企業級應用建議採用強型別 ConfigurationSection 並搭配型別轉換器,獲得最佳的型別安全與維護性。