Ответ 1
Try
<add key="mykey" value="A,B,C"/>
И
string[] mykey = ConfigurationManager.AppSettings["mykey"].Split(',');
Я пытаюсь использовать ConfigurationManager.AppSettings.GetValues()
для получения нескольких значений конфигурации для одного ключа, но я всегда получаю массив только из последнего значения. Мой appsettings.config
выглядит как
<add key="mykey" value="A"/>
<add key="mykey" value="B"/>
<add key="mykey" value="C"/>
и я пытаюсь получить доступ с помощью
ConfigurationManager.AppSettings.GetValues("mykey");
но я получаю только { "C" }
.
Любые идеи о том, как это решить?
Try
<add key="mykey" value="A,B,C"/>
И
string[] mykey = ConfigurationManager.AppSettings["mykey"].Split(',');
Конфигурационный файл обрабатывает каждую строку как назначение, поэтому вы видите только последнюю строку. Когда он читает конфигурацию, он назначает вашему ключу значение "A", затем "B", затем "C", а так как "C" - это последнее значение, то оно придерживается.
как предлагает @Kevin, лучший способ сделать это - это, вероятно, значение, содержимое которого представляет собой CSV, который можно разобрать отдельно.
Я знаю, что опаздываю, но я нашел это решение, и он отлично работает, поэтому я просто хочу поделиться.
Все о определении вашего собственного ConfigurationElement
namespace Configuration.Helpers
{
public class ValueElement : ConfigurationElement
{
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
{
get { return (string) this["name"]; }
}
}
public class ValueElementCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new ValueElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ValueElement)element).Name;
}
}
public class MultipleValuesSection : ConfigurationSection
{
[ConfigurationProperty("Values")]
public ValueElementCollection Values
{
get { return (ValueElementCollection)this["Values"]; }
}
}
}
И в app.config просто используйте свой новый раздел:
<configSections>
<section name="PreRequest" type="Configuration.Helpers.MultipleValuesSection,
Configuration.Helpers" requirePermission="false" />
</configSections>
<PreRequest>
<Values>
<add name="C++"/>
<add name="Some Application"/>
</Values>
</PreRequest>
и при получении данных так:
var section = (MultipleValuesSection) ConfigurationManager.GetSection("PreRequest");
var applications = (from object value in section.Values
select ((ValueElement)value).Name)
.ToList();
Наконец, благодаря автору оригинала post
То, что вы хотите сделать, невозможно. Вы либо должны называть каждый ключ по-разному, либо делать что-то вроде значения = "A, B, C" и выделять разные значения в коде string values = value.split(',')
.
Он всегда будет выбирать значение последнего ключа (в вашем примере C).
Я думаю, вы можете использовать разделы Custom Config http://www.4guysfromrolla.com/articles/032807-1.aspx
Так как метод ConfigurationManager.AppSettings.GetValues()
не работает, я использовал следующее обходное решение, чтобы получить аналогичный эффект, но с необходимостью суффикс ключей с уникальными индексами.
var name = "myKey";
var uniqueKeys = ConfigurationManager.AppSettings.Keys.OfType<string>().Where(
key => key.StartsWith(name + '[', StringComparison.InvariantCultureIgnoreCase)
);
var values = uniqueKeys.Select(key => ConfigurationManager.AppSettings[key]);
Это будет соответствовать таким клавишам, как myKey[0]
и myKey[1]
.
Вот полное решение: код в aspx.cs
namespace HelloWorld
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
UrlRetrieverSection UrlAddresses = (UrlRetrieverSection)ConfigurationManager.GetSection("urlAddresses");
}
}
public class UrlRetrieverSection : ConfigurationSection
{
[ConfigurationProperty("", IsDefaultCollection = true,IsRequired =true)]
public UrlCollection UrlAddresses
{
get
{
return (UrlCollection)this[""];
}
set
{
this[""] = value;
}
}
}
public class UrlCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new UrlElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((UrlElement)element).Name;
}
}
public class UrlElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("url", IsRequired = true)]
public string Url
{
get
{
return (string)this["url"];
}
set
{
this["url"] = value;
}
}
}
}
И в веб-конфигурации
<configSections>
<section name="urlAddresses" type="HelloWorld.UrlRetrieverSection" />
</configSections>
<urlAddresses>
<add name="Google" url="http://www.google.com" />
<add name="Yahoo" url="http://www.yahoo.com" />
<add name="Hotmail" url="http://www.hotmail.com/" />
</urlAddresses>
Мой ответ на JJS: Файл конфигурации:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="List1" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<section name="List2" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<List1>
<add key="p-Teapot" />
<add key="p-drongo" />
<add key="p-heyho" />
<add key="p-bob" />
<add key="p-Black Adder" />
</List1>
<List2>
<add key="s-Teapot" />
<add key="s-drongo" />
<add key="s-heyho" />
<add key="s-bob"/>
<add key="s-Black Adder" />
</List2>
</configuration>
Код для извлечения в строку []
private void button1_Click(object sender, EventArgs e)
{
string[] output = CollectFromConfig("List1");
foreach (string key in output) label1.Text += key + Environment.NewLine;
label1.Text += Environment.NewLine;
output = CollectFromConfig("List2");
foreach (string key in output) label1.Text += key + Environment.NewLine;
}
private string[] CollectFromConfig(string key)
{
NameValueCollection keyCollection = (NameValueCollection)ConfigurationManager.GetSection(key);
return keyCollection.AllKeys;
}
ИМО, что так просто, как это получится. Не стесняйтесь доказывать, что я ошибаюсь:)
Я использую соглашение об именах ключей и работает как шарм
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="section1" type="System.Configuration.NameValueSectionHandler"/>
</configSections>
<section1>
<add key="keyname1" value="value1"/>
<add key="keyname21" value="value21"/>
<add key="keyname22" value="value22"/>
</section1>
</configuration>
var section1 = ConfigurationManager.GetSection("section1") as NameValueCollection;
for (int i = 0; i < section1.AllKeys.Length; i++)
{
//if you define the key is unique then use == operator
if (section1.AllKeys[i] == "keyName1")
{
// process keyName1
}
// if you define the key as a list, starting with the same name, then use string StartWith function
if (section1.AllKeys[i].Startwith("keyName2"))
{
// AllKeys start with keyName2 will be processed here
}
}