自定义ConfigurationSection,创建多个嵌套的ConfigurationElementCollection节点
由于接口地址都是固定的,所以想到使用自定義節點,來將接口都配置到web.config中。
很快,v1.0版本出爐:
public class RequestConfigSection : ConfigurationSection{[ConfigurationProperty("sources", IsDefaultCollection = true)][ConfigurationCollection(typeof(RequestConfigSourceCollection), AddItemName = "add")]public RequestConfigSourceCollection ConfigCollection{get { return (RequestConfigSourceCollection)this["sources"]; }set { this["sources"] = value; }}}public class RequestConfigSourceCollection : ConfigurationElementCollection{/// <summary>/// 創建新元素/// </summary>/// <returns></returns>protected override ConfigurationElement CreateNewElement(){return new RequestConfigSource();}/// <summary>/// 獲取元素的鍵/// </summary>/// <param name="element"></param>/// <returns></returns>protected override object GetElementKey(ConfigurationElement element){return ((RequestConfigSource)element).Name;}/// <summary>/// 獲取所有鍵/// </summary>public IEnumerable<string> AllKeys { get { return BaseGetAllKeys().Cast<string>(); } }/// <summary>/// 索引器/// </summary>/// <param name="name"></param>/// <returns></returns>public new RequestConfigSource this[string name]{get { return (RequestConfigSource)BaseGet(name); }}}public class RequestConfigSource : ConfigurationElement{/// <summary>/// 名稱/// </summary>[ConfigurationProperty("name")]public string Name{get { return (string)this["name"]; }set { this["name"] = value; }}/// <summary>/// 地址/// </summary>[ConfigurationProperty("url")]public string Url{get { return (string)this["url"]; }set { this["url"] = value; }}/// <summary>/// 訪問類型/// </summary>[ConfigurationProperty("type")]public RequestType RequestType{get{return (RequestType)Enum.Parse(typeof(RequestType), this["type"].ToString(), true);}set { this["type"] = value; }}}?
在web.config中的配置方式為:
<apiRequestConfig><sources><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /></sources> </apiRequestConfig>?這時候又看了一遍需求文檔,發現有說明不同平臺的接口地址是不一樣的,但接口做的事情是一樣的。
然后就開始想,如果接著在下邊追加,則不同平臺的同一接口的名稱是不能相同的。
所以想到的理想的配置方式為:
<apiRequestConfig><sources platform="android"><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /></sources><sources platform="ios"><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /></sources> </apiRequestConfig>?但是sources 名稱的節點只能出現一次…好吧,蛋疼了。
研究嘗試了一上午也沒有找到合適的解決方式,又懶得再重新寫一套代碼來讀取XML,…開始在網上搜解決方案
用中文做關鍵字找不著…翻了墻,用英文來當關鍵字 one or more ConfigurationElementCollection…
最終在一老外的博客里找到了一個替代的解決方案,最終的配置為:
<apiRequestConfig><requestConfigs><request platform="android"><sources><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /></sources></request><request platform="ios"><sources><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /><add name="..." url="..." type="POST" /></sources></request></requestConfigs></apiRequestConfig>?
C#代碼如下:
public class RequestConfigSection : ConfigurationSection{[ConfigurationProperty("requestConfigs", IsDefaultCollection = true)][ConfigurationCollection(typeof(RequestConfigTypeCollection), AddItemName = "request")]public RequestConfigTypeCollection ConfigCollection{get { return (RequestConfigTypeCollection)this["requestConfigs"]; }set { this["requestConfigs"] = value; }}/// <summary>/// 根據平臺和名稱獲取請求配置信息/// </summary>/// <param name="name"></param>/// <param name="platform"></param>/// <returns></returns>public RequestConfigSource GetRequestConfigSource(string platform, string name){return ConfigCollection[platform].SourceCollection[name];}}public class RequestConfigTypeCollection : ConfigurationElementCollection{/// <summary>/// 創建新元素/// </summary>/// <returns></returns>protected override ConfigurationElement CreateNewElement(){return new RequestConfigType();}/// <summary>/// 獲取元素的鍵/// </summary>/// <param name="element"></param>/// <returns></returns>protected override object GetElementKey(ConfigurationElement element){return ((RequestConfigType)element).Platform;}/// <summary>/// 獲取所有鍵/// </summary>public IEnumerable<string> AllKeys { get { return BaseGetAllKeys().Cast<string>(); } }/// <summary>/// 索引器/// </summary>/// <param name="name"></param>/// <returns></returns>public new RequestConfigType this[string platform]{get { return (RequestConfigType)BaseGet(platform); }}}public class RequestConfigType : ConfigurationElement{/// <summary>/// 獲取全部請求配置信息/// </summary>/// <returns></returns>public RequestConfigSource[] GetAllRequestSource(){var keys = this.SourceCollection.AllKeys;return keys.Select(name => this.SourceCollection[name]).ToArray();}/// <summary>/// 平臺標識/// </summary>[ConfigurationProperty("platform")]public string Platform{get { return (string)this["platform"]; }set { this["platform"] = value; }}[ConfigurationProperty("sources", IsDefaultCollection = true)][ConfigurationCollection(typeof(RequestConfigSourceCollection), AddItemName = "add")]public RequestConfigSourceCollection SourceCollection{get { return (RequestConfigSourceCollection)this["sources"]; }set { this["sources"] = value; }}}public class RequestConfigSourceCollection : ConfigurationElementCollection{/// <summary>/// 創建新元素/// </summary>/// <returns></returns>protected override ConfigurationElement CreateNewElement(){return new RequestConfigSource();}/// <summary>/// 獲取元素的鍵/// </summary>/// <param name="element"></param>/// <returns></returns>protected override object GetElementKey(ConfigurationElement element){return ((RequestConfigSource)element).Name;}/// <summary>/// 獲取所有鍵/// </summary>public IEnumerable<string> AllKeys { get { return BaseGetAllKeys().Cast<string>(); } }/// <summary>/// 索引器/// </summary>/// <param name="name"></param>/// <returns></returns>public new RequestConfigSource this[string name]{get { return (RequestConfigSource)BaseGet(name); }}}/// <summary>/// 請求的配置信息/// </summary>public class RequestConfigSource : ConfigurationElement{/// <summary>/// 名稱/// </summary>[ConfigurationProperty("name")]public string Name{get { return (string)this["name"]; }set { this["name"] = value; }}/// <summary>/// 地址/// </summary>[ConfigurationProperty("url")]public string Url{get { return (string)this["url"]; }set { this["url"] = value; }}/// <summary>/// 訪問類型/// </summary>[ConfigurationProperty("type")]public RequestType RequestType{get{return (RequestType)Enum.Parse(typeof(RequestType), this["type"].ToString(), true);}set { this["type"] = value; }}}?
本人的開發環境為 .net framework 4.0
最初RequestConfigSection?類中的ConfigCollection?和??RequestConfigType?類中的SourceCollection? 沒有定義ConfigurationCollection特性
而是在RequestConfigTypeCollection和RequestConfigTypeCollection?中重載了ElementName屬性,返回子級的節點名。
結果拋出節點名未定義的異常…
改由特性ConfigurationCollection定義,并給特性屬性AddItemName賦值為子級的節點名 解決…
總結
以上是生活随笔為你收集整理的自定义ConfigurationSection,创建多个嵌套的ConfigurationElementCollection节点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用gulp处理简单的前端问题
- 下一篇: 【原】iOS学习之Xcode8关于控制台