Как получить значения ConfigurationSection типа NameValueSectionHandler
Я работаю с С#, Framework 3.5 (VS 2008).
Я использую ConfigurationManager
для загрузки конфигурации (а не файла app.config по умолчанию) в объект конфигурации.
Используя класс Configuration, я смог получить ConfigurationSection
, но не смог найти способ получить значения этого раздела.
В конфигурации ConfigurationSection
имеет тип System.Configuration.NameValueSectionHandler
.
Для чего стоит, когда я использовал метод GetSection
для ConfigurationManager
(работает только тогда, когда он был в моем файле app.config по умолчанию), я получил тип объекта, который я мог бы передать в коллекцию пар от ключевого значения, и я просто получил значение, как словарь. Я не мог сделать такой откат, когда получил класс ConfigurationSection
из класса Configuration.
EDIT:
Пример файла конфигурации:
<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"]);
Ответы
Ответ 1
Вот хороший пост, который показывает, как это сделать.
Если вы хотите прочитать значения из файла, отличного от app.config, вам нужно загрузить его в ConfigurationManager.
Попробуйте этот метод: ConfigurationManager.OpenMappedExeConfiguration()
Вот пример того, как использовать его в статье MSDN.
Ответ 2
Страдает от точной проблемы. Проблема связана с именем 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>
затем в коде С#:
AppSettingsSection section = (AppSettingsSection)ConfigurationManager.GetSection("TEST");
btw NameValueSectionHandler больше не поддерживается в версии 2.0.
Ответ 3
Попробуйте использовать 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
Единственный способ, которым я могу заставить это работать, - это вручную создать экземпляр типа обработчика раздела, передать ему необработанный 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>();
Ответ 5
Это старый вопрос, но я использую следующий класс для выполнения задания. Он основан на блоге Скотта Дормана:
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
Вот несколько примеров из этого блога, упомянутых ранее:
<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();