在ASPNET中配置数据存储在nfig文件中该文件使用xml来表示数据所有的配置信息都位于和根xml标记之间这里的配置信息分为两个区域配置节处理程序声明区域和配置节设置区域
配置节处理程序声明区域位于和xml标记之间使用section元素来声明配置节处理程序可以将这些配置节处理程序声明嵌套在sectionGroup元素中帮助组织配置信息如下所示<configSections>
<sectionGroup name=systemweb type= SystemWebConfigurationSystemWebSectionGroupSystemWeb Version= Culture=neutralPublicKeyToken=bfffdaa> <section name=pages type= SystemWebConfigurationPagesSectionSystemWeb Version= Culture=neutralPublicKeyToken=bfffdaa /> <!—— Other <section /> elements ——> </sectionGroup> <!—— Other <sectionGroup /> and <section /> elements ——> </configSections>配置节处理程序声明区域中的每个配置节都有一个节处理程序声明节处理程序是实现了ConfigurationSection类的Net Framework类节处理程序声明中包含节的名称(如pages)以及用来处理该节中配置数据的节处理程序类的名称(如SystemWebConfigurationPagesSection)如下所示<section name=pages type= SystemWebConfigurationPagesSectionSystemWeb Version= Culture=neutralPublicKeyToken=bfffdaa> </section>当您需要自定义配置节时需要完成这样几个任务一设计自己的配置节处理程序类实现ConfigurationSection类并扩展自己所需的功能二在配置节处理程序声明区域中声明节处理程序类三在配置节配置自定义的配置节
实现自己的配置节处理程序通常有两种方式也就是两种实现模型分别是声明性模型和编程模型首先我们以声明性模型来实现一个自定义配置节处理程序添加CustomSectioncs文件到网站其内容如下using Systemusing SystemConfigurationnamespace AntarDev { public class CustomSectionConfigurationSection { public CustomSection()
{ }
[ConfigurationProperty(CustomAttribute)] public String CustomAttribute { get { return (String)this[CustomAttribute]} set { this[CustomAttribute] = value}修改nfig文件在ConfigSections配置节添加自己的配置节如下所示<configSections> <sectionGroup name=newSectionGroup> <section name=newSection type=AntarDevCustomSection/> </sectionGroup> </configSections>在之后的配置节设置区域中使用我们新定义的配置节如下所示<newSectionGroup> <newSection CustomAttribute=AttributeValue /> </newSectionGroup>然后我们在Defaultaspx的Page_Load事件中书写如下代码以编程方式访问配置数据protected void Page_Load(object sender EventArgs e)
{ AntarDevCustomSection cus =(AntarDevCustomSection)ConfigurationManager GetSection(newSectionGroup/newSection)ResponseWrite(Attribute= + cusCustomAttribute)}运行网站将会输出Attribute=AttributeValue我们的自定义配置节已经可以正常工作虽然她是那么的原始而且看起来并不能完成什么具体的工作但是先让我们耐心理解这个简单的示例吧这样我们才能进一步学些自定义配置节的高级用法来帮助我们完成有意义的工作^_^在CustomSection类的实现中有下面几个细节需要解释一下继承自ConfigurationSection类这是本文中创建自定义配置节程序类的基础虽然也可以通过继承IConfigurationSectionHandler创建自定义配置节但是该接口在Net中已经被否决本文中将不讨论基于该接口的实现方法
通过对类的一个普通字符串属性(Property)CustomAttribute进行修饰使之成为了一个配置节的节属性(Attribute)这是通过ConfigurationPropertyAttribute来实现的关于该属性(Attribute)的详细用法请查阅MSDN 在CustomAttribute属性的get和set访问器中我们使用了this[CustomAttribute ]来存取节属性的值为什么可以这样使用呢?因为我们的类继承自ConfigurationSection类而该类继承自ConfigurationElement在ConfigurationElement类中定义了两个索引器如下所示protected internal object this[ConfigurationProperty prop] { get set }
protected internal object this[string propertyName] { get set }我们自己的程序中的用法正是使用的该类中的第二个索引器对配置数据进行访问通过声明性模型创建自定义配置节程序类比较简单因为他对ASPNET的基础配置架构进行了进一步的封装使我们更方便使用同时简化了程序结构
[ConfigurationProperty(CustomAttribute)]属性修饰与被修饰属性的两个访问器中的this[CustomAttribute]其中的字符串必须一致因为这个字符串就代表着要操作的节属性名称也就是在nfig中要使用的节属性名称
通过上例中的CustomSection类我们实现了如下形式的自定义配置节<newSectionGroup> <newSection CustomAttribute=AttributeValue /> </newSectionGroup>现在newSection元素仅仅是一个元素如果我们希望newSection元素可以包含子元素呢?如下所示<newSectionGroup> <newSection CustomAttribute=AttributeValue> <SubElement ElementAttribute=newValue></SubElement> </newSection> </newSectionGroup>要能够给newSection元素添加一个子元素需要对我们的自定义配置节程序类进行改进如下所示using Systemusing SystemConfigurationnamespace AntarDev { public class CustomSectionConfigurationSection { public CustomSection()
{ }
[ConfigurationProperty(CustomAttribute)] public String CustomAttribute { get { return (String)this[CustomAttribute]} set { this[CustomAttribute] = value}
[ConfigurationProperty(SubElement)] public CustomElement SubElement {//新添加的属性因为其返回类型继承自ConfigurationElement故可以在nfig中作为配置节的子元素使用
get { return (CustomElement)this[SubElement]} set { this[SubElement] = value } }
public class CustomElement ConfigurationElement {//新添加的自定义元素
[ConfigurationProperty(ElementAttribute)] public string ElementAttribute { get { return (String)this[ElementAttribute] } set { this[ElementAttribute] = value } }在上述程序中我们进行了如下改动
增加一个继承自ConfigurationElement的类CustomElement作为自定义配置节的子元素同时为该类声明一个新属性作为子元素的元素属性
在自定义配置节程序类中增加一个属性该属性使用ConfigurationPropertyAttribute修饰同时返回类型为CustomElement(继承自ConfigurationElement)
编程访问新增的子元素
protected void Page_Load(object sender EventArgs e)
{ AntarDevCustomSection cus = AntarDevCustomSection)ConfigurationManager GetSection(newSectionGroup/newSection)ResponseWrite(subElement= + cusSubElementElementAttribute)}如果希望配置节有两个或者两个以上子元素呢?类似于下面这样<newSectionGroup> <newSection CustomAttribute=AttributeValue> <SubElement ElementAttribute=newValue /> </newSection> </newSectionGroup>直接编译运行会出现错误提示SubElement只能出现一次因为该子元素在配置节处理程序中是作为一个属性存在(Property)的如果希望出现多个子元素需要使用集合的方式来实现如下所示<newSectionGroup> <newSection CustomAttribute=AttributeValue> <ElementCollection> <add ElementAttribute=CollectionTest /> <add ElementAttribute=CollectionTest /> </ElementCollection> </newSection> </newSectionGroup>为此需要对我们的自定义配置节程序类进行改进如下所示using Systemusing SystemConfigurationnamespace AntarDev { public class CustomSectionConfigurationSection { public CustomSection()
{ }
[ConfigurationProperty(CustomAttribute)] public String CustomAttribute { get { return (String)this[CustomAttribute]} set { this[CustomAttribute] = value}
[ConfigurationProperty(SubElement)] public CustomElement SubElement { get { return (CustomElement)this[SubElement]} set { this[SubElement] = value } }
[ConfigurationProperty(ElementCollection)] public CustomElementCollection SubElementCollection {//添加了一个新属性返回类型为一个继承自ConfigurationElementCollection的类get { return (CustomElementCollection)this[ElementCollection]} }
public class CustomElement ConfigurationElement { [ConfigurationProperty(ElementAttribute)] public string ElementAttribute { get { return (String)this[ElementAttribute] } set { this[ElementAttribute] = value } }
public class CustomElementCollection ConfigurationElementCollection {//新创建的类下面两个方法是继承自ConfigurationElementCollection的类必须实现的两个基本方法protected override ConfigurationElement CreateNewElement()
{ return new CustomElement()}
protected override object GetElementKey(ConfigurationElement element)
{ return ((CustomElement)element)ElementAttribute}考虑一下在appSettings配置节中常见的形式并不需要使用一个嵌套元素将子元素包围起来直接就可以使用addremoveclear元素对配置元素进行修改在我们的自定义配置节处理程序中如何实现呢?先看一下原先的实现方法[ConfigurationProperty(ElementCollection)] public CustomElementCollection SubElementCollection {//添加了一个新属性返回类型为一个继承自ConfigurationElementCollection的类get{ return (CustomElementCollection)this[ElementCollection]} }我们使用ConfigurationPropertyAttribute修饰属性将其转换为一个内置的元素集合如果将ConfigurationPropertyAttribute中的字符串改为空同时增加IsDefaultCollection=true变成下面这样[ConfigurationProperty(IsDefaultCollection=true)] public CustomElementCollection SubElementCollection {//添加了一个新属性返回类型为一个继承自ConfigurationElementCollection的类get{ return (CustomElementCollection)this[]}//这里也为空字符串}这样的话就可以像appSettings配置节那样直接操作子元素了至于newSectionGroup元素如果不喜欢去掉就是了
<newSectionGroup> <newSection CustomAttribute=AttributeValue> <add ElementAttribute=directCollection /> <add ElementAttribute=directCollection /> </newSection> </newSectionGroup>至此关于自定义配置节处理程序中常见的几种元素组织形式我们都已经可以实现细节部分在具体的项目中还需要具体完善同时NET Framework中有不少现成的配置节处理程序如果能够实现需求不放直接使用比如NameValueSectionHandler等类