創建自定義配置節點(web.config和app.config都適用)

  • 2019 年 10 月 7 日
  • 筆記

  惱火!不小心點到全屏幕模式,剛寫的東西全丟了!!從頭再來!!!

  無論是web程序、windows程序、windows service程序,配置文件都是少不了的。我們都習慣了將連接字符串放在ConnectionString節點中,將程序的設置放在appSetting節點中。配置文件的管理程序為我們提供了方便的管理方式,那麼,我們如何自定義配置節點呢?

  有兩種方法,其一,繼承IConfigurationSectionHandler,通過實現Create方法。這種方法的靈活度非常大,我們需要動手解析自定義節點的XmlNode,所以,實現起來也比較複雜。其二,繼承ConfigurationSection,這種方法就簡單多了,只需要指定對應的屬性名稱即可。

  本文旨在使用最少的代碼實現自定義配置節點,所以果斷放棄第一種方法,使用第二種方法實現自定義配置節點。

  光說不練假把式,接下來我們就着手使用第二種方法實現自定義配置節點。步驟如下:

  1.在configSections節點中定義自定義配置節點信息

  <configSections>      <section name="custom" type="SampleWebConfigSection.Configuration.customSection, SampleWebConfigSection" />    </configSections>
  • name:自定義配置節點的名稱
  • type:類型,自定義配置節點對應的數據類型

  2.完成自定義配置節點的結構

<custom fileName="Default.txt" maxUsers="2500" maxIdleTime="00:10:00" />

  3.編程實現節點的訪問

