如何在web.config中配置自定义的节点,网上有很多这方面的文章,我这里只想说说在.net framework中如何实现的。由于结合例子比较好说明问题,下面来看个例子。
1.假设在web.config有这样一段自定义的代码:
1
<Itelite>
2
<Passport defaultProvider="SqlServerDataProvider">
3
<providers>
4
<add name="SqlServerDataProvider" type="Itelite.Passport.SqlDataProvider.Database,Itelite.Passport.SqlDataProvider"
5
connectionString="database=Forums;server=.;User ID=sa;Password=apple;"
6
databaseOwner="dbo" />
7
<add name="AcessDataProvider" type="Itelite.Passport.AcessDataProvider.Database,Itelite.Passport.AccessDataProvider"
8
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}"
9
databaseOwner="~/db.config" />
10
</providers>
11
</Passport>
12
</Itelite>
2. 为了获取自定义的内容,我们需要写一个类来继承IConfigurationSectionHandler.这个接口只有一个方法:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Create Method
1
internal class ConfigurationHandler : IConfigurationSectionHandler
2![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
3
public object Create(Object parent, Object context, XmlNode node)
4![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
5
Config config = new Config();
6
config.LoadValuesFromConfigurationXml(node);
7
return config;
8
}
9
}
先别管这个方法里的代码,后面再交代.
3. 问题来了,我们写这个方法在哪里调用呢?又怎么获取web.config自定义节点的内容呢?
先讲答案:我们只需要调用System.Configuration.ConfigurationSettings.GetConfig("Itelite/Passport");就可以获取节点的内容了.这个方法的返回值就是Create(...)方法返回的结果.再来分析一下下:使用Reflector打开.net framework1.1中system.dll,找到ConfigurationSettings类.该类中的GetConfig()是调用DefaultConfigurationSystem的GetConfig(),而这个类的GetConfig又是调用ConfigurationRecord类的GetConfig().ConfigurationRecord类的GetConfig()接着调用了如下方法:ResolveConfig()-->Evaluate()-->EvaluateRecursive().而就是在EvaluateRecursive()里调用了第2步中我们自定义的方法. 问题又来了,EvaluateRecursive()怎么知道我定义的那个类(ConfigurationHandler)呢?在Evaluate()方法里会根据我们在web.config配置中的type来找.如果从type的dll文件中没有任何类继承IConfigurationSectionHandler,那就要抛出异常来啦.
4. 到此为止我们还没有获取web.config中的connectionString,databaseOwner的值.我们可以定义:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Config
1
public class Config
2![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
3
public Config()
4![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
5
}
6![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
public struct CachedConfigData
8![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
9
public string ProviderTypeName;
10
public string DatabaseOwner;
11
public string ConnectionString;
12
}
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
private string defaultProvider;
15
private Hashtable providers = new Hashtable();
16![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
18
public struct CachedConfigData
19![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
20
public string ProviderTypeName;
21
public string DatabaseOwner;
22
public string ConnectionString;
23
}
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
public static Config GetConfig()
26![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
27
return (Config) ConfigurationSettings.GetConfig("Itelite/Passport");
28
}
29![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
internal void LoadValuesFromConfigurationXml(XmlNode node)
31![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
32
XmlAttributeCollection attributeCollection = node.Attributes;
33![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
34
// Get the default provider
35
//
36
defaultProvider = attributeCollection["defaultProvider"].Value;
37
//Providers.Add
38![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
39
foreach (XmlNode child in node.ChildNodes)
40![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
41![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
42
if (child.Name == "providers")
43
GetProviders(child);
44
}
45![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
46![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
}
48![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
49
// *********************************************************************
50
// GetProviders
51
//
52![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
53
/// Internal class used to populate the available providers.
54
/// </summary>
55
/// <param name="node">XmlNode of the providers to add/remove/clear.</param>
56
///
57
// ***********************************************************************/
58
internal void GetProviders(XmlNode node)
59![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
60![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
61
foreach (XmlNode provider in node.ChildNodes)
62![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
63![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
64
switch (provider.Name)
65![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
66
case "add" :
67
providers.Add(provider.Attributes["name"].Value, new Provider(provider.Attributes) );
68
break;
69![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
70
case "remove" :
71
providers.Remove(provider.Attributes["name"].Value);
72
break;
73![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
74
case "clear" :
75
providers.Clear();
76
break;
77![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
78
}
79![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
80
}
81![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
82
}
83
}
这段代码要自己看哦.
5.有个注意事项: framework2.0已经没有GetConfig()了,所以只能在1.1使用该方式了.