前言
昨天修改代碼發現了一個問題,由于自己要在WCF服務接口中添加了一個方法,那么在相應調用的地方進行更新服務就可以了,不料意外發生了,竟然無法更新。左查右查終于發現了問題。App.config配置文件中的配置貌似出現了問題。查找節點發現是如下節點:
<configSections> <section name="Test1" type="Demo.Section1,Demo"/> .............. </configSections>
我當時也只是看到了下劃波浪線,才猜測是這里的問題,于是我把configSections節點注釋后,重新更新WCF服務,沒想到真的可以更新了,心想這是個什么節點呢,雖然之前自己也見過這個節點,但是從來沒用過,于是趁此機會就進行簡單的學習一下吧,以便之后說不定什么時候就會用到。
這里我的講解暫時之針對.NET的Web.config文件和App.confg文件,也就是對.Net配置文件自定義節點進行學習記錄。
配置文件優先級
在此簡單的學習一個配置文件的優先級吧,因為自己之前對配置文件接觸的也比較少,沒詳細的進行學習過。
首先在.net提供了一個針對當前機器的配置文件,這個文件是machine.config。所在地址如下圖所示。
然后此文件夾下還存在一個Web.confg的配置文件。
asp.net網站IIS啟動的時候會加載配置文件中的配置信息,然后緩存這些信息,這樣就不必每次去讀取配置信息。在運行過程中asp.net應用程序會監視配置文件的變化情況,一旦編輯了這些配置信息,就會重新讀取這些配置信息并緩存。
1、如果在當前頁面所在目錄下存在web.config文件,查看是否存在所要查找的結點名稱,如果存在返回結果并停止查找。2、如果當前頁面所在目錄下不存在web.config文件或者web.config文件中不存在該結點名,則查找它的上級目錄,直到網站的根目錄。
3、如果網站根目錄下不存在web.config文件或者web.config文件中不存在該節點名則在C:/Windows/Microsoft.NET/Framework/v4.0.30319/Config/web.config文件中查找。(這是我本機的地址,請根據情況進行調整)4、如果在C:/Windows/Microsoft.NET/Framework/v4.0.30319/Config/web.config文件中不存在相應結點,則在C:/Windows/Microsoft.NET/Framework/v4.0.30319/Config/machine.config文件中查找。5、如果仍然沒有找到則返回null。
所以如果我們對某個網站或者某個文件夾有特定要求的配置,可以在相應的文件夾下創建一個web.config文件,覆蓋掉上級文件夾中的web.config文件中的同名配置即可。這些配置信息的尋找只查找一次,以后便被緩存起來供后來的調用。在asp.net應用程序運行過程中,如果web.config文件發生更改就會導致相應的應用程序重新啟動,這時存儲在服務器內存中的用戶會話信息就會丟失(如存儲在內存中的session)。
所以如果我們對某個網站或者某個文件夾有特定要求的配置,可以在相應的文件夾下創建一個web.config文件,覆蓋掉上級文件夾中的web.config文件中的同名配置即可。這些配置信息的尋找只查找一次,以后便被緩存起來供后來的調用。在asp.net應用程序運行過程中,如果web.config文件發生更改就會導致相應的應用程序重新啟動,這時存儲在服務器內存中的用戶會話信息就會丟失(如存儲在內存中的Session)。一些軟件(如殺毒軟件)每次完成對web.config的訪問時就會修改web.config的訪問時間屬性,也會導致asp.net應用程序的重啟。
常用配置文件節點appSettings和connectionSettings說明
1、<appSettings>節點
<appSettings>節點主要用來存儲asp.net應用程序的配置信息,例如網站上傳文件的類型:
<appSettings> <!--允許上傳的圖片格式類型--> <add key="ImageType" value=".jpg;.bmp;.gif;.png;.jpeg"/> <!--允許上傳的文件類型--> <add key="FileType" value=".jpg;.bmp;.gif;.png;.jpeg;.pdf;.z對于<appSettings>節點中的值可以按照key來進行訪問,以下就是一個讀取key值為“FileType”節點值的例子:
string fileType=ConfigurationManager.AppSettings["FileType "];2、<connectionStrings>節點
<connectionStrings>節點主要用于配置數據庫連接的,我們可以<connectionStrings>節點中增加任意個節點來保存數據庫連接字符串,將來在代碼中通過代碼的方式動態獲取節點的值來實例化數據庫連接對象,這樣一旦部署的時候數據庫連接信息發生變化我們僅需要更改此處的配置即可,而不必因為數據庫連接信息的變化而需要改動程序代碼和重新部署。數據庫鏈接示例如下:
<connectionStrings> <add name="OraWord=123456;" providerName="System.Data.OracleClient"/> </connectionStrings>在代碼中我們可以這么實例化數據庫連接對象:
///1讀取web.config文件節點配置string ConnectionStringProfile = ConfigurationManager.ConnectionStrings["OraProfileConnString"].ConnectionString;///2實例化OracleConnection對象OracleConnection conn = new OracleConnection(ConnectionStringProfile);這樣做的好處是一旦開發時所用的數據庫和部署時的數據庫不一致,僅僅需要用記事本之類的文本編輯工具編輯connectionString屬性的值就行了。
自定義節點配置解析
經過查閱資料發現,有些人和我一樣,只用過我上面說的兩個節點,但是如果參數過多,這種做法的缺點也會明顯地暴露出來:appSetting中的配置參數項只能按key名來訪問,不能支持復雜的層次節點也不支持強類型, 而且由于全都只使用這一個集合,你會發現:完全不相干的參數也要放在一起!解決的方法便是使用自定義節點配置來解析。
我們來看一下如何在app.config或者web.config中增加一個自定義的配置節點。 在這篇博客中,我將介紹4種自定義配置節點的方式。
1、第一種情況——Property
配置文件如下,依照屬性的方式處理:
<?xml version="1.0" encoding="utf-8" ?><configuration> <configSections> <section name="Test1" type="Demo.Section1,Demo"/> </configSections> <Test1 UserName="aehyok" Path="www.companysz.com/aehyok"></Test1></configuration>自定義一個類,以ConfigurationSection為基類,各個屬性要加上[ConfigurationProperty] ,ConfigurationProperty的構造函數中傳入的name字符串將會用于config文件中,表示各參數的屬性名稱。
屬性的值的讀寫要調用this[],由基類去保存。
為了能使用配置節點能被解析,需要在<configSections>中注冊,代碼如上<section name="Test1" type="Demo.Section1,Demo"/>。
實現代碼如下:
namespace Demo{ public class Section1 : ConfigurationSection { [ConfigurationProperty("UserName")] public string UserName { get { return this["UserName"].ToString(); } set { this["UserName"] = value; } } [ConfigurationProperty("Path")] public string Path { get { return this["Path"].ToString(); } set { this["Path"] = value; } } }}下面將要介紹另三種配置節點雖然復雜一點,但是一些基礎的東西與這個節點是一樣的,所以后面我就不再重復說明了。
2、第二種情況——Element
配置文件如下:
<?xml version="1.0" encoding="utf-8" ?><configuration> <configSections> <section name="Test2" type="Demo.Section2,Demo"/> </configSections> <Test2> <Users UserName="aehyok" Password="123456"></Users> </Test2></configuration>實現代碼如下:
namespace Demo{ public class Section2 : ConfigurationSection { [ConfigurationProperty("Users", IsRequired = true)] public SectionElement Users { get { return (SectionElement)this["Users"]; } } public class SectionElement : ConfigurationElement { [ConfigurationProperty("UserName", IsRequired = true)] public string UserName { get { return this["UserName"].ToString(); } set { this["UserName"] = value; } } [ConfigurationProperty("Password", IsRequired = true)] public string Password { get { return this["Password"].ToString(); } set { this["Password"] = value; } } } }}第二種情況比第一種情況的區別就是,數據類型也是自己定義的,具體的配置屬性寫在ConfigurationElement的繼承類中。
3、第三種情況——CDATA
CDATA可以包含比較長的字符串,且可以包含HTML代碼段,這樣針對特殊字符的存放也比較方便。假如如下配置:
<?xml version="1.0" encoding="utf-8" ?><configuration> <configSections> <section name="Test3" type="Demo.Section3,Demo"/> </configSections> <Test3> <T1> <![CDATA[ Create proc insert_bank @param1 char(10),@param2 varchar(20),@param3 varchar(20),@param4 int,@param5 int output with encryption ---------加密 as insert bankMoney (id,userID,sex,Money) Values(@param1,@param2,@param3, @param4) select @param5=sum(Money) from bankMoney where userID='Zhangsan' go ]]> </T1> <T2> <![CDATA[ <html> <head> <title>Test</title> </head> <body> This is Test。 </body> </html> ]]> </T2> </Test3></configuration>代碼實現如下:
namespace Demo{ public class Section3 : ConfigurationSection { [ConfigurationProperty("T1", IsRequired = true)] public MyTextElement Command1 { get { return (MyTextElement)this["T1"]; } } [ConfigurationProperty("T2", IsRequired = true)] public MyTextElement Command2 { get { return (MyTextElement)this["T2"]; } } } public class MyTextElement : ConfigurationElement { protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) { CommandText = reader.ReadElementContentAs(typeof(string), null) as string; } protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) { if (writer != null) writer.WriteCDat
新聞熱點
疑難解答