由于接口地址都是固定的,所以想到使用自定义节点,来将接口都配置到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特性

而是在RequestConfigTypeCollectionRequestConfigTypeCollection 中重载了ElementName属性,返回子级的节点名。

结果抛出节点名未定义的异常…

改由特性ConfigurationCollection定义,并给特性属性AddItemName赋值为子级的节点名 解决…

自定义ConfigurationSection,创建多个嵌套的ConfigurationElementCollection节点相关推荐

  1. 使用 Azure CLI 2.0 从自定义磁盘创建 Linux VM

    本文说明如何在 Azure 中上传自定义的虚拟硬盘 (VHD) 或复制现有 VHD,并从自定义磁盘创建 Linux 虚拟机 (VM). 可以根据要求安装并配置 Linux 分发版,并使用该 VHD 快 ...

  2. 各种 SAP 产品的自定义 UI 创建和集成方法一览

    这是 Jerry 2021 年的第 70 篇文章,也是汪子熙公众号总共第 347 篇原创文章. Jerry 之前通过下列两篇文章,介绍了构成 SAP 产品 UI 的逻辑单元:UI 组件和 UI 容器组 ...

  3. 一种不通过UI给C4C自定义BO创建测试数据的方式

    假设我在Cloud Studio里创建了如下一个非常简单的自定义BO: 我想生成一些该BO的实例.以前我采用的做法是给这个自定义BO创建编辑用的UI.然后使用这些UI创建BO实例.这种方式很花费时间. ...

  4. 利用Packer自定义镜像创建容器集群

    阿里云容器服务Kubernetes集群支持CentOS操作系统,在绝大多数情况下可以满足客户的要求.但是有些客户由于业务系统对操作系统依赖比较高,希望定制化一些操作系统参数,则可以用自定义镜像来创建K ...

  5. 自定义路径创建Cocos2d-x项目

    自定义路径创建Cocos2d-x项目 本文介绍windows下面如何优雅的创建Cocos2d-x项目.为何称之为优雅,是因为现在网上流传的一些创建方法有一些问题.大致内容如下: l 使用VS向导创建C ...

  6. python自定义函数名_使用自定义名称创建Python动态函数

    如果这个问题已经提出并得到了回答,我深表歉意. 我需要做的是非常简单的概念,但不幸的是,我还没有找到一个在线答案. 我需要在Python(Python2.7)中使用运行时的自定义名称创建动态函数.每个 ...

  7. 通过自定义镜像创建具有相同操作系统、应用程序和数据的百度云服务器BCC,有效提高交付效率!

    由于业务需求有时候我们需要创建N个拥有相同操作系统.应用程序和数据的百度云服务器实例,这显然不能纯手工拷贝数据.配置环境.安装程序,毕竟重复大量的操作真的好难熬 [/擦汗] 这个时候就可以使用自定义镜 ...

  8. java操作跨页的word cell_Java 创建Word表格/嵌套表格、添加/复制表格行或列、设置表格跨页断行...

    概述 表格作为一种可视化交流模式及组织整理数据的手段,在各种场合及文档中应用广泛.常见的表格可包含文字.图片等元素,我们操作表格时可以插入图片.写入文字及格式化表格样式等.下面,将通过Java编程在W ...

  9. MySQL自定义函数创建与使用总结

    MySQL自定义函数创建与使用总结 MySQL自定义函数和存储过程类似,也需要在数据库中创建并保存.它与存储过程一样,都是由SQL语句和控制语句组成的代码片段,可以被应用程序和其他SQL语句调用. M ...

最新文章

  1. 他211本硕毕业,一边是年薪15万国企送北京户口,一边是28万大厂offer,究竟该怎么选?...
  2. @Value获取值和@ConfigurationProperties获取值比较||配置文件注入值数据校验
  3. java uri_Android中的Uri与Java中的URI类
  4. java通用分页条件查询_通用分页查询
  5. c语言几种排序方法的比较,基于C语言的几种排序方法比较.doc
  6. leetcode-卡车加气走环
  7. JAVA EE 6 jar包集合_Java EE6将JSF facelets(xhtml)和ManagedBeans打包成JAR
  8. 通过静态发现方式部署 Etcd 集群
  9. [Common 17-39] ‘connect_bd_intf_net‘ failed due to earlier errors. 的解决办法
  10. 一篇关于蓝牙SDP和L2CAP协议的文章
  11. WPF MediaElement循环播放
  12. 佳能mp145/mp140/mp288打印机 e16代码怎么处理
  13. python从键盘上输入10个数、求其平均值_从键盘上循环输入10个数,求其平均值,并打印输出....
  14. python死循环_python中死循环
  15. H5C3第二个完整大项目————天猫国际首页跳转登录页
  16. java 方法继承方法_java的继承原理与实现方法详解
  17. 《PYTHON编程初学者指南》pdf
  18. 手把手教学用Python合成大西瓜
  19. python软件介绍-python软件界面介绍(python软件介绍)
  20. 如何把控签到效率?如何选择最合适的签到方式?

热门文章

  1. 友元实例:友元类及友元函数
  2. HEAP: Free Heap block XXXX modified at XXXX after it was freed
  3. Chrome 的又一个bug?
  4. Flutter介绍 - Flutter,H5,React Native之间的对比
  5. 自定义简单版本python线程池
  6. 程序员的魔法——用Masking GAN让100,000人都露出灿烂笑容
  7. Android开发环境——模拟器AVD相关内容汇总
  8. SpringMVC+Mybatis+MySQL配置Redis缓存
  9. 【网络编程】——connect函数遇见EINTR的处理
  10. ISP_MPLS *** 理论笔记