C# 自定义配置、配置元素和配置属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/568125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Custom Configuration, ConfigurationElements, and ConfigurationProperties
提问by user62064
I've been scouring the net for the last 3 days, and can't find any reference to this question. I've created a custom configuration class to be used with my app.config. Everything works fine. The problem comes in when a configuration property (of a configuration element) is not required, and is not defined in the app.config. It seems that default values are returned for the configuration property. Does anyone know how to determine if the property isn't defined in the app.config? (I've been trying to post my app.config, but can't figure out how to do it...anyone know how?)
过去 3 天我一直在网上搜索,但找不到任何关于此问题的参考。我创建了一个自定义配置类来与我的 app.config 一起使用。一切正常。当不需要配置属性(配置元素的)并且未在 app.config 中定义时,问题就会出现。似乎为配置属性返回了默认值。有谁知道如何确定该属性是否未在 app.config 中定义?(我一直在尝试发布我的 app.config,但不知道该怎么做……有人知道怎么做吗?)
//Main
namespace TestStub
{
class Program
{
static void Main(string[] args)
{
CustomSettingsHandler config = (CustomSettingsHandler)ConfigurationManager.GetSection("CustomSettingsManager");
Console.WriteLine("Setting1 {0}", config.Setting1.CustomSettingItem);
Console.WriteLine("Setting2 {0}", config.Setting2.CustomSettingItem);
}
}
}
//Custom Configuration Class
namespace CustomConfiguration
{
public class CustomSettingsHandler : ConfigurationSection
{
[ConfigurationProperty("setting1", IsRequired = false)]
public CustomSettingElement Setting1 { get { return (CustomSettingElement)this["setting1"]; } }
[ConfigurationProperty("setting2", IsRequired = false)]
public CustomSettingElement Setting2 { get { return (CustomSettingElement)this["setting2"]; } }
}
public class CustomSettingElement : ConfigurationElement
{
[ConfigurationProperty("customsettingitem", IsRequired = false)]
public int CustomSettingItem { get { return (int)this["customsettingitem"]; } }
}
}
回答by CodingWithSpike
The 2 things I can think of off the top of my head would be to use a DefaultValue, like so:
我能想到的两件事是使用 DefaultValue,如下所示:
[ConfigurationProperty("customsettingitem", DefaultValue = -1)]
public int CustomSettingItem { get { return (int)this["customsettingitem"]; } }
Assuming there is some value that is invalid. In this case, CustomSettingItem == -1 means it wasnt set, and >= 0 was a value set in config. Of course that assumes -1 wasnt valid input in the first place.
假设有一些无效的值。在这种情况下,CustomSettingItem == -1 表示它没有设置,>= 0 是在 config 中设置的值。当然,首先假设 -1 不是有效输入。
Second idea is to use a nullable int instead:
第二个想法是使用可为空的 int 代替:
[ConfigurationProperty("customsettingitem", IsRequired = false)]
public int? CustomSettingItem { get { return (int?)this["customsettingitem"]; } }
Now if nothing is set in config, it should default to null instead of 0.
现在,如果在 config 中没有设置任何内容,它应该默认为 null 而不是 0。
回答by Patrick Huizinga
So far I've not been able to tell a property to be null if it isn't defined in the configuration file. It seems that in it's infinite wisdom, Microsoft decided you really mean String.Empty or new ConfigurationElement() when you type null.
到目前为止,如果一个属性没有在配置文件中定义,我还不能告诉它为 null。似乎在它的无限智慧中,当您键入 null 时,Microsoft 决定您真正指的是 String.Empty 或 new ConfigurationElement()。
The way I'm currently solving it is like this:
我目前解决它的方式是这样的:
bool _hasProp = true;
protected override object OnRequiredPropertyNotFound(string name)
{
if (name == "prop")
{
_hasProp = false;
return null; // note that this will still not make prop null
}
return base.OnRequiredPropertyNotFound(name);
}
[ConfigurationProperty("prop", IsRequired = true)]
public string Prop
{
get { return _hasProp ? (string) this["prop"] : null; }
}
It's a hack and will wrongly mark the property as required. If you're using a tool to edit your configuration file it won't like this.
这是一种黑客行为,会根据需要错误地标记该属性。如果您使用工具来编辑您的配置文件,它不会像这样。
回答by Good Night Nerd Pride
I found the best way is to override ConfigurationSection.PostDeserialize()
and check the IsPresent
property of each section member that derives from ConfigurationElement
.
我发现最好的方法是覆盖ConfigurationSection.PostDeserialize()
和检查IsPresent
从ConfigurationElement
.
public class CustomSettingsHandler : ConfigurationSection
{
// ...
protected override void PostDeserialize()
{
foreach (ConfigurationProperty property in Properties)
{
var configElement = this[property] as ConfigurationElement;
if (configElement != null
&& !configElement.ElementInformation.IsPresent)
{
this[property] = null;
}
}
base.PostDeserialize();
}
}
Each ConfigurationElement
that has not been read from the config file will be null
afterwards.
ConfigurationElement
没有从配置文件中读取的每个都将在null
之后。
回答by vocaris
Try the following:
请尝试以下操作:
configElement.ElementInformation.Properties[propName].ValueOrigin =
PropertyValueOrigin.SetHere
The ValueOrigin
property tells you where does the value come from.
该ValueOrigin
属性会告诉您值从何而来。
回答by Jose Ch.
You can also check using the following:
您还可以使用以下方法进行检查:
config.Setting1.CustomSettingItem.ElementInformation.IsPresent
it will give you false if it was not found in your config file.
如果在您的配置文件中找不到它,它会给您 false。