2010-08-11 31 views
50

我用C#,框架3.5(VS 2008)的工作。如何獲得類型的配置節的值NameValueSectionHandler

我使用的是ConfigurationManager加載配置(不是默認app.config文件)爲配置對象。

使用配置類,我能得到一個ConfigurationSection,但我不能找到一個辦法讓該段的值。

在配置中,ConfigurationSectionSystem.Configuration.NameValueSectionHandler類型。

對於它的價值,當我使用ConfigurationManager的方法GetSection(僅適用於我的默認app.config文件時),我收到了一個對象類型,價值,而我剛收到像Dictionary這樣的價值。但是,當我從配置類中收到ConfigurationSection類時,我無法做這樣的演員。

編輯:配置文件的實施例 :

的方式我能夠使用它時,它是上的app.config
<configuration> 
    <configSections> 
    <section name="MyParams" 
      type="System.Configuration.NameValueSectionHandler" /> 
    </configSections> 

    <MyParams> 
    <add key="FirstParam" value="One"/> 
    <add key="SecondParam" value="Two"/> 
    </MyParams> 
</configuration> 

實施例(以下簡稱「GetSection」方法是默認的app.config ):

NameValueCollection myParamsCollection = 
      (NameValueCollection)ConfigurationManager.GetSection("MyParams"); 

Console.WriteLine(myParamsCollection["FirstParam"]); 
Console.WriteLine(myParamsCollection["SecondParam"]); 
+0

你有沒有得到很好的解決了這一點? – 2014-06-24 04:11:52

+0

如果你將使用.Net版本4.0,那麼動態可以幫助 – Rahul 2014-09-03 07:06:25

回答

20

Here's一個很好的帖子,說明如何做到這一點。

如果要從app.config以外的文件中讀取值,則需要將其加載到ConfigurationManager中。

試試這個方法:ConfigurationManager.OpenMappedExeConfiguration()

有怎樣的MSDN文章中使用它的一個例子。

+4

正如我在我的帖子中所說,這就是我所做的。 我收到Configuraion類,並從中收到ConfigurationSection。 我的問題是我怎樣才能得到該ConfigurationSection對象的值?我沒有問如何獲得配置對象.. 無論如何,謝謝! – 2010-08-11 20:32:50

+2

順便說一句,在你給我的例子中,他們沒有使用來自OpenMappedExeConfiguration的Configuration類,但他們使用的是默認的app.config(可以使用.GetSection/.GetConfig方法使用,但正如我所說在我的文章中 - 我已經這樣做了,但它對我沒有好處,因爲它僅適用於app.config)。 和msdn,我無法找到我的問題在那裏的答案.. – 2010-08-11 20:35:43

+0

好吧,我越看越,我越看越不容易做。基本的問題是,你正在嘗試混合使用.Net 1.1配置風格代碼和2.0。閱讀本文,它會指出您正確的方向:http://www.eggheadcafe.com/software/aspnet/30832856/backwards-compatibility-of-systemconfigurationconfiguration.aspx – MonkeyWrench 2010-08-12 13:37:16

10

嘗試使用AppSettingsSection而不是NameValueCollection。事情是這樣的:

var section = (AppSettingsSection)config.GetSection(sectionName); 
string results = section.Settings[key].Value; 

來源: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/d5079420-40cb-4255-9b3b-f9a41a1f7ad2/

+4

nope這樣你會得到「無法將類型爲」System.Configuration.DefaultSection「的對象轉換爲鍵入」System.Configuration.AppSettingsSection「。」 – nerijus 2013-03-04 14:23:57

+3

@nerijus:來吧......當然,Steven的假設之一就是你實際上改變了這個部分的類型......沒有冒犯性,但你在評論之前真的可以考慮。我試過這個解決方案,它工作。 +1對於Steven – h9uest 2013-04-03 14:58:59

+1

@ h9uest:它不那麼直截了當,因爲Liran寫的部分是'System.Configuration.NameValueSectionHandler'。這個答案看起來更像是一種骯髒的黑客。 – 2013-10-03 08:17:51

15

從具體問題受到影響。問題是由於.config文件中的NameValueSectionHandler。您應該使用AppSettingsSection代替:

<configuration> 

<configSections> 
    <section name="DEV" type="System.Configuration.AppSettingsSection" /> 
    <section name="TEST" type="System.Configuration.AppSettingsSection" /> 
</configSections> 

