2013-07-15 11 views
32

obecnie mam app.config w aplikacji kopalni skonfigurować tak:Reading keyvalue par język słownika z app.config configSection

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <sectionGroup name="DeviceSettings"> 
     <section name="MajorCommands" type="System.Configuration.DictionarySectionHandler"/> 
    </sectionGroup> 
    </configSections> 
    <appSettings> 
    <add key="ComPort" value="com3"/> 
    <add key="Baud" value="9600"/> 
    <add key="Parity" value="None"/> 
    <add key="DataBits" value="8"/> 
    <add key="StopBits" value="1"/> 
    <add key="Ping" value="*IDN?"/> 
    <add key="FailOut" value="1"/> 
    </appSettings> 
    <DeviceSettings> 
    <MajorCommands> 
     <add key="Standby" value="STBY"/> 
     <add key="Operate" value="OPER"/> 
     <add key="Remote" value="REMOTE"/> 
     <add key="Local" value="LOCAL"/> 
     <add key="Reset" value="*RST" /> 
    </MajorCommands> 
    </DeviceSettings> 
</configuration> 

Mój obecny celem jest foreach lub po prostu przeczytać wszystkie wartości z MajorCommands w postaci Dictionary<string, string> sformatowanej jako Dictionary<key, value>. Próbowałem kilka różnych podejść przy użyciu System.Configuration, ale żaden nie wydaje się działać i nie byłem w stanie znaleźć żadnych szczegółów tam dokładne moje pytanie. Czy jest jakiś właściwy sposób na zrobienie tego?

+0

dla przyszłych pokoleń napotykając to pytanie jak zrobiłem - gdy działa pod mono typu części należy 'System.Configuration.DictionarySectionHandler, Systemem - część System jest kluczowa. – MattDavey

Odpowiedz

40

użyciu ConfigurationManager klasę można dostać całą sekcję z app.config pliku jako Hashtable które można konwertować do Dictionary jeśli chcesz:

var section = (ConfigurationManager.GetSection("DeviceSettings/MajorCommands") as System.Collections.Hashtable) 
       .Cast<System.Collections.DictionaryEntry>() 
       .ToDictionary(n=>n.Key.ToString(), n=>n.Value.ToString()); 

trzeba dodać odwołanie do System.Configuration montażu

+4

'.ToDictionary (n => n.Key, n => n.Value);' musi być '.ToDictionary (n => n.Key.ToString(), n => n.Value.ToString()); '. Poza tym odpowiedź działa idealnie z niewielkim dodatkiem kodu. Dziękuję Ci! – DanteTheEgregore

+0

Nie działa dla mnie w 4.5.2. Obiekt to NameValueCollection, a nie HashTable. – arviman

+1

Działa poprawnie w wersjach 4.5 i 4.6. Upewnij się, że wpis 'configSections' w Twojej aplikacji/web.config to' DictionarySectionHandler', a nie 'NameValueSectionHandler'. Ten ostatni da ci "ReadOnlyNameValueCollection" zamiast HashTable. – Nick

-1

Prawdopodobnie potraktuję plik konfiguracyjny jako plik xml.

Dictionary<string, string> myDictionary = new Dictionary<string, string>(); 
XmlDocument document = new XmlDocument(); 
document.Load("app.config"); 
XmlNodeList mejorCommands = doc.SelectNodes("/configuration/DeviceSettings/MajorCommands/add"); 

foreach (XmlNode node in majorCommands) 
{ 
    myDictionary.Add(node.Attributes["key"].Value, node.Attributes["value"].Value) 
} 

Jeśli document.Load nie działa, spróbuj przekonwertować plik konfiguracyjny na plik xml.

32

You są prawie na miejscu - po prostu zagnieździłeś swoje MajorCommands zbyt głęboko. Wystarczy zmienić go na to:

<configuration> 
    <configSections> 
    <section 
     name="MajorCommands" 
     type="System.Configuration.DictionarySectionHandler" /> 
    </configSections> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 
    <MajorCommands> 
    <add key="Standby" value="STBY"/> 
    <add key="Operate" value="OPER"/> 
    <add key="Remote" value="REMOTE"/> 
    <add key="Local" value="LOCAL"/> 
    <add key="Reset" value="*RST" />  
    </MajorCommands> 
</configuration> 

A potem dodaje będzie pracować dla Ciebie:

var section = (Hashtable)ConfigurationManager.GetSection("MajorCommands"); 
Console.WriteLine(section["Reset"]); 

Należy pamiętać, że jest to Hashtable (nie typu safe), w przeciwieństwie do słownika. Jeśli ma to być Dictionary<string,string> można przekształcić go tak:

Dictionary<string,string> dictionary = section.Cast<DictionaryEntry>().ToDictionary(d => (string)d.Key, d => (string)d.Value); 
+1

zobacz odpowiedź @ dkozl, jak to zrobić, bez usuwania zagnieżdżenia (ze ścieżką '" DeviceSettings/MajorCommands "') –

+0

tak, szukałem tego przez lata. Kiedyś rozwijałem konfiguracje za pomocą ConfigSectionDesigner, ale to kołysze .. btw, szukałem podobnych podstawowych typów dotyczących obsługi wartości konfiguracyjnych za pośrednictwem MSDN, jest tylko jedna przydatna rzecz: https://msdn.microsoft.com/en-us/library/ system.configuration.namevaluefilesectionhandler (v = vs.110) .aspx –