由于接口地址都是固定的,所以想到使用自定义节点,来将接口都配置到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. javascript一种新的对象创建方式-Object.create()

    1.Object.create() 是什么? Object.create(proto [, propertiesObject ]) 是E5中提出的一种新的对象创建方式,第一个参数是要继承的原型,如果不 ...

  2. Ubuntu server解决不能访问外网问题

    Ubuntu server解决不能访问外网问题 在Ubuntu Server上设置访问外网时,需要设置dns,通常是将dns添加到/etc/resolv.conf文件中. 但是将dns添加至/etc/ ...

  3. TargetProcess 中更改了域名如何修改里面的附件地址

    在默认情况,TP 安装的目录是默认的网站(IIS)的targetprocess2下面,但是如果想采用 tp.targetprocess.cn 这种方式直接访问,则需要做一些设置. 基本要点如下: 1. ...

  4. java代写

    Computer Science, Claremont McKenna CollegeCS51.2 - Introduction to Computer Science, Fall 2014Probl ...

  5. AngularJS初始化闪烁

    可以使用:ng-if和ng-cloak解决,原因见:http://www.cnblogs.com/whitewolf/p/3495822.html

  6. popupwindow 与 输入法

    有时候popupwindow会被输入法覆盖, 有时候popupwindow会被输入法给顶上去. 而且这个问题还跟theme的windowFullscreen属性相关. 不过这些可以都不用管, 根据项目 ...

  7. redhat下mysql安装与使用

    1.安装 (1)查看是否安装 yum list installed mysql* (2)查看现有安装包 yum list mysql* (3)安装mysql服务器端 yum install mysql ...

  8. Ubuntu14.04安装中文输入法以及解决Gedit中文乱码问题

    1 设置中文显示环境 1. 打开System Settings 2. 打开Personal-> Language Support. 会弹出如下对话框,提示你“语言支持没安装完整”. 点击“Rem ...

  9. 顺序执行到来的消息 actor

    在某项目里,有个 actor 需要做一些持久化的操作,这些操作耗时比较久,理应使用异步的代码来写,但是需求又强调每次只能做一个持久化操作,后来的请求应该等待.一个显然的做法是阻塞式的写,这样就能比较简 ...

  10. CORS Cookie,和nodejs中的具体实现

    CORS(跨来源资源共享协议),高级浏览器(Chrome,firefox, opera, safir, ie10)在 XMLHttpRequest(AJAX) 中已经支持了这个协议.可以实现ajax跨 ...