using System.Configuration;  using System;    namespace SampleWebConfigSection.Configuration  {      public class customSection : ConfigurationSection      {          [ConfigurationProperty("fileName", DefaultValue = "default.txt", IsRequired = true, IsKey = false)]          [StringValidator(InvalidCharacters = " ~!@#$%^&*()[]{}/;'"|\", MinLength = 1, MaxLength = 60)]          public string FileName          {              get { return (string)this["fileName"]; }              set { this["fileName"] = value; }          }            [ConfigurationProperty("maxUsers", DefaultValue = (long)10000, IsRequired = false)]          [LongValidator(MinValue = 1, MaxValue = 10000000, ExcludeRange = false)]          public long MaxUsers          {              get { return (long)this["maxUsers"]; }              set { this["maxUsers"] = value; }          }            [ConfigurationProperty("maxIdleTime", DefaultValue = "0:10:0", IsRequired = false)]          [TimeSpanValidator(MinValueString = "0:0:30", MaxValueString = "5:00:0", ExcludeRange = false)]          public TimeSpan MaxIdleTime          {              get { return (TimeSpan)this["maxIdleTime"]; }              set { this["maxIdleTime"] = value; }          }      }  }
  • ConfigurationProperty標記:指示 .NET Framework 通過custom節點的屬性來實例化對象的字段值。對於每一個標記有此特性的屬性,.NET Framework 都使用反射來讀取修飾參數,並創建相關的 ConfigurationProperty 實例。
  • StringValidator標記:以聲明的方式指示 .NET Framework 對配置屬性執行字符串驗證。
  • LongValidator標記:以聲明的方式指示 .NET Framework 對配置屬性執行長整型驗證。
  • TimeSpanValidator標記:以聲明的方式指示 .NET Framework 對配置屬性執行時間驗證。

  4.自定義配置節點的使用

    customSection custom = (customSection)System.Configuration.ConfigurationManager.GetSection("custom");      Response.Write(custom.FileName + "|" + custom.MaxUsers.ToString() + "|" + custom.MaxIdleTime);

  在第一句代碼中,我們通過ConfigurationManager.GetSection獲取custom節點,並強制類型轉換為我們自定義的節點,這樣就能夠方便的使用了。

  OK,第一個例子完成。其實這個例子是MSDN中的,我將它拿下來,稍加說明而已。

  當然,只有上面這些內容是不足以放首頁的。上面的例子並不能完全滿足我們常規的需求,甚至我們可以把這些配置放在appSetting中來替代我們的自定義配置節點。下面介紹一個實際的需求:

  在網站的建設中,我們希望將網站的標題、副標題和網址放在一條配置中,因為網站有文件上傳功能,我們希望在配置中限制上傳文件的大小,並針對不同的上傳類型將文件放在不同的目錄中。定以後的節點結構如下:

  <webSetting>      <base title="草屋&amp;拾荒" subTitle="七千米深藍的博客" url="http://youring2.cnblogs.com"></base>      <fileUpload>        <file name="headPhoto" path="upload/image/headPhoto" size="200"></file>        <file name="album" path="upload/image/album" size="1024"></file>      </fileUpload>    </webSetting>

  要完成這個自定義配置節點,按照第一個例子的步驟,我們需要現在configSections中配置自定義節點信息:

<section name="webSetting" type="SampleWebConfigSection.Configuration.webSettingSection, SampleWebConfigSection" />

  不解釋,接下來我們需要完成四個類:

  • webSettingSection
  • baseSection
  • fileUploadSection
  • fileSection

  這四個類分別對應這個配置中的四個節點:webSetting、base、fileUpload和file。

using System.Configuration;    namespace SampleWebConfigSection.Configuration  {      public class webSettingSection : ConfigurationSection      {          //base節點          [ConfigurationProperty("base")]          public baseSection BaseSetting { get {return (baseSection)base["base"]; } }            //fileUpload節點          [ConfigurationProperty("fileUpload")]          public fileUploadSection FileUploadSetting { get { return (fileUploadSection)base["fileUpload"]; } }      }  }

  派生自ConfigurationSection,包含兩個屬性:BaseSetting和FileUploadSetting,這兩個屬性分別對應配置文件中的兩個子節點base 和fileUpload。

using System.Configuration;    namespace SampleWebConfigSection.Configuration  {      public class baseSection : ConfigurationElement      {          //title屬性          [ConfigurationProperty("title", IsKey = true, IsRequired = true)]          public string title { get { return (string)base["title"]; } set { title = value; } }          //subTitle屬性          [ConfigurationProperty("subTitle",  IsRequired = false, DefaultValue="")]          public string subTitle { get { return (string)base["subTitle"]; } set { subTitle = value; } }          //url屬性          [ConfigurationProperty("url", IsRequired = true)]          public string url { get { return (string)base["url"]; } set { url = value; } }      }  }

  派生自ConfigurationElement,因為它是一個子元素,被包含在webSettingSection類中。它的幾個屬性不作解釋。

using System.Configuration;    namespace SampleWebConfigSection.Configuration  {      [ConfigurationCollection(typeof(fileSection), AddItemName = "file")]      public class fileUploadSection : ConfigurationElementCollection      {          protected override ConfigurationElement CreateNewElement()          {              return new fileSection();          }            protected override object GetElementKey(ConfigurationElement element)          {              return ((fileSection)element).name;          }            public fileSection this[int index]          {              get { return (fileSection)base.BaseGet(index); }          }            new public fileSection this[string name]          {              get { return (fileSection)base.BaseGet(name); }          }      }  }

  派生自ConfigurationElementCollection,因為它是一個子元素的集合,它包含一個fileSection的集合。

  這個類使用了如下的標記:

[ConfigurationCollection(typeof(fileSection), AddItemName = "file")]

  這是一個子元素集合的說明,第一個type參數是必須的,它指定了包含子集的類型。第二個參數是可選的,它指定了要添加到集合中的子節點的節點名,默認是是add,我們沒有使用默認值,而是使用了「file」,所以在這裡進行了指定。

  另外,這個類還實現了通過index和name獲取一個fileSection的方法,分別是this[int index]和this[string name]。基類本身存在通過字符串獲取子元素的方法,所以這裡要使用new關鍵字。

using System.Configuration;    namespace SampleWebConfigSection.Configuration  {      public class fileSection : ConfigurationElement      {          //name屬性          [ConfigurationProperty("name", IsKey = true, IsRequired = true)]          public string name { get { return (string)this["name"]; } set { name = value; } }          //path屬性          [ConfigurationProperty("path", IsRequired = true)]          public string path { get { return (string)this["path"]; } set { path = value; } }          //size屬性          [ConfigurationProperty("size", IsRequired = true, DefaultValue = 1024)]          public int size { get { return (int)this["size"]; } set { size = value; } }      }  }

  派生自ConfigurationElement。它的屬性很簡單,不解釋。

  我們可以使用如同第一個示例中使用自定義配置節點的方法使用這個配置節點。但通常我們不希望每次使用的時候都重新加載一次配置項,所以,我們通過一個靜態對象來訪問這個配置節點:

namespace SampleWebConfigSection.Configuration  {      public class WebSettingManager      {          public static webSettingSection WebSetting = (webSettingSection)System.Configuration.ConfigurationManager.GetSection("webSetting");      }  }

  測試一下我們的自定義配置節點是否好使,在網站的頁面中加入如下代碼:

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">      <h2>          <asp:Label ID="lblTitle" Text="" runat="server" />      </h2>      <h3>           <asp:Label ID="lblSubTitle" Text="" runat="server" />      </h3>      地址:<asp:Label ID="lblUrl" Text="" runat="server" />      <p></p><p></p>      <asp:GridView ID="gvFileUploadSetting" runat="server" Width="300" BackColor="#F0F8FF" AutoGenerateColumns="false">          <Columns>              <asp:TemplateField HeaderText="名稱">                  <HeaderStyle Width="80px" Font-Bold="true" />                  <ItemStyle Font-Bold="false" />                  <ItemTemplate>                      <%#Eval("name")%>                  </ItemTemplate>              </asp:TemplateField>              <asp:TemplateField HeaderText="路徑">                  <HeaderStyle Width="160px" Font-Bold="true" />                  <ItemStyle Font-Bold="false" />                  <ItemTemplate>                      <%#Eval("path")%>                  </ItemTemplate>              </asp:TemplateField>              <asp:TemplateField HeaderText="大小">                  <HeaderStyle Width="60px" Font-Bold="true" />                  <ItemStyle Font-Bold="false" />                  <ItemTemplate>                      <%#Eval("size")%>                  </ItemTemplate>              </asp:TemplateField>          </Columns>      </asp:GridView>  </asp:Content>
        protected void Page_Load(object sender, EventArgs e)          {              this.Title = WebSettingManager.WebSetting.BaseSetting.title + " - " + WebSettingManager.WebSetting.BaseSetting.subTitle;              this.lblTitle.Text = WebSettingManager.WebSetting.BaseSetting.title;              this.lblSubTitle.Text = WebSettingManager.WebSetting.BaseSetting.subTitle;              this.lblUrl.Text = WebSettingManager.WebSetting.BaseSetting.url;                this.gvFileUploadSetting.DataSource = WebSettingManager.WebSetting.FileUploadSetting;              this.gvFileUploadSetting.DataBind();          }

  運行網站,我們可以看到如下界面,說明我們的配置節點是可用的:

我們可以休息了,哈哈,附上源代碼:http://files.cnblogs.com/youring2/SampleWebConfigSection.rar

另外,通過實現System.Configuration.IConfigurationSectionHandler接口來實現自定義配置節點感興趣的朋友可以點擊這裡

再附上MSDN上面關於兩種實現方法的地址:

http://msdn.microsoft.com/zh-cn/library/2tw134k3(v=VS.100).aspx

http://msdn.microsoft.com/zh-cn/library/ms228056.aspx

我們可以真的休息了,如果你覺得這篇文章還不錯,點擊一下推薦鏈接也不費勁,卻可以給我很大鼓勵,謝謝您的關注!

————————————————-

ps.補充一點Configuration自定義節點結構:

  • ConfigurationSection:對應整個自定義節點Xml的最外層節點
  • ConfigurationElement:Section節點下的一個子節點,不包含集合
  • ConfigurationElementCollection:對應Element集合