Cum se obțin valorile unei ConfigurationSection de tip NameValueSectionHandler (Programare, C#, Config, Configurationmanager, Secțiune De Configurare)

Liran B a intrebat.

Lucrez cu C#, Framework 3.5 (VS 2008).

Folosesc ConfigurationManager pentru a încărca o configurație (nu fișierul implicit app.config) într-un obiect Configuration.

Utilizând clasa Configuration, am reușit să obțin un fișier ConfigurationSection, , dar nu am putut găsi o modalitate de a obține valorile din acea secțiune.

În config, secțiunea ConfigurationSection este de tip System.Configuration.NameValueSectionHandler.

Dacă are vreo valoare, când am folosit metoda GetSection din ConfigurationManager (funcționează numai când a fost în fișierul meu app.config implicit), am primit un tip de obiect, pe care l-am putut transforma într-o colecție de perechi de valori-cheie, și am primit valoarea ca un dicționar. Nu am putut face o astfel de distribuție atunci când am primit ConfigurationSection clasa din clasa Configuration.

EDIT:Exemplu de fișier de configurare:

<configuration>
  <configSections>
    <section name="MyParams" 
             type="System.Configuration.NameValueSectionHandler" />
  </configSections>

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

Exemplu al modului în care am putut să îl folosesc atunci când a fost pe app.config (metoda „GetSection” este doar pentru app.config implicit):

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

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

Comentarii

  • Dacă ați utiliza versiunea .Net 4.0, atunci dynamic ar putea fi de ajutor –  > Por Rahul.
7 răspunsuri
nerijus

Suferit de o problemă exactă. Problema a fost din cauza NameValueSectionHandler în fișierul .config. Ar trebui să folosiți AppSettingsSection în schimb:

<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>

apoi în codul C#:

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

btw NameValueSectionHandler nu mai este suportat în 2.0.

Comentarii

  • Casting to AppSettings section nu a funcționat pentru mine. În schimb, am făcut castarea la NameValueCollection și a funcționat. –  > Por Jone Polvora.
  • Am avut ceva probleme să fac să funcționeze secțiunea mea (câteva greșeli la încărcarea fișierului de configurare în sine), dar după aceea această soluție a funcționat perfect. Acum pot împărți fișierul meu de configurare în mai multe secțiuni și pot accesa cu ușurință valorile prin intermediul AppSettingsSection. –  > Por Onsokumaru.
MonkeyWrench

Iată o postare bună care arată cum se face acest lucru.

Dacă doriți să citiți valorile dintr-un alt fișier decât app.config, trebuie să îl încărcați în ConfigurationManager.

Încercați această metodă: ConfigurationManager.OpenMappedExeConfiguration()

Există un exemplu de utilizare a acesteia în articolul MSDN.

Comentarii

  • După cum am spus în postarea mea, iată ce am făcut. Am primit clasa Configuraion, iar din ea am primit o ConfigurationSection. Întrebarea mea era cum pot obține valorile din acel obiect ConfigurationSection? Nu am întrebat cum să obțin obiectul Configuration… Mulțumesc oricum! –  > Por Liran B.
  • apropo, în exemplul pe care mi l-ai dat nu se folosește clasa Configuration care provine din OpenMappedExeConfiguration, ci se folosește implicit app.config (care poate fi folosit folosind metodele .GetSection/.GetConfig, dar așa cum am spus în postarea mea am făcut deja asta. dar nu este bun pentru mine, deoarece este bun doar pentru app.config). și pentru msdn, nu am putut găsi răspunsul la întrebarea mea acolo.. –  > Por Liran B.
  • Ok, cu cât mă interesez mai mult, cu atât mai mult văd că nu este ușor de făcut. Problema de bază este că încerci să amesteci codul de tip configurare .Net 1.1 cu cel 2.0. Citește asta, te va îndruma în direcția corectă: eggheadcafe.com/software/aspnet/30832856/… –  > Por MonkeyWrench.
  • @MonkeyWrench Pagina nu mai este disponibilă. –  > Por Hari.
  • Acest răspuns pare să sufere de putrezirea linkurilor, de aceea sunt descurajate răspunsurile numai cu linkuri. –  > Por Liam.
Steven Ball

Încercați să folosiți un AppSettingsSection în loc de un NameValueCollection. Ceva de genul acesta:

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

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

Comentarii

  • nu, în acest fel veți obține „Unable to cast object of type ‘System.Configuration.DefaultSection’ to type ‘System.Configuration.AppSettingsSection’.” –  > Por nerijus.
  • @nerijus : haide omule … Desigur, una dintre presupunerile lui Steven este că, de fapt, schimbi tipul secțiunii în mod corespunzător … Fără supărare, dar chiar ai putea să te gândești înainte de a comenta. Am încercat această soluție și funcționează. +1 pentru Steven –  > Por h9uest.
  • @h9uest: Nu este atât de simplu, așa cum a scris Liran secțiunea este System.Configuration.NameValueSectionHandler. Acest răspuns pare mai degrabă un fel de hack murdar. –  > Por Peter Ivan.
Steven Padfield

Singurul mod în care pot face ca acest lucru să funcționeze este să instanțiez manual tipul de gestionar de secțiune, să îi transmit XML-ul brut și să transform obiectul rezultat.

Pare destul de ineficient, dar asta e.

Am scris o metodă de extensie pentru a încapsula acest lucru:

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);
    }
}

Modul în care ați apela-o în exemplul dvs. este:

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>();

Comentarii

  • Este atât de plăcut să vezi că cineva răspunde la întrebarea pusă. Am răsfoit o grămadă de răspunsuri la întrebări despre manipularea OpenExeConfiguration GetSection cu „răspunsuri” care redirecționează oamenii către ConfigurationManager.GetSection, care nu face același lucru. –  > Por Joseph.
  • Ar trebui să puteți apela doar metoda Get: var myParamsCollection = myParamsSection.Get<NameValueCollection>(); –  > Por nivs1978.
Peter Ivan

Aceasta este o întrebare veche, dar eu folosesc următoarea clasă pentru a face treaba. Aceasta se bazează pe Blogul lui Scott Dorman:

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];
        }
    }

Utilizarea este simplă:

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

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

RayLoveless

Iată câteva exemple din acest blog menționate anterior:

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

obțineți valori:

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

Un alt exemplu:

<Locations 
   ImportDirectory="C:ImportInbox"
   ProcessedDirectory ="C:ImportProcessed"
   RejectedDirectory ="C:ImportRejected"
/>

get value:

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

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

Sedat Kumcu

Încercați acest lucru;

Credit: https://www.limilabs.com/blog/read-system-net-mailsettings-smtp-settings-web-config

SmtpSection section = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");

string from = section.From;
string host = section.Network.Host;
int port = section.Network.Port;
bool enableSsl = section.Network.EnableSsl;
string user = section.Network.UserName;
string password = section.Network.Password;