文章目錄
使用 ConfigurationSection 自訂 ASP.NET config (web.config) 區段
不得不服老呀,一樣的功能二、三年前寫的時候還相當流暢,想不到這二、三年的光景過去,就搞得像是沒寫過一樣XD 乾脆當做沒寫過,好好地留個紀錄 避免下次遇到又要重來…
透過 ConfigurationSection 的做法可以讓我們使用 .NET Framework 內建的 ConfigurationManager api 來讀取 config 檔案內容,而不用自行處理檔案讀寫與解析,但也因為要使用 .NET Framewrok 功能,開發及使用上就需要符合相關規範,接著就一步步來看看開發上有什麼需要留意的眉角
1. 自訂解析的 handler
1-1. 新增
public
class 並繼承System.Configuration.ConfigurationSection
public class YowkoSettingConfiguration : ConfigurationSection { }
1-2. 定義需要的屬性(property)
關於 ConfigurationProperty 設定請參考 ConfigurationPropertyAttribute 類別
- 基本型別的 property 用於表示 attibute
套用
ConfigurationProperty
指定對應 config 檔內容的屬性名稱getter
:用 xml 的屬性名稱 returnget { return this["{propertyName}"] as string; }
setter
:用 xml 的屬性名稱設定值set { this["{propertyName}"] = value; }
自訂型別的 perperty 用於表示 child element
- 套用
ConfigurationProperty
指定對應 config 檔內容的元名稱 - 自訂型別需
繼承ConfigurationElement
- 只有getter
- 元素中的屬性規則 follow 基本型別的 property 的規則範例 1 及 範例 2 可用的 handler 完整程式碼
public class YowkoConfiguration : ConfigurationSection { [ConfigurationProperty("name")] public string Attr_Name { get { return this["name"] as string; } set { this["name"] = value; } } [ConfigurationProperty("tel")] public string Attr_Tel { get { return this["tel"] as string; } set { this["tel"] = value; } } [ConfigurationProperty("yowkoSetting")] public YowkoSettingElement Elem_YowkoSetting => this["yowkoSetting"] as YowkoSettingElement; } public class YowkoSettingElement : ConfigurationElement { [ConfigurationProperty("site", DefaultValue = "", IsRequired = true)] public string Site { get { return this["site"] as string; } set { this["site"] = value; } } [ConfigurationProperty("userName", IsRequired = true)] public string UserName { get { return this["userName"] as string; } set { this["userName"] = value; } } [ConfigurationProperty("password", IsRequired = true)] public string Password { get { return this["password"] as string; } set { this["password"] = value; } } }
2. web.config 中 configSections 加入自訂 section 宣告
- MSDN 建議使用
sectionGroup
把將 section 內容包起來,使資料結構性更好 - 關於 section
- type 設定必需符合組件資訊清單 (Assembly Manifest)
- type =“{Namespace + ClassName},[dllName]“,如果configSections 定義在 web.config 中可忽略不填,如是置於外部檔還是需要填寫
- 參考的組件 assembly - dll 必需與 web.config 在相同的應用程式目錄中
範例 1 (官方建議寫法) - 需搭配下方
範例 1
使用<configSections> <sectionGroup name="yowkoSettingGroup"> <section name="yowkoConfig" type="TestConfig.Handler.YowkoConfiguration,TestConfig" /> </sectionGroup> </configSections>
範例 2 (簡潔寫法) - 需搭配下方
範例 2
使用<configSections> <section name="yowkoConfig" type="TestConfig.Handler.YowkoConfiguration,TestConfig" /> </configSections>
3. web.config 加上 自定 section 內容
- 名稱需與 configSection 宣告名稱相同
如有 group ,階層也必需相同(下圖 config 為了清楚標示,有多幾個空白)
範例 1 (官方建議寫法) - 需搭配上方及下方
範例 1
使用<yowkoSettingGroup> <yowkoConfig name="Yowko Tsai" tel="0123456789"> <yowkoSetting site="blog.yowko.com" userName="yowko" password="yowkoPass"></yowkoSetting> </yowkoConfig> </yowkoSettingGroup>
範例 2 (簡潔寫法) - 需搭配上方及下方
範例 2
使用<yowkoConfig name="Yowko Tsai" tel="0123456789"> <yowkoSetting site="blog.yowko.com" userName="yowko" password="yowkoPass"></yowkoSetting> </yowkoConfig>
4. 使用方式
- 使用
ConfigurationManager
指定區段並轉型為一開始自訂的 configuration handler - 如有 group 包覆,
GetSection
必需使用正確階層 範例 1 (官方建議寫法)
需搭配上方
範例 1
使用YowkoConfiguration clientConfiguration = ConfigurationManager.GetSection("yowkoSettingGroup/yowkoConfig") as YowkoConfiguration;
範例 2 (簡潔寫法)
需搭配上方
範例 2
使用YowkoConfiguration clientConfiguration = ConfigurationManager.GetSection("yowkoConfig") as YowkoConfiguration;
5. 需要多組相同設定格式的情境時
5-1. handler
- 新增自訂型別屬性
- 套用
ConfigurationProperty
指定對應 config 檔內容的元素名稱 - 套用
ConfigurationCollection
attribute 並指定需要重複格式的型別
以及元素名稱
- 自訂型別
必須
要繼承ConfigurationElementCollection
並覆寫兩個方法 1. CreateNewElement - 指定建立新元素的方式```cs protected override ConfigurationElement CreateNewElement() { return new YowkoSettingElement(); } ```
GetElementKey - 指定一個 unique key
```cs protected override object GetElementKey(ConfigurationElement element) { return (element as YowkoSettingElement).Site; } ```
完整範例
public class YowkoConfiguration : ConfigurationSection { [ConfigurationProperty("name")] public string Attr_Name { get { return this["name"] as string; } set { this["name"] = value; } } [ConfigurationProperty("tel")] public string Attr_Tel { get { return this["tel"] as string; } set { this["tel"] = value; } } [ConfigurationProperty("yowkoSettings")] [ConfigurationCollection(typeof(YowkoSettingElement), AddItemName = "yowkoSetting")] public YowkoSettingElementCollection YowkoSettings => this["yowkoSettings"] as YowkoSettingElementCollection; } public class YowkoSettingElementCollection :ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new YowkoSettingElement(); } protected override object GetElementKey(ConfigurationElement element) { return (element as YowkoSettingElement).Site; } } public class YowkoSettingElement :ConfigurationElement { [ConfigurationProperty("site", DefaultValue = "", IsRequired = true)] public string Site { get { return this["site"] as string; } set { this["site"] = value; } } [ConfigurationProperty("userName", IsRequired = true)] public string UserName { get { return this["userName"] as string; } set { this["userName"] = value; } } [ConfigurationProperty("password", IsRequired = true)] public string Password { get { return this["password"] as string; } set { this["password"] = value; } } }
5-2. web.config 設定
web.config 中 configSections 加入自訂 section 宣告
<configSections> <sectionGroup name="yowkoSettingGroup"> <section name="yowkoConfig" type="TestConfig.Handler.YowkoConfiguration,TestConfig" /> </sectionGroup> </configSections>
web.config 加上 自定 section 內容
<yowkoSettingGroup> <yowkoConfig name="Yowko Tsai" tel="0123456789"> <yowkoSettings> <yowkoSetting site="blog.yowko.com" userName="yowko" password="yowkoPass"></yowkoSetting> <yowkoSetting site="www.yowko.com" userName="yowko2" password="yowkoPass2"></yowkoSetting> </yowkoSettings> </yowkoConfig> </yowkoSettingGroup>
5-3. 使用方式
- 透過
ConfigurationManager.GetSection
取得設定(需注意階層) 範例
var section = ConfigurationManager.GetSection("yowkoSettingGroup/yowkoConfig");
- 透過
6. 如果 config 是獨立檔案的情境
- handler 皆與上述各個流程情境一致
- config
- 設定結構與上述各流程相同
- 需留意 config 檔案格式需與 web.config 相同 (e.g.XML,由 configuration 元素為根元素)
使用方式
指定 config 位置
var configFile = Path.Combine(Server.MapPath("~/App_Data"), "YowkoSetting.config");
使用 config 位置來取得 ConfigurationFileMap
ConfigurationFileMap fileMap = new ConfigurationFileMap(configFile);
將 ConfigurationFileMap 餵給 ConfigurationManager.OpenMappedMachineConfiguration 並使用 GetSection 取出資料 (注意階層)
YowkoConfiguration managerConfiguration =ConfigurationManager.OpenMappedMachineConfiguration(fileMap).GetSection("yowkoSettingGroup/yowkoConfig") as YowkoConfiguration;
完整程式碼
var configFile = Path.Combine(Server.MapPath("~/App_Data"), "YowkoSetting.config"); ConfigurationFileMap fileMap = new ConfigurationFileMap(configFile); YowkoConfiguration managerConfiguration =ConfigurationManager.OpenMappedMachineConfiguration(fileMap).GetSection("yowkoSettingGroup/yowkoConfig") as YowkoConfiguration;
如果想要取出設定時可以支援 IEnumerable 功能,記得在自訂的 ConfigurationElementCollection 一併繼承 IEnumerable 並實作 GetEnumerator 方法 > 因為 ConfigurationElementCollection 有許多基礎類別繼承而來的屬性,我們是用不到的,除了自己一個一個對應外,使用 lambda 來處理相對容易些
繼承 IEnumerable
public class YowkoSettingElementCollection : ConfigurationElementCollection,IEnumerable<YowkoSettingElement>
實作 GetEnumerator
IEnumerator<YowkoSettingElement> IEnumerable<YowkoSettingElement>.GetEnumerator() { foreach (YowkoSettingElement element in Enumerable.Range(0, base.Count).Select(base.BaseGet)) yield return element; }
完整程式碼
public class YowkoSettingElementCollection : ConfigurationElementCollection,IEnumerable<YowkoSettingElement> { protected override ConfigurationElement CreateNewElement() { return new YowkoSettingElement(); } protected override object GetElementKey(ConfigurationElement element) { return (element as YowkoSettingElement).Site; } IEnumerator<YowkoSettingElement> IEnumerable<YowkoSettingElement>.GetEnumerator() { foreach (YowkoSettingElement element in Enumerable.Range(0, base.Count).Select(base.BaseGet)) yield return element; } }
就可以使用 lambda 來取得需要屬性並轉換成 list
var test = managerConfiguration.YowkoSettings.Select(a => new YowkoSettingElement { Site= a.Site, UserName = a.UserName, Password = a.Password}).ToList();
心得
我怎麼記得以前好像沒這麼多需要注意的,不知道是不是因為以文字紀錄的關係,總覺得可以再詳細點再多點說明,不過經過這次整理我相信下次再次遇到時一定可以更快回憶起來的
參考資料
文章作者 Yowko Tsai
上次更新 2021-10-08
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。