由于接口地址都是固定的,所以想到使用自定义节点,来将接口都配置到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. 自定义路径创建Cocos2d-x项目

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

  2. java版微信公众平台自定义菜单创建代码实现

    微信公众平台自定义菜单创建代码实现—java版 搞了两天的自定义菜单,终于搞定了,现在分享下心得,以便后来者少走弯路...... 好了,先看先微信官方的API 官方写的很详细,但是我看完后很茫然,不知 ...

  3. 在Azure China用自定义镜像创建Azure VM Scale Set

    在Azure China用自定义镜像创建Azure VM Scale Set 在此感谢世纪互联的工程师Johnny Lee和Lan,你们给了我很大的帮助.因为Azure China的官网没有给出完整的 ...

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

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

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

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

  6. 什么是 DNS 的 A记录 和 CNAME记录 域名解析 为我的自定义域名创建 CNAME 记录

    # CNAME https://support.google.com/blogger/answer/58317?hl=zh-Hans 为我的自定义域名创建 CNAME 记录 如果您的域名不是在 Blo ...

  7. 线段树&&线段树的创建线段树的查询&&单节点更新&&区间更新

    目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...

  8. 使用 ConfigurationSection 创建自定义配置节

    我们可以通过用自己的 XML 配置元素来扩展标准的 ASP.NET 配置设置集,要完成这一功能,我们必须实现继承System.Configuration.ConfigurationSection 类来 ...

  9. C#微信公众号开发 -- (五)自定义菜单创建

    公众号中,底部都是有自己定义的功能按钮,通过点击某个按钮来实现指定的业务逻辑操作. 下面就来说说这些按钮是怎样放到微信公众平台的,还是先来看看微信的官方解释: 请注意: 1.自定义菜单最多包括3个一级 ...

随机推荐

  1. Python中is和==的区别

    Python中有很多运算符,今天我们就来讲讲is和==两种运算符在应用上的本质区别是什么. 在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,分别是:id(身份标识) ...

  2. Moto G 通话没声音

    入手了摩托罗拉被 Google 收购后推出的第二款手机 Moto G (第一款是 Moto X) 后发现有个问题,有时候会莫名其妙地通话没声音,你听不到对方的,对方也听不到你的,从网上的搜索结果来看, ...

  3. CAS认证原理图

  4. Timeout 时间已到。在操作完成之前超时时间已过或服务器未响应。

    近来遇到这样一个错误:Timeout 时间已到.在操作完成之前超时时间已过或服务器未响应.错误截图如下: 错误原因分析:产生错误时我执行的操作需要的执行时间比较长.我测试了一下,那个操作用到的存储过程 ...

  5. 牛顿方法(Newton-Raphson Method)

    本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ 牛顿方法是一种求解等式的非常有效的数值分析方法. 1.  牛顿方法 假设\(x_0\)是等式的 ...

  6. CLR via C#深解笔记六 - 泛型

    面向对象编程一个好处就是“代码重用”,极大提高了开发效率.如是,可以派生出一个类,让它继承基类的所有能力,派生类只需要重写虚方法,或添加一些新的方法,就可以定制派生类的行为,使之满足开发人员的需求. ...

  7. 二十一、【.Net开源框架】EFW框架Web前端开发之目录结构和使用FireBug调试方法

    回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan.baidu. ...

  8. ASP.NET服务器控件使用之Reportviewer 报表

    http://blog.csdn.net/oemoon/article/details/7338967 http://www.cnblogs.com/emanlee/archive/2008/09/1 ...

  9. NET实现微信分享和获取openid

    VS2010开发,MVC3架构. 通过调用微信官方接口实现获取openid,和分享好友功能,实现获取signature和jsapi_ticket,并在服务端进行缓存AccessToken和jsapi_ ...

  10. 蓝凌OA二次开发手册

    1.蓝凌OA表单前端调用后台数据 一.后台存储过程: create procedure sp_test @ftext nvarchar(50) as begin select @ftext as '测 ...