在开发Asp.net站点的时候,我们会遇到很多的配置参数:网站名称,上传图片后缀,上传文件后缀,关键字过滤,数据库连接字串等等,这些内容如果比较少的话,直接配置到Web.config文件中,借由.NET提供的操作类,将会非常方便的来操作这些自定义配置节点,以下文章只是在Fish-Li的文章基础上而来,具体内容如下:
首先,配置一个最简单的节点,类似
<MySection username="程序诗人" url="http://scy251147.cnblogs.com" comment="注意啦!!!!!!" />
这个该如何来进行呢?
在Web.Config中,如果想配置这样的自定义节点,需要首先在configuration节点下的configSections节点中进行注册,如下:
<section name="MySection" type="WebApplication1.MySection,WebApplication1"/>
这样,我们只需要将MySection节点配置在configuration节点下即可,具体的ScreenShot如下:
那么如何在界面上展示出来呢?首先得需要定义一个类继承自ConfigurationSection才可以继续后面的操作.
using System.Configuration;
namespace WebApplication1 { public class MySection:ConfigurationSection { [ConfigurationProperty("username", IsRequired = true)] public string UserName { get { return this["username"].ToString(); } set { this["username"] = value; } }
[ConfigurationProperty("url", IsRequired = true)] public string Url { get { return this["url"].ToString(); } set { this["url"] = value; } }
[ConfigurationProperty("comment", IsRequired = true)] public string Comment { get { return this["comment"].ToString(); } set { this["comment"] = value; } } } }
在界面上可以通过如下方式来显示:
MySection mySection = (MySection)ConfigurationManager.GetSection("MySection"); Response.Write(mySection.UserName + "----" + mySection.Url+"----"+mySection.Comment);
其次对于一个稍微复杂一点的自定义节点,这个自定义节点下面有子节点,这个该如何来进行呢?类似:
<MySectionWithChild>
<users username="程序诗人" url="http://scy251147.cnblogs.com" comment="注意啦!!!!!" />
</MySectionWithChild>
这个在Web.Config中的配置和前面类似,就是先注册节点,然后将节点放到configuration节点下:
当然,如果要访问这个自定义节点,也需要通过类来配置,我们得首先定义一个父节点类,父节点类包含子节点元素:
父节点类:
using System.Configuration;
namespace WebApplication1 { public class MySectionParent:ConfigurationSection { [ConfigurationProperty("users", IsRequired = true)] public MySectionWithChild Users { get { return (MySectionWithChild)this["users"]; } } } }
子节点类(注意这里的子节点类需要继承自ConfigurationElement类):
using System.Configuration;
namespace WebApplication1 { public class MySectionWithChild:ConfigurationElement { [ConfigurationProperty("username", IsRequired = true)] public string UserName { get { return this["username"].ToString(); } set { this["username"] = value; } }
[ConfigurationProperty("url", IsRequired = true)] public string Url { get { return this["url"].ToString(); } set { this["url"] = value; } }
[ConfigurationProperty("comment", IsRequired = true)] public string Comment { get { return this["comment"].ToString(); } set { this["comment"] = value; } } } }
如何在界面上使用呢?可以通过如下的方式:
MySectionParent mySectionParent = (MySectionParent)ConfigurationManager.GetSection("MySectionWithChild"); MySectionWithChild users = mySectionParent.Users; Response.Write(users.UserName + "----" + users.Url + "----" + users.Comment);
再者,我们知道xml文件中是不能包含形如<的关键字符的,这将导致xml报错.假设我们将SQL语句配置在了配置文件中,那么这种关键字是不可避免的,当然,遇到这种问题我们可以利用CDATA标签来避免,假设在配置文件中存在CDATA标签,我们该如何读取其数据呢?先看节点配置:
这种情况和第二种类似,即一个父节点,里面包含有子节点,当然也需要两个类支持,一个类继承自ConfigurationSection,而另一个类继承自ConfigurationElement,类操作代码如下:
父节点类:
using System.Configuration;
namespace WebApplication1 { public class MySectionWithPlainTextCollection:ConfigurationSection { [ConfigurationProperty("CommandOne", IsRequired = true)] public MySectionWithPlainText CommandOne { get { return (MySectionWithPlainText)this["CommandOne"]; } }
[ConfigurationProperty("CommandTwo", IsRequired = true)] public MySectionWithPlainText CommandTwo { get { return (MySectionWithPlainText)this["CommandTwo"]; } } } }
子节点类:
using System.Configuration;
namespace WebApplication1 { public class MySectionWithPlainText:ConfigurationElement {
[ConfigurationProperty("data", IsRequired = true)] public string CommandText { get { return this["data"].ToString(); } set { this["data"] = value; } }
//反序列化 protected override void DeserializeElement(System.Xml.XmlReader reader, bool serializeCollectionKey) { CommandText = reader.ReadElementContentAs(typeof(string), null) as string; }
//序列化 protected override bool SerializeElement(System.Xml.XmlWriter writer, bool serializeCollectionKey) { if (writer != null) writer.WriteCData(CommandText); return true; } } }
需要说明一下,在进行这样的自定义节点操作的时候,系统已经通过重载序列化和反序列化标志,对特殊字符进行了还原处理.在界面上显示的做法如下:
MySectionWithPlainTextCollection planCommand = (MySectionWithPlainTextCollection)ConfigurationManager.GetSection("MySectionWithPlainText");
//这条命令里面我专门放置了小于号(<)用来测试其正确性 Response.Write(planCommand.CommandOne.CommandText.ToString()+"</br>"); Response.Write(planCommand.CommandTwo.CommandText.ToString()+"</br>");
最后,是我们最熟悉的,即在通过ConnectionString配置数据库连接字串的时候经常遇到的含有key值和value值的节点:
像这种自定义节点,使用的是比较多的,大多属于配置型的,我们该如何来进行读取呢?像这种具有键值对的,读取方法和上面类似,只是稍微麻烦了一点,我们当然还是首先定义一个父节点类,同样继承自ConfigurationSection:
using System.Configuration;
namespace WebApplication1 { public class MySectionCollection:ConfigurationSection { private static readonly ConfigurationProperty property = new ConfigurationProperty(string.Empty, typeof(MySectionKeyValue), null, ConfigurationPropertyOptions.IsDefaultCollection);
[ConfigurationProperty("",Options = ConfigurationPropertyOptions.IsDefaultCollection)] public MySectionKeyValue KeyValues { get { return (MySectionKeyValue)base[property]; } } } }
由于这样的自定义节点含有多个<add …></add>标签,所以我们得需要定义一个ConfigurationElementCollection的集合,这个集合中可以通过索引方式来获取单个的键值对,方法中包含了对Element的创建,删除,获取的功能:
using System.Configuration; using System;
namespace WebApplication1 { [ConfigurationCollection(typeof(MySectionKeyValueSettings))] public class MySectionKeyValue : ConfigurationElementCollection { public MySectionKeyValue() : base(StringComparer.OrdinalIgnoreCase) //忽略大小写 {
}
//其实关键就是这个索引器,但它也是调用基类的实现,只是做下类型转换就行了 new public MySectionKeyValueSettings this[string name] { get { return (MySectionKeyValueSettings)base.BaseGet(name); } }
//下面二个方法中抽象类中必须要实现的 protected override ConfigurationElement CreateNewElement() { return new MySectionKeyValueSettings(); }
protected override object GetElementKey(ConfigurationElement element) { return ((MySectionKeyValueSettings)element).Key; }
//说明:如果不需要在代码中修改集合,可以不实现Add,Clear,Remove public void Add(MySectionKeyValueSettings setting) { this.BaseAdd(setting); }
public void Clear() { this.BaseClear(); }
public void Get(MySectionKeyValueSettings setting) { this.BaseGet(setting.Key); }
public void Remove(string name) { base.BaseRemove(name); } } }
最后是单个键值对类,继承自ConfigurationElement:
using System.Configuration;
namespace WebApplication1 { public class MySectionKeyValueSettings:ConfigurationElement { [ConfigurationProperty("key", IsRequired = true)] public string Key { get { return this["key"].ToString(); } set { this["key"] = value; } }
[ConfigurationProperty("value", IsRequired = true)] public string Value { get { return this["value"].ToString(); } set { this["value"] = value; } } } }
使用方式如下:
MySectionCollection sectionCollection = (MySectionCollection)ConfigurationManager.GetSection("MySectionCollection"); sResponse.Write(string.Join("</br>",( from kv in sectionCollection.KeyValues.Cast<MySectionKeyValueSettings>() let s=string.Format("{0}={1}",kv.Key,kv.Value) select s).ToArray() ));
这样,通过上面的四个步骤,我们就可以读取自定义节点的值,显示效果如下:
至于修改节点内容的方法,我就不过于多说了,比较简单,见如下代码:
#region 编辑节点
Configuration config = WebConfigurationManager.OpenWebConfiguration("/");
protected void Button1_Click(object sender, EventArgs e) { MySection section1 = config.GetSection("MySection") as MySection; section1.Comment = "注意啦,我是修改以后的内容!!!!!!"; ConfigurationManager.RefreshSection("MySection"); config.Save();
Response.Write(section1.UserName + "----" + section1.Url + "----" + section1.Comment); }
protected void Button2_Click(object sender, EventArgs e) { MySectionParent section2 = config.GetSection("MySectionWithChild") as MySectionParent; section2.Users.Comment = "注意啦,我也是修改以后的内容!!!!!"; ConfigurationManager.RefreshSection("MySectionWithChild"); config.Save();
Response.Write(section2.Users.UserName + "----" + section2.Users.Url + "----" + section2.Users.Comment); }
protected void Button3_Click(object sender, EventArgs e) { MySectionWithPlainTextCollection section3 = config.GetSection("MySectionWithPlainText") as MySectionWithPlainTextCollection; section3.CommandOne.CommandText = "select * from trade"; ConfigurationManager.RefreshSection("MySectionWithPlainText"); config.Save();
Response.Write(section3.CommandOne.CommandText.ToString() + "</br>"); Response.Write(section3.CommandTwo.CommandText.ToString() + "</br>"); }
protected void Button4_Click(object sender, EventArgs e) { MySectionCollection section4 = config.GetSection("MySectionCollection") as MySectionCollection; MySectionKeyValueSettings setting = new MySectionKeyValueSettings(); setting.Key = "testnode"; setting.Value = "testvalue"; section4.KeyValues.Add(setting);
config.Save();
Response.Write(string.Join("</br>", ( from kv in section4.KeyValues.Cast<MySectionKeyValueSettings>() let s = string.Format("{0}={1}", kv.Key, kv.Value) select s).ToArray() )); } #endregion
希望有用,谢谢…
源代码下载:点击这里下载
|
请发表评论