我正在实施自定义.NET ConfigurationSection
并需要验证配置中是否满足以下两个条件之一,但我不确定如何针对多个字段进行验证。
基本上条件是,给定三个KVP(A,B和C),需要A或B和C是必需的。
因为它们实际上是独立可选的,所以我不能将它们标记为必需,但是有效配置需要两个条件中的一个。
我已经阅读过关于在Jon Rista的Decoding the Mysteries of .NET 2.0 Configuration上编写自定义验证器的内容,但这些只验证了单个字段的值。
我是否应该将这三个设置嵌套为自己的ConfigurationElement
并为显示此部分的属性编写验证器(或使用CallbackValidator
)?或者有更好的方法来验证多个属性吗?
答案 0 :(得分:2)
如何使用the PostDeserialize
method?
protected override void PostDeserialize()
{
base.PostDeserialize();
if (A == null && (B == null || C == null))
{
throw new ConfigurationErrorsException("...");
}
}
答案 1 :(得分:1)
我最终将这三个配置属性推送到自定义ConfigurationElement
并在属性上使用CallbackValidator
:
public class AlphabetElement : ConfigurationElement
{
private static ConfigurationPropertyCollection _properties;
private static ConfigurationProperty _a;
[ConfigurationProperty("A")]
public Letter A
{
get { return (Letter)base[_a]; }
}
private static ConfigurationProperty _b;
[ConfigurationProperty("B")]
public Letter B
{
get { return (Letter)base[_b]; }
}
private static ConfigurationProperty _c;
[ConfigurationProperty("C")]
public Letter C
{
get { return (Letter)base[_c]; }
}
static AlphabetElement()
{
// Initialize the ConfigurationProperty settings here...
}
public static void Validate(object value)
{
AlphabetElement element = value as AlphabetElement;
if (element == null)
throw new ArgumentException(
"The method was called on an invalid object.", "value");
if (A == null && (B == null || C == null))
throw new ArgumentException(
"Big A, little a, bouncing beh... " +
"The system might have got you but it won't get me.");
}
}
public class BestBefore : ConfigurationSection
{
private static ConfigurationPropertyCollection _properties;
private static ConfigurationProperty _alphabetElement;
[ConfigurationProperty("alphabet", IsRequired = true)]
public AlphabetElement Alphabet
{
get { return (AlphabetElement)base[_alphabetElement]; }
}
static BestBefore()
{
_properties = new ConfigurationPropertyCollection();
_alphabetElement = new ConfigurationProperty(
"alphabet",
typeof(AlphabetElement),
null,
null,
new CallbackValidator(
typeof(AlphabetElement),
new ValidatorCallback(AlphabetElement.Validate)),
ConfigurationPropertyOptions.IsRequired);
_properties.Add(_alphabetElement);
}
}
然后在配置中它看起来像:
<bestBefore ...>
<alphabet B="B" C="C"/>
</bestBefore>
我会把这个留给后人。
Crass赞同。