2010-05-12 4 views
34

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" }을 얻고있다.

해결 방법에 대한 아이디어가 있으십니까?

답변

37

<add key="mykey" value="A,B,C"/> 

그리고

string[] mykey = ConfigurationManager.AppSettings["mykey"].Split(','); 
+13

그래서 ConfigurationManager.AppSettings.GetValues'의 포인트 (무엇)'그럼? – Yuck

+0

@Yuck은 기본 NameValueCollection 클래스의 포인트에 질문합니다.이 클래스는 키당 여러 값을 지원하지만 실제로 키당 하나 이상을 설정할 수는 없습니다 (AppSettings는 내부적으로 set 인덱서를 사용해야합니다). 이것이 바로 문제가 아니라 단일 값을 반환하는 GetValues ​​(). – fusi

+0

단일 값만있는 경우 문자를 찾을 수 없음 오류가 발생합니까? –

6

원하는 작업을 수행 할 수 없습니다. 다르게 각 키의 이름을 지정하거나 value = "A, B, C"와 같은 것을하고 코드 string values = value.split(',')의 다른 값을 분리해야합니다.

마지막으로 정의 된 키 값 (예 C)이 항상 선택됩니다.

9

설정 파일 취급 만 마지막 줄을보고있는 이유는 할당과 같은 각 라인을 사용해보십시오. 구성을 읽으면 키에 "A", "B", "C"의 값이 지정되고 "C"는 마지막 값이므로 막대기가됩니다.

@Kevin이 제시 한대로, 가장 좋은 방법은 아마도 내용을 CSV로 파싱 할 수있는 가치 일 것입니다.

2

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] 같은 키와 일치합니다.

+0

ConfigurationManager.ConnectionStrings는이 질문에 대한 모든 답을 무효화하는 목록을 반복 할 수있는 기능을 제공합니다 (말하면 연결 문자열이 아니지만 그대로 사용할 수 있음) – user3036342

9

나는 늦었지만이 해결책을 발견하고 완벽하게 작동하기 때문에 나는 단지 공유하고 싶다.

그것의 모든 정의에 대한 당신의 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 그냥 새로운 섹션 사용에 자신의 :

var section = (MultipleValuesSection) ConfigurationManager.GetSection("PreRequest"); 
var applications = (from object value in section.Values 
        select ((ValueElement)value).Name) 
        .ToList(); 
:

<configSections> 
    <section name="PreRequest" type="Configuration.Helpers.MultipleValuesSection, 
    Configuration.Helpers" requirePermission="false" /> 
</configSections> 

<PreRequest> 
    <Values> 
     <add name="C++"/> 
     <add name="Some Application"/> 
    </Values> 
</PreRequest> 

을 그냥 같은 데이터를 검색 할 때

마침내 원래의 작성자 덕분에 post

0

여기 풀 솔루션 : 코드는 aspx입니다.

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

    } 
} 

그리고 웹 설정에서 CS

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

재 할당을위한 CubeJockey에게 감사드립니다. –

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

으로 검색 IMO, 그건 간단합니다. 그것은 얻을 것이다. : 잘못된 내가 키의 이름 지정 규칙을 사용하십시오

0

날을 증명 자유롭게하고 그것이 마치 마법처럼 작동

<?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 
    } 
} 
관련 문제