本人現在在一家游戲公司,最近在做一個項目,需要做一個GM的管理后臺,需要調用其他公司提供的接口,來實現后臺管理的操作
由于接口地址都是固定的,所以想到使用自定義節點,來將接口都配置到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 賦值為子級的節點名 解決…
?
老外博客地址: http://tneustaedter.blogspot.com/2011/09/how-to-create-one-or-more-nested.html ? 需要FQ訪問
或者直接看這兒,俺給Copy出來了: http://www.cnblogs.com/efenghuo/articles/4022836.html
自定義ConfigurationSection,創建多個嵌套的ConfigurationElementCollection節點
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

