2010-05-12 26 views
34

Tôi đang cố gắng sử dụng ConfigurationManager.AppSettings.GetValues() để truy xuất nhiều giá trị cấu hình cho một khóa, nhưng tôi luôn nhận được một mảng giá trị cuối cùng. appsettings.config của tôi trông giống nhưNhiều giá trị cho một khóa cấu hình đơn

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

và tôi đang cố gắng truy cập với

ConfigurationManager.AppSettings.GetValues("mykey"); 

nhưng tôi chỉ nhận được { "C" }.

Bất kỳ ý tưởng nào về cách giải quyết vấn đề này?

Trả lời

37

Hãy thử

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

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

Vì vậy, các điểm của 'ConfigurationManager.AppSettings.GetValues ​​(là những gì) 'sau đó? – Yuck

+0

@Yuck một câu hỏi về điểm của lớp NameValueCollection cơ bản - hỗ trợ nhiều giá trị cho mỗi khóa, nhưng không thực sự cho phép bạn đặt nhiều giá trị cho mỗi khóa (AppSettings phải sử dụng bộ chỉ mục) - đây là nguyên nhân thực sự của vấn đề, thay vì GetValues ​​() chỉ trả về một giá trị duy nhất. – fusi

+0

Nếu chỉ có một giá trị duy nhất, bất kỳ lỗi nào không tìm thấy ký tự xảy ra? –

6

Điều bạn muốn làm là không thể. Bạn phải đặt tên cho mỗi khóa khác nhau, hoặc làm một cái gì đó như value = "A, B, C" và tách ra các giá trị khác nhau trong mã string values = value.split(',').

Nó sẽ luôn luôn nhận giá trị của khóa được xác định lần cuối (trong ví dụ C).

9

Các tập tin cấu hình xử lý từng dòng như một bài tập, đó là lý do tại sao bạn chỉ nhìn thấy những dòng cuối cùng. Khi nó đọc cấu hình, nó gán khóa của bạn giá trị của "A", sau đó "B", sau đó "C", và vì "C" là giá trị cuối cùng, nó là một trong đó gậy.

như @Kevin đề xuất, cách tốt nhất để làm điều này có lẽ là giá trị có nội dung là CSV mà bạn có thể phân tích cú pháp.

2

Kể từ khi phương pháp ConfigurationManager.AppSettings.GetValues() không làm việc, tôi đã sử dụng các workaround sau đây để có được một hiệu ứng tương tự, nhưng với sự cần thiết phải hậu tố các phím với các chỉ mục duy nhất.

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

Điều này sẽ khớp với các phím như myKey[0]myKey[1].

+0

ConfigurationManager.ConnectionStrings cung cấp cho bạn khả năng lặp qua danh sách phủ nhận bất kỳ và tất cả các câu trả lời cho câu hỏi này (Tôi biết nó không phải là chuỗi kết nối cho mỗi câu nói, nhưng bạn có thể sử dụng nó như vậy) – user3036342

9

Tôi biết mình đã trễ nhưng tôi đã tìm thấy giải pháp này và nó hoạt động hoàn hảo vì vậy tôi chỉ muốn chia sẻ.

Đó là tất cả về việc xác định của riêng 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"]; } 
     } 
    } 
} 

Và trong app.config chỉ cần sử dụng phần mới của bạn:

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

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

và khi lấy dữ liệu chỉ như thế này:

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

Cuối cùng, nhờ tác giả của bản gốc post

0

Đây là giải pháp đầy đủ: mã trong 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; 
      } 
     } 

    } 
} 

Và trong cấu hình web

<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

Cảm ơn CubeJockey for reallignment. –

0

Đưa tôi về trả lời của JJS: Config file:

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

Mã để lấy thành string []

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, đơn giản như vậy s nó sẽ nhận được. Cảm thấy tự do để chứng minh tôi sai :)

0

tôi sử dụng quy ước đặt tên trong những chìa khóa và nó hoạt động như một nét duyên dáng

<?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 
    } 
} 
Các vấn đề liên quan