本人现在在一家游戏公司,最近在做一个项目,需要做一个GM的管理后台,需要调用其他公司提供的接口,来实现后台管理的操作
由于接口地址都是固定的,所以想到使用自定义节点,来将接口都配置到web.config中。
很快,v1.0版本出炉:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
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中的配置方式为:
1
2
3
4
5
6
7
|
<apiRequestConfig>
<sources>
<add name=
"..."
url=
"..."
type=
"POST"
/>
<add name=
"..."
url=
"..."
type=
"POST"
/>
<add name=
"..."
url=
"..."
type=
"POST"
/>
</sources>
</apiRequestConfig>
|
这时候又看了一遍需求文档,发现有说明不同平台的接口地址是不一样的,但接口做的事情是一样的。
然后就开始想,如果接着在下边追加,则不同平台的同一接口的名称是不能相同的。
所以想到的理想的配置方式为:
1
2
3
4
5
6
7
8
9
10
11
12
|
<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…
最终在一老外的博客里找到了一个替代的解决方案,最终的配置为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<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#代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
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