2009-01-15 45 views
10

我試圖實現通用方式從配置文件中讀取節。配置文件可能包含如下的「標準」部分或「自定義」部分。閱讀配置節的通用方法

<configuration> 
<configSections> 
    <section name="NoteSettings" type="System.Configuration.NameValueSectionHandler"/> 
</configSections> 
<appSettings> 
    <add key="AutoStart" value="true"/> 
    <add key="Font" value="Verdana"/> 
</appSettings> 
<NoteSettings> 
    <add key="Height" value="100"/> 
    <add key="Width" value="200"/> 
</NoteSettings> 

,我試過的方法如下:

private string ReadAllSections() 
    { 
     StringBuilder configSettings = new StringBuilder(); 

     Configuration configFile = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); 

     foreach (ConfigurationSection section in configFile.Sections) 
     { 
      configSettings.Append(section.SectionInformation.Name); 
      configSettings.Append(Environment.NewLine);     

      if (section.GetType() == typeof(DefaultSection)) 
      { 
       NameValueCollection sectionSettings = ConfigurationManager.GetSection(section.SectionInformation.Name) as NameValueCollection; 

       if (sectionSettings != null) 
       { 
        foreach (string key in sectionSettings) 
        { 
         configSettings.Append(key); 
         configSettings.Append(" : "); 
         configSettings.Append(sectionSettings[key]); 
         configSettings.Append(Environment.NewLine); 
        } 
       } 
      } 

      configSettings.Append(Environment.NewLine); 
     } 

     return configSettings.ToString(); 
    } 

假設所有的自定義欄目將只有鍵值

  • 是這樣的實現可能?如果是的話,有沒有比這個更清潔更優雅的解決方案?
  • 上述方法還讀取'不可見'部分,如mscorlib,system.diagnostics。這是可以避免的嗎?
  • System.Data.Dataset返回無法轉換爲NameValueCollection的數據集。這怎麼處理?

更正/建議歡迎。

謝謝。

回答

9

由於配置文件是XML文件,您可以使用XPath查詢此任務:

Configuration configFile = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location); 
    XmlDocument document = new XmlDocument(); 
    document.Load(configFile.FilePath); 
    foreach (XmlNode node in document.SelectNodes("//add")) 
    { 
     string key = node.SelectSingleNode("@key").Value; 
     string value = node.SelectSingleNode("@value").Value; 
     Console.WriteLine("{0} = {1}", key, value); 
    } 

如果你需要得到所有{鍵,值}對再您需要定義XPath查詢的三元組: 1 - 用於選擇具有相似結構的節點的主要查詢。 2,3 - 查詢從第一個查詢檢索到的節點中提取關鍵字和值節點。在你的情況下,對所有節點都有共同的查詢就足夠了,但很容易維護對不同自定義部分的支持。

2

將您的配置讀入XmlDocument,然後使用XPath查找您要查找的元素?

有點像;

XmlDocument doc = new XmlDocument(); 
doc.Load(HttpContext.Current.Server.MapPath("~/web.config")); 

XmlNodeList list = doc.SelectNodes("//configuration/appSettings"); 

foreach (XmlNode node in list[0].ChildNodes) 

...

1

當您指定NameValueSectionHandler作爲某個節的type屬性並調用Configuration.GetSection(string)時,您將收到一個DefaultSection實例作爲返回類型。

string SectionInformation.SectionInformation.GetRawXml()是在這種情況下進入您的數據的關鍵。

我用有效的方法回答了另一個類似的問題,使用System.Configuration,你可以參考獲取所有的細節和代碼片段。 NameValueSectionHandler can i use this section type for writing back to the app

2

如下您可以閱讀自定義欄目:

var sectionInformation = configuration.GetSection("mysection").SectionInformation; 
var xml = sectionInformation.GetRawXml(); 
var doc = new XmlDocument(); 
doc.LoadXml(xml); 
IConfigurationSectionHandler handler = (IConfigurationSectionHandler)Type.GetType(sectionInformation.Type).GetConstructor(new Type[0]).Invoke(new object[0]); 
var result = handler.Create(null, null, doc.DocumentElement); 
+0

這真是棒極了! – codechurn 2012-10-03 21:07:21