Asp.net配置文件中自定義節點詳解


在開發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

希望有用,謝謝…

源代碼下載:點擊這里下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM