【问题标题】:ConfigurationErrorsException "Invalid Key Value", What am I doing wrong?ConfigurationErrorsException“无效的键值”,我做错了什么?
【发布时间】:2010-12-07 12:50:50
【问题描述】:

我有一个简单的控制台应用程序,旨在在我运行此程序时读取自定义配置异常(下面的代码)。我在调用 ConfigurationManager.GetSection 时收到带有“无效键值”消息的 ConfigurationErrorsException。谁能看到我做错了什么?

配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="MySection" type="ConsoleApplication1.MySection, ConsoleApplication1" />
  </configSections>
  <MySection>
    <add name="MyName" value="MyValue" />
  </MySection>
</configuration>

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Configuration;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MySection section = (MySection)ConfigurationManager.GetSection("MySection");

            Console.WriteLine("Done");
        }
    }

    public class MySection : ConfigurationSection
    {
        [ConfigurationProperty("", IsDefaultCollection = true)]
        public MyCollection Collection
        {
            get
            {
                return (MyCollection)this[""];
            }
        }
    }

    public class MyCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new MyElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((MyElement)element).Name;
        }
    }

    public class MyElement : ConfigurationElement
    {
        [ConfigurationProperty("name")]
        public string Name { get; set; }

        [ConfigurationProperty("value")]
        public string Value { get; set; }


    }
}

例外

System.Configuration.ConfigurationErrorsException was unhandled
  Message=Invalid key value. (C:\Users\martin.brown\documents\visual studio 2010\Projects\ConsoleApplication1\bin\Debug\ConsoleApplication1.vshost.exe.config line 7)
  Source=System.Configuration
  BareMessage=Invalid key value.
  Filename=C:\Users\martin.brown\documents\visual studio 2010\Projects\ConsoleApplication1\bin\Debug\ConsoleApplication1.vshost.exe.config
  Line=7
  StackTrace:
       at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
       at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
       at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
       at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
       at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
       at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
       at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
       at System.Configuration.ConfigurationManager.GetSection(String sectionName)
       at ConsoleApplication1.Program.Main(String[] args) in C:\Users\martin.brown\documents\visual studio 2010\Projects\ConsoleApplication1\Program.cs:line 14
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

【问题讨论】:

    标签: c# .net app-config


    【解决方案1】:

    我没有看到自定义部分以您尝试的方式定义。但是,您可以通过进行一些小的更改来使其工作

    从以下位置更改您的配置:

    ...
    <MySection>
        <add name="MyName" value="MyValue" />
    </MySection>
    ...
    

    到:

    ...
    <MySection>
        <MyElements>
            <add name="MyName" value="MyValue" />
        </MyElements>
    </MySection>
    ...
    

    然后稍微修改你的代码:

    public class MySection : ConfigurationSection
    {
        [ConfigurationProperty("MyElements", IsDefaultCollection = true)]
        public MyCollection Collection{get {return (MyCollection) this["MyElements"];}}
    }
    
    public class MyElement : ConfigurationElement
    {
        [ConfigurationProperty("name")]
        public string Name
        {
            get {return (string) (base["name"]);}
            set {base["name"] = value;}
        }
    
        [ConfigurationProperty("value")]
        public string Value
        {
            get {return (string) (base["value"]);}
            set {base["value"] = value;}
        }
    }
    

    MyCollection 类保持不变)

    这将起作用,并且还可以让您在配置中添加多个值:

    ...
    <MySection>
        <MyElements>
            <add name="MyName1" value="MyValu1e" />
            <add name="MyName2" value="MyValue2" />
        </MyElements>
    </MySection>
    ...
    

    【讨论】:

    • 原来错误是由于我没有从基本 ConfigurationElement 的集合中获取 MyElement.Name 属性引起的。在 ConfigSection 中不给默认集合命名仅意味着您可以省略 元素。感谢您的帮助。
    • 我遇到了同样的问题,没有在属性上调用 base["name"]。
    【解决方案2】:

    如果它对任何人有帮助,我也会遇到同样的错误,但原因不同。在我的自定义 ConfigurationElementCollection 类中,GetElementKey() 方法返回的值有时为空:

    protected override Object GetElementKey(ConfigurationElement element)
    {
      return ((EmulatorPositionElement)element).Method;
    }
    

    更具体地说,它正在从自定义 ConfigurationElement 对象中检索可为空的枚举值:

    [ConfigurationProperty("method", IsRequired = true)]
    public string MethodString
    {
      get { return (string)this["method"]; }
      set { this["method"] = value; }
    }
    
    public Method? Method
    {
      get { return (MethodString.Trim() == "*") ? null : (Method?)Enum.Parse(typeof(Method), MethodString.Trim(), true); }
      set { MethodString = (value == null) ? "*" : value.ToString(); }
    }
    

    只要配置文件中有此 ConfigurationProperty 值为 null 的子元素,我就会收到此错误。

    <position method="*" ...
    

    【讨论】:

      【解决方案3】:

      您必须为 MyName 键添加一个值

      <add name="MyName" value="your value" /> 
      

      【讨论】:

        【解决方案4】:
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Xml.Serialization;
        using System.Configuration;
        
        namespace ConsoleApplication1
        {
            class Program
            {
                static void Main(string[] args)
                {
                      var section = (MySection)ConfigurationManager.GetSection("MySection");
        
                    Console.WriteLine("Done");
                }
            }
        
            public class MySection : ConfigurationSection
            {
                [ConfigurationProperty("name", IsKey = true, DefaultValue = "", IsRequired = true)]
                public string Name
                {
                    get { return (string)this["name"]; }
                    set { this["name"] = value; }
                }
        
                [ConfigurationProperty("value")]
                public string Value
                {
                    get { return (string)this["value"]; }
                    set { this["value"] = value; }
                }
        
            }
        
            public class MyCollection : ConfigurationElementCollection
            {
                protected override ConfigurationElement CreateNewElement()
                {
                    return new MyElement();
                }
        
                protected override object GetElementKey(ConfigurationElement element)
                {
                    return ((MyElement)element).Name;
                }
            }
        
            public class MyElement : ConfigurationElement
            {
                [ConfigurationProperty("name", IsKey = true, DefaultValue = "", IsRequired = true)]
                public string Name
                {
                    get { return (string)this["name"]; }
                    set { this["name"] = value; }
                }
        
                [ConfigurationProperty("value")]
                public string Value
                {
                    get { return (string)this["value"]; }
                    set { this["value"] = value; }
                }
        
        
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2020-02-14
          • 2019-07-26
          • 2022-07-31
          • 1970-01-01
          • 1970-01-01
          • 2019-03-13
          • 1970-01-01
          • 2011-06-01
          • 1970-01-01
          相关资源
          最近更新 更多