Как получить значения ConfigurationSection типа NameValueSectionHandler

Я работаю с C #, Framework 3.5 (VS 2008).

Я использую ConfigurationManager для загрузки конфигурации (а не файла app.config по умолчанию) в объект конфигурации.

Используя класс Configuration, я смог получить ConfigurationSection, но не смог найти способ получить значения этого раздела.

В конфигурации ConfigurationSection имеет тип System.Configuration.NameValueSectionHandler.

Как бы то ни было, когда я использовал метод GetSection из ConfigurationManager (работает только тогда, когда он был в моем файле app.config по умолчанию), я получил тип объекта, который я мог преобразовать в коллекцию пар ключ-значение, и я только что получил значение как Словарь. Однако я не смог выполнить такое приведение, когда получил класс ConfigurationSection из класса конфигурации.

РЕДАКТИРОВАТЬ: Пример файла конфигурации:

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

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

Пример того, как я смог его использовать, когда он был в app.config (метод GetSection предназначен только для app.config по умолчанию):

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

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

person Liran B    schedule 11.08.2010    source источник
comment
Если вы будете использовать .Net версии 4.0, тогда вам может помочь динамический   -  person Rahul    schedule 03.09.2014


Ответы (7)


Пострадал от точного выпуска. Проблема возникла из-за NameValueSectionHandler в файле .config. Вместо этого вы должны использовать 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");

Кстати, NameValueSectionHandler больше не поддерживается в 2.0.

person nerijus    schedule 04.03.2013
comment
Приведение в раздел AppSettings у меня не сработало. Вместо этого я использовал NameValueCollection и работал. - person Jone Polvora; 28.09.2014
comment
У меня были небольшие проблемы с тем, чтобы мой раздел заработал (некоторые ошибки при загрузке самого файла конфигурации), но после этого это решение сработало отлично. Теперь я могу разделить свой файл конфигурации на несколько разделов и легко получить доступ к значениям через AppSettingsSection. - person Onsokumaru; 04.02.2019

Вот хороший пост, в котором показано, как это сделать.

Если вы хотите прочитать значения из файла, отличного от app.config, вам необходимо загрузить его в ConfigurationManager.

Попробуйте этот метод: ConfigurationManager.OpenMappedExeConfiguration ()

В статье MSDN есть пример того, как его использовать.

person MonkeyWrench    schedule 11.08.2010
comment
Как я сказал в своем посте, это то, что я сделал. Я получил класс Configuraion, а от него - ConfigurationSection. Мой вопрос заключался в том, как я могу получить значения из этого объекта ConfigurationSection? Я не спрашивал, как получить объект конфигурации .. В любом случае спасибо! - person Liran B; 12.08.2010
comment
кстати, в примере, который вы мне дали, они не используют класс Configuration, который поступает из OpenMappedExeConfiguration, но они используют app.config по умолчанию (который можно использовать с помощью методов .GetSection / .GetConfig, но, как я сказал в мой пост - я это уже сделал. но для меня это бесполезно, так как оно годится только для app.config). а для msdn я не нашел там ответа на свой вопрос .. - person Liran B; 12.08.2010
comment
Хорошо, чем больше я вглядываюсь в это, тем больше вижу, что сделать это непросто. Основная проблема заключается в том, что вы пытаетесь смешать код стиля конфигурации .Net 1.1 и 2.0. Прочтите это, это укажет вам правильное направление: eggheadcafe.com/software/aspnet/30832856/ - person MonkeyWrench; 12.08.2010
comment
@MonkeyWrench Страница больше не доступна. - person Hari; 06.11.2014
comment
Похоже, что bluefeet исправил это. Спасибо. - person MonkeyWrench; 03.02.2015
comment
Ой ... почему голос против? Я не могу починить интернет. Ссылке 5 лет. Хороший пример есть и в MSDN. - person MonkeyWrench; 24.02.2015
comment
Этот ответ, похоже, страдает от гниения ссылок, поэтому только ссылки не приветствуются. - person Liam; 22.07.2015
comment
Отличный пост в блоге. Спасибо, что поделился. - person RayLoveless; 28.09.2016
comment
Голос против: это хороший ответ в целом по теме конфигурации для новичка / стандартного варианта использования, но бесполезный ответ для конкретной проблемы исходного вопроса. Я столкнулся с той же проблемой, что и Лиран Б., и этот блог мне совершенно не помогает. Вопрос в том, как поступить с ConfigurationSection-объектом. - person Onsokumaru; 04.02.2019

Попробуйте использовать 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/.

person Steven Ball    schedule 17.01.2013
comment
нет, таким образом вы получите Unable to cast object of type 'System.Configuration.DefaultSection' to type 'System.Configuration.AppSettingsSection'. - person nerijus; 04.03.2013
comment
@nerijus: давай, чувак ... Конечно, одно из предположений Стивена состоит в том, что ты действительно соответствующим образом меняешь тип раздела ... Без обид, но ты действительно можешь подумать, прежде чем комментировать. Я попробовал это решение, и оно работает. +1 для Стивена - person h9uest; 03.04.2013
comment
@ h9uest: Это не так просто, как написала Лиран, раздел System.Configuration.NameValueSectionHandler. Этот ответ больше похож на грязный взлом. - person Peter Ivan; 03.10.2013

Единственный способ заставить это работать - вручную создать экземпляр типа обработчика раздела, передать ему необработанный 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>();
person Steven Padfield    schedule 20.03.2014
comment
Так приятно видеть, что кто-то отвечает на заданный вопрос. Я копался в куче ответов на вопросы об обработке OpenExeConfiguration GetSection с ответами, которые перенаправляют людей на ConfigurationManager.GetSection, что не то же самое. - person Joseph; 15.05.2018
comment
У вас должна быть возможность просто вызвать метод Get: var myParamsCollection = myParamsSection.Get ‹NameValueCollection› (); - person nivs1978; 28.05.2020


Вот несколько примеров из этот блог, упомянутый ранее:

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

получить значение:

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

labelImport2.Text = loc["ImportDirectory"].ToString();
labelProcessed2.Text = loc["ProcessedDirectory"].ToString();
person RayLoveless    schedule 28.09.2016

Попробуй это;

Кредит: 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;
person Sedat Kumcu    schedule 19.12.2019