我有一个简单的控制台应用程序,用于在运行此操作时读取自定义配置异常(下面的代码)我在调用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:
答案 0 :(得分:4)
我没有看到自定义部分按照您尝试的方式定义。但是,您可以通过进行一些小的更改来使其工作
从以下位置更改配置:
...
<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>
...
答案 1 :(得分:1)
如果它对任何人有帮助,我有同样的错误,但原因不同。在我的自定义ConfigurationElementCollection类中,GetElementKey()方法返回的值有时为null:
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="*" ...
答案 2 :(得分:0)
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; }
}
}
}
答案 3 :(得分:0)
您必须添加一个MyName键值
<add name="MyName" value="your value" />