自定义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节点的更多相关文章
- 自定义路径创建Cocos2d-x项目
自定义路径创建Cocos2d-x项目 本文介绍windows下面如何优雅的创建Cocos2d-x项目.为何称之为优雅,是因为现在网上流传的一些创建方法有一些问题.大致内容如下: l 使用VS向导创建 ...
- java版微信公众平台自定义菜单创建代码实现
微信公众平台自定义菜单创建代码实现—java版 搞了两天的自定义菜单,终于搞定了,现在分享下心得,以便后来者少走弯路...... 好了,先看先微信官方的API 官方写的很详细,但是我看完后很茫然,不知 ...
- 在Azure China用自定义镜像创建Azure VM Scale Set
在Azure China用自定义镜像创建Azure VM Scale Set 在此感谢世纪互联的工程师Johnny Lee和Lan,你们给了我很大的帮助.因为Azure China的官网没有给出完整的 ...
- 使用 Azure CLI 2.0 从自定义磁盘创建 Linux VM
本文说明如何在 Azure 中上传自定义的虚拟硬盘 (VHD) 或复制现有 VHD,并从自定义磁盘创建 Linux 虚拟机 (VM). 可以根据要求安装并配置 Linux 分发版,并使用该 VHD 快 ...
- 一种不通过UI给C4C自定义BO创建测试数据的方式
假设我在Cloud Studio里创建了如下一个非常简单的自定义BO: 我想生成一些该BO的实例.以前我采用的做法是给这个自定义BO创建编辑用的UI.然后使用这些UI创建BO实例.这种方式很花费时间. ...
- 什么是 DNS 的 A记录 和 CNAME记录 域名解析 为我的自定义域名创建 CNAME 记录
# CNAME https://support.google.com/blogger/answer/58317?hl=zh-Hans 为我的自定义域名创建 CNAME 记录 如果您的域名不是在 Blo ...
- 线段树&&线段树的创建线段树的查询&&单节点更新&&区间更新
目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...
- 使用 ConfigurationSection 创建自定义配置节
我们可以通过用自己的 XML 配置元素来扩展标准的 ASP.NET 配置设置集,要完成这一功能,我们必须实现继承System.Configuration.ConfigurationSection 类来 ...
- C#微信公众号开发 -- (五)自定义菜单创建
公众号中,底部都是有自己定义的功能按钮,通过点击某个按钮来实现指定的业务逻辑操作. 下面就来说说这些按钮是怎样放到微信公众平台的,还是先来看看微信的官方解释: 请注意: 1.自定义菜单最多包括3个一级 ...
随机推荐
- webpack处理非模块化的几方法
webpack处理非模块化文件有几方法,主要分为外链和webpack打包二种情况: 一.使用CDN外部链接的方法 官网文档External: https://webpack.github.io/doc ...
- 在 Excel 中使用公式拆分字符串日期
如图所示,分别使用 LEFT.MIDB.RIGHT 来拆分再拼接字符串即可: =LEFT(A1,4)&"-"&MIDB(A1,5,2)&"-&qu ...
- php 生成 Json
php 生成 Json 部分 <?php $arr_result = array(); //返回值 $arr_result['result'] = '0'; $arr_result['calle ...
- 简单配置nginx使之支持pathinfo
只需要修改3个地方就可以了 location ~ \.php { #去掉$ root H:/PHPServer/WWW; fastcgi_pass 127.0.0.1:90 ...
- android 九宫加密记事本
自己写的超级安全记事本,用PBEWithMD5AndDES加密sqlite内容几乎无法破解, 九宫点密码登录, 支持备份到SDcard,email,network drivers etc. 附件Apk ...
- WorkbookDesigner mvc里面返回file
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- eclipse 编译出错(java.io.ObjectInputStream)的解决办法
Multiple markers at this line - The type java.io.ObjectInputStream cannot be resolved. It is indirec ...
- UML2
UML中有3种构造块:事物.关系和图,事物是对模型中最具有代表性的成分的抽象:关系是把事物结合在一起:图聚集了相关的的事物.具体关系图标如下 说明:构件事物是名词,是模型的静态部分.行为事物是动态部分 ...
- encfs创建时fuse: failed to exec fusermount: Permission denied错误解决
今天用encfs创建加密文件夹时碰到提示错误fuse: failed to exec fusermount: Permission denied fuse failed. Common problem ...
- 一个代价11万的bug
这个bug不是技术bug或者是程序bug,是典型的业务操作bug. 开发人员混淆了线上数据和本地测试数据,把线上数据切换到本地的数据做测试,结果对这些客户进行了资金调整...就导致了这个悲剧发生 早在 ...