代码之家  ›  专栏  ›  技术社区  ›  Daniel Schierbeck

单个配置键的多个值

  •  39
  • Daniel Schierbeck  · 技术社区  · 14 年前

    我想用 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" } .

    有什么解决办法吗?

    9 回复  |  直到 6 年前
        1
  •  41
  •   Joel    14 年前

    尝试

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

    string[] mykey = ConfigurationManager.AppSettings["mykey"].Split(',');
    
        2
  •  11
  •   SqlRyan    14 年前

    配置文件将每一行视为一个分配,这就是为什么您只看到最后一行的原因。当它读取配置时,它会给你的键分配值“A”,然后是“B”,然后是“C”,因为“C”是最后一个值,所以它是坚持的值。

    正如@kevin建议的那样,最好的方法可能是一个值,它的内容是一个csv,您可以对其进行解析。

        3
  •  9
  •   Wahid Bitar    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中,只需使用新的部分:

    <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

        4
  •  6
  •   kemiller2002    14 年前

    你想做的是不可能的。您要么对每个键进行不同的命名,要么执行value=“a,b,c”之类的操作,并在代码中分离出不同的值。 string values = value.split(',') .

    它将始终获取上次定义的键的值(在示例C中)。

        5
  •  3
  •   LCJ    12 年前

    我认为,您可以使用自定义配置部分 http://www.4guysfromrolla.com/articles/032807-1.aspx

        6
  •  2
  •   Bart Verkoeijen    10 年前

    自从 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] .

        7
  •  1
  •   CubeJockey Marco    8 年前

    以下是完整的解决方案: 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>
    
        8
  •  1
  •   user2981217    7 年前

    我接受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;
        }
    

    依我看,这很简单。请随意证明我错了:)

        9
  •  1
  •   Damian    7 年前

    我使用钥匙的命名规则,它的工作方式很有魅力

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