Web.config自定义节点configSections
由于最近一个项目的数据库变动比较频繁, 为了减少数据层的负担, 打算采用.net的MVC框架, 使用LINQ对付数据层.
<configSections>
<section name="NameM" type="LearningConfiguration.NameSectionHandler"/>
</configSections>
<NameM>
<Add key="name1" firstname="Jim" lastname="w1"/>
<Add key="name2" firstname="Chris" lastname="w2"/>
</NameM>

namespace LearningConfiguration
{
public class NameSectionHandler : IConfigurationSectionHandler
{
#region IConfigurationSectionHandler Members
public object Create(object parent, object configContext, XmlNode section)
{
Dictionary<string, NameManagement> names = new Dictionary<string, NameManagement>();
string key = string.Empty;
string firstName = string.Empty;
string lastName = string.Empty;
foreach (XmlNode childNode in section.ChildNodes)
{
if (childNode.Attributes["key"] != null)
{
key = childNode.Attributes["key"].Value;
if (childNode.Attributes["firstname"] != null)
{
firstName = childNode.Attributes["firstname"].Value;
}
else
{
firstName = string.Empty;
}
if (childNode.Attributes["lastname"] != null)
{
lastName = childNode.Attributes["lastname"].Value;
}
else
{
lastName = string.Empty;
}
names.Add(key, new NameManagement(firstName, lastName));
}
}
return names;
}
#endregion
}
}
{
public class NameManagement
{
string _firstName;
public string FirstName
{
get { return this._firstName; }
set { this._firstName = value; }
}
string _lastName;
public string LastName
{
get { return this._lastName; }
set { this._lastName = value; }
}
public NameManagement(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}
public string RetrieveFullName()
{
return string.Format("{0} {1}", this.FirstName, this.LastName);
}
}
}
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Dictionary<string, NameManagement> names = ConfigurationManager.GetSection("NameM") as Dictionary<string, NameManagement>;
if (names != null)
{
foreach(string key in names.Keys)
{
NameManagement name = names[key] as NameManagement;
Response.Write(name.RetrieveFullName());
}
}
}
}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Collections.Specialized;
using LearningConfiguation;
public partial class Default4 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Dictionary<String, NameManagement> names = System.Configuration.ConfigurationManager.GetSection("test/aa") as Dictionary<String, NameManagement>;
Dictionary<String, NameManagement>.KeyCollection keys = names.Keys;
foreach (String key in keys)
{
NameManagement nm = names[key] as NameManagement;
Response.Write(nm.FirstName);
Response.Write("<br>");
Response.Write(nm.LastName);
}
}
}
1.为什么需要自定义节点
为了增加应用程序的可移植性,通常网站需要配置一些自定义的节点,例如:文件上传的路径等,再深入的应用,可以定义工厂方法需要创建的类。
2.configSections使用方法
configSections节点下定义自定义节点可以帮我们实现我们自己的节点。
首先定义自己的节点,定义方法如下:
< sectionGroup name = " section group name " >
< section name = " section name " type = " configuration section handler class " />
</ sectionGroup >
</ configSections >
定义自己的节点必须在 configSections 节点。
sectionGroup 元素充当 section 元素的容器。
section 元素将配置节处理程序与配置元素或节关联。由于 ASP.NET 不对如何处理配置文件内的设置作任何假设,因此这非常必要。但 ASP.NET 会将配置数据的处理委托给配置节处理程序, ( 稍候说明。 ) 每个 section 元素均标识一个配置节或元素。可以在 sectionGroup 元素中对 section 元素进行逻辑分组,以对 section 元素进行组织并避免命名冲突。 section 和 sectionGroup 元素包含在 configSections 元素中。
sectionGroup 节点属性:
name :必选的 String 属性, 这是 group 元素在配置文件的节设置区域中使用的名称。
section 节点属性:
name :必选的 String 属性,指定与 type 属性中指定的配置节处理程序关联的配置节或元素的名称。这是该元素在配置文件的节设置区域中使用的名称。
type :必选的 String 属性,指定用来执行如下操作的配置节处理程序类的名称:处理在 name 属性中指定的节或元素中的配置设置。
现在定义好了自己的节点,可以使用该节点了。使用方法如下:
< section name >
< add key = " key1 " value = " value1 " />
</ section name >
</ section group name >
定义好了自己的节点,如何读取节点信息呢?
以下是 msdn 上的原话:
您可以用自己的 XML 配置元素来扩展标准的 ASP.NET 配置设置集。若要完成该操作,您必须创建自己的配置节处理程序。
该处理程序必须是一个实现 System.Configuration.IConfigurationSectionHandler 接口或 System.Configuration.ConfigurationSection 类的 .NET Framework 类。
节处理程序解释并处理 Web.config 文件特定部分中 XML 配置元素中定义的设置,并根据配置设置返回适当的配置对象。处理程序类返回的配置对象可以是任何数据结构;它不限于任何基配置类或配置格式。 ASP.NET 使用该配置对象,以对自定义配置元素进行读取和写入。
上面这段话的意思就是说,我们要定义一个类,这个类要继承自 System.Configuration.IConfigurationSectionHandler 接口或 System.Configuration.ConfigurationSection 类。
然后用这个类来处理我们自定义的节点。
我们看到 System.Configuration.IConfigurationSectionHandler 接口中,只有一个方法 :
Object Create (Object parent, Object configContext, XmlNode section)
返回值
创建的节处理程序对象。
这个类是干什么用的呢?让我们通过一个例子来看看。
首先,我们新建一个网站项目,并在 web.config 中加入以下节点:
< sectionGroup name = " WebSiteInfo " >
< section name = " basicInfo " type = " ConfigurationSectionTest.WebSiteInfoHandler " />
< section name = " fileUpload " type = " ConfigurationSectionTest.WebSiteInfoHandler " />
</ sectionGroup >
</ configSections >
< WebSiteInfo >
< basicInfo >
< add key = " name " value = " huchen's homepage " />
< add key = " version " value = " 1.0 " />
</ basicInfo >
< fileUpload >
< add key = " fileUploadPath " value = " E://MyHomePage//Web//Upload// " />
< add key = " fileUploadSizeMax " value = " 2M " />
</ fileUpload >
</ WebSiteInfo >
以上我们在 WebSiteInfo 节点下定义了两个节点 basicInfo 和 fileUpload ,并定义了节点处理程序类 ConfigurationSectionTest.WebSiteInfoHandler ,并且随后运用了我们定义的节点。
我们来看看节点处理程序 ConfigurationSectionTest.WebSiteInfoHandler。
任意建立一个项目,新建一个类,或者直接在 App_Code 里新建一个类,如下 :
并在 Create 函数中设置一个断点。
{
/// <summary>
/// WebSiteInfoHandler 的摘要说明
/// </summary>
public class WebSiteInfoHandler : IConfigurationSectionHandler
{
public WebSiteInfoHandler()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region IConfigurationSectionHandler 成员
public object Create( object parent, object configContext, System.Xml.XmlNode section)
{
// 这里我们首先返回个hello,并且在此处设置一个断点。看看程序什么时候执行到这。
return " hello " ;
}
#endregion
}
}
然后在 Default.aspx 的 Page_Load 事件处理程序中去访问我们自定义的节点,并在 ConfigurationSettings.GetConfig("WebSiteInfo/basicInfo"); 这条语句上设置断点。
{
Object o = ConfigurationSettings.GetConfig( " WebSiteInfo/basicInfo " );
}
好了,我们启动调试,看到程序首先执行到 ConfigurationSettings.GetConfig("WebSiteInfo/basicInfo"); 这句。
然后执行到 ConfigurationSectionTest.WebSiteInfoHandler 中的 Create 函数。
我们再看看这时处理函数中参数的值:
parent 为 null
configContext 为配置上下文对象。
section 的 InnerXml 为 <add key="name" value="huchen's homepage" /><add key="version" value="1.0" />
按F11继续执行 return "hello", 继续执行...
在执行到 Object o = ConfigurationSettings.GetConfig("WebSiteInfo/basicInfo") 后面的“ } “,我们发现 o 的值为 ”hello” 。
相信您已经明白的差不多了,当读取自定义节点的内容时,程序去执行我们定义的节点处理程序,并把节点中的内容传给 Create 函数中的参数。然后我们在 Create 中自己处理节点下的内容,并返回我们格式化后的节点内容给调用者,也就是ConfigurationSettings.GetConfig( " WebSiteInfo/basicInfo " )。
好,知道这些以后,我们就来完善我们的代码,我们在Create中处理传进来的节点内容。
为了简单起见,我们引入两个类 NameValueCollection , NameValueSectionHandler 。
NameValueCollection :表示可通过键或索引访问的关联 String 键和 String 值的集合。
NameValueSectionHandler :提供配置节中的名称 / 值对配置信息。 NameValueSectionHandler 这个类也继承 IConfigurationSectionHandler
反编译可以看出 NameValueSectionHandler 的 Create 方法把参数 section 的结果转化成了一个集合,就是 NameValueCollection 。
那么我们可以在节点处理程序中的Create函数中写如下代码:
NameValueSectionHandler baseHandler = new NameValueSectionHandler();
configs = (NameValueCollection)baseHandler.Create(parent,configContext,section);
Return configs;
这样我们就可以这样访问我们的节点了:
在 Default.aspx 的 Page_Load 事件处理程序中添加如下代码:
Response.Write(myWebSiteName);
Ctrl+F5 运行,可以看到页面输出了 huchen's homepage
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)