<TEST> 
    <add key="key" value="value1" /> 
</TEST> 

<DEV> 
    <add key="key" value="value2" /> 
</DEV> 

</configuration> 

然後在C#代碼:

AppSettingsSection section = (AppSettingsSection)ConfigurationManager.GetSection("TEST"); 

BTW NameValueSectionHandler不支持2.0更多。

+4

投射到AppSettings部分沒有爲我工作。相反,我鑄造了NameValueCollection並且工作。 – 2014-09-28 07:10:45

+0

@JonePolvora我也是。 – 2017-06-08 15:01:08

1

這是一個老問題,但我使用以下課程來完成這項工作。它是基於Scott Dorman's blog

public class NameValueCollectionConfigurationSection : ConfigurationSection 
{ 
    private const string COLLECTION_PROP_NAME = ""; 

    public IEnumerable<KeyValuePair<string, string>> GetNameValueItems() 
    { 
     foreach (string key in this.ConfigurationCollection.AllKeys) 
     { 
      NameValueConfigurationElement confElement = this.ConfigurationCollection[key]; 
      yield return new KeyValuePair<string, string> 
       (confElement.Name, confElement.Value); 
     } 
    } 

    [ConfigurationProperty(COLLECTION_PROP_NAME, IsDefaultCollection = true)] 
    protected NameValueConfigurationCollection ConfCollection 
    { 
     get 
     { 
      return (NameValueConfigurationCollection) base[COLLECTION_PROP_NAME]; 
     } 
    } 

的用法很簡單:

Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
NameValueCollectionConfigurationSection config = 
    (NameValueCollectionConfigurationSection) configuration.GetSection("MyParams"); 

NameValueCollection myParamsCollection = new NameValueCollection(); 
config.GetNameValueItems().ToList().ForEach(kvp => myParamsCollection.Add(kvp)); 
6

我能得到這個工作的唯一方法是手動實例化區段處理器類型,原始的XML傳遞給它,投射結果物體。

看起來效率很低,但你去了。

我寫了一個擴展方法來封裝此:

public static class ConfigurationSectionExtensions 
{ 
    public static T GetAs<T>(this ConfigurationSection section) 
    { 
     var sectionInformation = section.SectionInformation; 

     var sectionHandlerType = Type.GetType(sectionInformation.Type); 
     if (sectionHandlerType == null) 
     { 
      throw new InvalidOperationException(string.Format("Unable to find section handler type '{0}'.", sectionInformation.Type)); 
     } 

     IConfigurationSectionHandler sectionHandler; 
     try 
     { 
      sectionHandler = (IConfigurationSectionHandler)Activator.CreateInstance(sectionHandlerType); 
     } 
     catch (InvalidCastException ex) 
     { 
      throw new InvalidOperationException(string.Format("Section handler type '{0}' does not implement IConfigurationSectionHandler.", sectionInformation.Type), ex); 
     } 

     var rawXml = sectionInformation.GetRawXml(); 
     if (rawXml == null) 
     { 
      return default(T); 
     } 

     var xmlDocument = new XmlDocument(); 
     xmlDocument.LoadXml(rawXml); 

     return (T)sectionHandler.Create(null, null, xmlDocument.DocumentElement); 
    } 
} 

你會調用它在你的榜樣的方式是:

var map = new ExeConfigurationFileMap 
{ 
    ExeConfigFilename = @"c:\\foo.config" 
}; 
var configuration = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); 
var myParamsSection = configuration.GetSection("MyParams"); 
var myParamsCollection = myParamsSection.GetAs<NameValueCollection>(); 
0

下面是前面提到的從this blog一些例子:

<configuration>  
    <Database>  
     <add key="ConnectionString" value="data source=.;initial catalog=NorthWind;integrated security=SSPI"/>  
    </Database>  
</configuration> 

得到的值:

NameValueCollection db = (NameValueCollection)ConfigurationSettings.GetConfig("Database");   
    labelConnection2.Text = db["ConnectionString"]; 

-

又如:

<Locations 
    ImportDirectory="C:\Import\Inbox" 
    ProcessedDirectory ="C:\Import\Processed" 
    RejectedDirectory ="C:\Import\Rejected" 
/> 

GET值:

Hashtable loc = (Hashtable)ConfigurationSettings.GetConfig("Locations"); 

labelImport2.Text = loc["ImportDirectory"].ToString(); 
labelProcessed2.Text = loc["ProcessedDirectory"].ToString();