配置文件的读写
System.ConfigurationManager類用于對配置文件的讀取。其具有的成員如下:
一、AppSettings
? AppSetting是最簡單的配置節,讀寫非常簡單。
| 名稱 | 說明 |
| AppSettings | 獲取當前應用程序默認配置的 AppSettingsSection 數據 |
| ConnectionStrings | 獲取當前應用程序默認配置的 ConnectionStringsSection 數據 |
?
<?xml version="1.0" encoding="utf-8" ?> <configuration><appSettings><add key="DB" value="Access" /></appSettings><connectionStrings><add name="connstr" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F:\C#Code\DBOperation\ykjj.mdb"/></connectionStrings> </configuration>示例:
class Program{static void Main(string[] args){string strAppSettings = System.Configuration.ConfigurationManager.AppSettings["DB"]; //通過屬性索引獲取值Console.WriteLine(strAppSettings);string strConnection = System.Configuration.ConfigurationManager.ConnectionStrings["connstr"].ToString();Console.WriteLine(strConnection);Console.ReadKey();}}
對于以上這一個appSettings與connectionStrings都是由ConfigurationManager提供的兩個屬性來讀取的。通常大多數的配置信息都可以放在appSettings里。但是如果你覺得不夠用了,你還可以使用自定義配置信息。
二、自定義配置節
1、自帶Handler
關于自定義配置節,Configuration提供了很多Handler類來供你選擇使用。甚至如果你覺得不夠,還可以自定義處理Handler。
先來學下使用怎么使用三個簡單的Handler:
- System.Configuration.NameValueSectionHandler
- System.Configuration.DictionarySectionHandler
- System.Configuration.SingleTagSectionHandler
配置文件代碼示例:
<?xml version="1.0" encoding="utf-8" ?> <configuration><configSections><section name="Person" type="System.Configuration.NameValueSectionHandler"/> <!--以NameValue鍵值/對的形式返回配置節中的信息--><section name="Man" type="System.Configuration.DictionarySectionHandler"/> <!--以Dictionary字典鍵值對的形式返回配置節中的信息--><section name="Name" type="System.Configuration.SingleTagSectionHandler" /> <!--基礎結構。處理 .config 文件中由單個 XML 標記所表示的各配置節。--></configSections><Person><add key="老大" value="劉備" /><add key="老二" value="關羽" /><add key="老三" value="張飛" /></Person><Man><add key="老大" value="曹操" /><add key="老二" value="典韋" /><add key="老三" value="郭嘉" /></Man><Name one="1" two="2" three="3" four="4" five="5" /> <!--注意是要單個節SingleTagSectionHandler才能處理,但是無論你索性有多少個也能處理--> </configuration>讀取代碼示例:
static void Main(string[] args) {//讀取人名NameValueCollection nvc = (NameValueCollection)ConfigurationManager.GetSection("Person");foreach (string key in nvc.AllKeys){Console.WriteLine(key + ":" + nvc[key]);}//讀取男人IDictionary dict = (IDictionary)ConfigurationManager.GetSection("Man");foreach (string key in dict.Keys){Console.WriteLine(key + ":" + dict[key]);}IDictionary dict1 = (IDictionary)ConfigurationManager.GetSection("Name");foreach (string key in dict1.Keys){Console.WriteLine(key + ":" + dict1[key]);}Console.ReadKey(); }輸出結果如下:
2、自定義Handler
自定義讀取節點需要實現接口IConfigurationSectionHandler,并提供Create的具體實現。
Appconfig代碼:
<?xml version="1.0" encoding="utf-8" ?> <configuration><configSections> <!--后面的type是處理處理節點PersonHandler所在的位置第二個參數是程序集,你可以不要Version開始之后的--><section name="Person" type="ConsoleApplication1.PersonHandler,ConsoleApplication1,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null" allowLocation="true" allowDefinition="Everywhere" /></configSections><Person age="23" name="劉備" /> </configuration>主程序代碼:
class Program{static void Main(string[] args){Hashtable config = ConfigurationManager.GetSection("Person") as Hashtable;Console.WriteLine("節點數量是:" + config.Count);//2重鍵值對的方式,其中deKey又可以再次轉化為一個Hashtableforeach (DictionaryEntry deKey in config){Console.WriteLine("屬性元素: " + deKey.Key.ToString());Hashtable attribs = (Hashtable)deKey.Value;foreach (DictionaryEntry deAttrib in attribs){Console.WriteLine(deAttrib.Key.ToString() + "=" + deAttrib.Value.ToString());}}Console.ReadKey();}}//注意必須要實現IConfigurationSectionHandler接口class PersonHandler : IConfigurationSectionHandler{public object Create(object parent, object configContext, System.Xml.XmlNode section){Hashtable myConfig = new Hashtable();// 本節元素,獲取的任何屬性。Hashtable myAttribs = new Hashtable();//遍歷當前節點的屬性foreach (XmlAttribute attrib in section.Attributes){//如果當前節點是屬性節點,則添加進入myAttribsif (XmlNodeType.Attribute == attrib.NodeType){myAttribs.Add(attrib.Name, attrib.Value);}}//把當前屬性節點集合添加進myConfig myConfig.Add(section.Name, myAttribs);return myConfig;}}輸出結果如下:
? 這樣的配置代碼看起來還是有點吃力,畢竟Hashtable的層次有兩層。
3、property屬性的方式讀取
先來看看配置文件的寫法:
<?xml version="1.0" encoding="utf-8" ?> <configuration><configSections> <!--后面的type是處理處理節點PersonSection所在的位置第二個參數是程序集,你可以不要Version開始之后的--><section name="Person" type="ConsoleApplication1.PersonSection,ConsoleApplication1,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null" allowLocation="true" allowDefinition="Everywhere" /></configSections><Person age="23" name="劉備" /> </configuration>然后程序代碼:
class Program{static void Main(string[] args){PersonSection person = ConfigurationManager.GetSection("Person") as PersonSection;Console.WriteLine("name={0},age={1}", person.Age, person.Name);Console.ReadKey();}}//注意 這里是繼承自System.Configuration.ConfigurationSection了class PersonSection : System.Configuration.ConfigurationSection{[ConfigurationProperty("age", IsRequired = false, DefaultValue = 0)]public int Age{get { return (int)base["age"]; } set { base["age"] = value; }}[ConfigurationProperty("name", IsRequired = false, DefaultValue = "")]public string Name{get { return (string)base["name"]; }set { base["name"] = value; }}}輸出結果如下:
4、配置子元素
對于稍微在復雜一點的結構,子元素的Model類要繼承自ConfigurationElement。
config文件代碼:
<?xml version="1.0" encoding="utf-8" ?> <configuration><configSections><section name="complex" type="ConsoleApplication1.ComplexSection,ConsoleApplication1"/></configSections><complex height="182"><child firstName="張" lastName="飛"/></complex> </configuration>主程序代碼:
class Program{static void Main(string[] args){ComplexSection sec = ConfigurationManager.GetSection("complex") as ComplexSection;Console.WriteLine(sec.Height); //訪問屬性Console.WriteLine(sec.Child.FirstName); //訪問子節點屬性Console.WriteLine(sec.Child.LastName); //訪問子節點屬性 Console.ReadKey();}}public class ComplexSection : ConfigurationSection{[ConfigurationProperty("height", IsRequired = true)]public int Height{get { return (int)base["height"]; }set { base["height"] = value; }}[ConfigurationProperty("child", IsDefaultCollection = false)]public ChildSection Child{get { return (ChildSection)base["child"]; }set { base["child"] = value; }}}public class ChildSection : ConfigurationElement{[ConfigurationProperty("firstName", IsRequired = true, IsKey = true)]public string FirstName{get { return (string)base["firstName"]; }set { base["firstName"] = value; }}[ConfigurationProperty("lastName", IsRequired = true)]public string LastName{get { return (string)base["lastName"]; }set { base["lastName"] = value; }}}輸出結果如圖所示:
5、配置文件中的CDATA
有時候,在配置文件里可能會包含一些比較復雜的代碼段,這時候就要用到XML的CDATA了。
<?xml version="1.0" encoding="utf-8" ?> <configuration><configSections><section name="MySection" type="ConsoleApplication1.MySection, ConsoleApplication1" /></configSections><MySection><HTML><![CDATA[<div style="#background-color:#000; font-size:24px">加粗顯示</div>]]></HTML><SQL><![CDATA[SELECT TOP 10 * FROM Person]]></SQL></MySection> </configuration>主程序代碼如下:
namespace ConsoleApplication1 {class Program{static void Main(string[] args){MySection section = ConfigurationManager.GetSection("MySection") as MySection;Console.WriteLine("{0}{1}", section.HTML.CommandText, section.SQL.CommandText);Console.ReadKey();}}//注意 這里是繼承自System.Configuration.ConfigurationSection了class MySection : System.Configuration.ConfigurationSection{[ConfigurationProperty("HTML", IsRequired = false)]public MyTextElement HTML{get { return (MyTextElement)base["HTML"]; }set { base["HTML"] = value; }}[ConfigurationProperty("SQL", IsRequired = false)]public MyTextElement SQL{get { return (MyTextElement)base["SQL"]; }set { base["SQL"] = value; }}}public class MyTextElement : ConfigurationElement{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;}[ConfigurationProperty("data", IsRequired = false)]public string CommandText{get { return this["data"].ToString(); }set { this["data"] = value; }}} }輸出如下:
6、配置元素Collection
類似下面的配置方式,在ASP.NET的HttpHandler, HttpModule中太常見了。?
<?xml version="1.0" encoding="utf-8" ?> <configuration><configSections><section name="MySection" type="ConsoleApplication1.MySection, ConsoleApplication1" /></configSections><MySection><add key="a" value="劉備"></add><add key="b" value="關羽"></add><add key="c" value="張飛"></add></MySection> </configuration>實現代碼如下:
class Program{static void Main(string[] args){MySection section = ConfigurationManager.GetSection("MySection") as MySection;foreach (MyKeyValueSetting add in section.KeyValues){Console.WriteLine(add.Key + ":" + add.Value);}Console.ReadKey();}}public class MySection : ConfigurationSection // 所有配置節點都要選擇這個基類 {private static readonly ConfigurationProperty s_property = new ConfigurationProperty(string.Empty, typeof(MyKeyValueCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);[ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)]public MyKeyValueCollection KeyValues{get{return (MyKeyValueCollection)base[s_property];}}}[ConfigurationCollection(typeof(MyKeyValueSetting))]public class MyKeyValueCollection : ConfigurationElementCollection // 自定義一個集合 {// 基本上,所有的方法都只要簡單地調用基類的實現就可以了。public MyKeyValueCollection() : base(StringComparer.OrdinalIgnoreCase) // 忽略大小寫 {}// 其實關鍵就是這個索引器。但它也是調用基類的實現,只是做下類型轉就行了。new public MyKeyValueSetting this[string name]{get { return (MyKeyValueSetting)base.BaseGet(name); }}// 下面二個方法中抽象類中必須要實現的。protected override ConfigurationElement CreateNewElement(){return new MyKeyValueSetting();}protected override object GetElementKey(ConfigurationElement element){return ((MyKeyValueSetting)element).Key;}// 說明:如果不需要在代碼中修改集合,可以不實現Add, Clear, Removepublic void Add(MyKeyValueSetting setting){this.BaseAdd(setting);}public void Clear(){base.BaseClear();}public void Remove(string name){base.BaseRemove(name);}}public class MyKeyValueSetting : 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; }}}輸出如下:
小結:
1. 為每個集合中的參數項創建一個從ConfigurationElement繼承的派生類。
2. 為集合創建一個從ConfigurationElementCollection繼承的集合類,具體在實現時主要就是調用基類的方法。
3. 在創建ConfigurationSection的繼承類時,創建一個表示集合的屬性就可以了,注意[ConfigurationProperty]的各參數。
7、配置節點的寫入
寫入配置節點的示例如下:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);PersonSection Section = config.GetSection("Person") as PersonSection;Section.Name = "撼地神牛";Section.Age = 10000;config.Save();ConfigurationManager.RefreshSection("Person"); //讓修改之后的結果生效在修改配置節點前,我們需要調用ConfigurationManager.OpenExeConfiguration(),然后調用config.GetSection()在得到節點后,轉成我們定義的節點類型, 然后就可以按照強類型的方式來修改我們定義的各參數項,最后調用config.Save();即可。
注意:
8、讀取.Net Framework中已經定義的節點
.Net Framework已定義節點的讀取很簡單:
<system.web><httpModules><add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/></httpModules></system.web>主程序如下:
public ActionResult Index(){HttpModulesSection section = ConfigurationManager.GetSection("system.web/httpModules") as HttpModulesSection;foreach (HttpModuleAction action in section.Modules){Response.Write(action.Name + "<br/>");}return Content("");}輸出如下:
注意,連服務器上mechine里面的配置都會一起讀出來。
在Web.config里是只讀的,寫不了,而非Web程序的寫與上面的例子一樣,此處不再復述。
轉載自http://www.cnblogs.com/kissdodog/archive/2013/04/11/3014227.html
轉載于:https://www.cnblogs.com/sparkleDai/p/7604903.html
總結
- 上一篇: qt setData()和data()
- 下一篇: Sublime Less 自动编译成cs