针对多个值的自定义.NET ConfigurationSection验证

时间:2014-08-08 14:57:32

标签: c# validation config

我正在实施自定义.NET ConfigurationSection并需要验证配置中是否满足以下两个条件之一,但我不确定如何针对多个字段进行验证。

基本上条件是,给定三个KVP(A,B和C),需要A或B和C是必需的。

因为它们实际上是独立可选的,所以我不能将它们标记为必需,但是有效配置需要两个条件中的一个。

我已经阅读过关于在Jon Rista的Decoding the Mysteries of .NET 2.0 Configuration上编写自定义验证器的内容,但这些只验证了单个字段的值。

我是否应该将这三个设置嵌套为自己的ConfigurationElement并为显示此部分的属性编写验证器(或使用CallbackValidator)?或者有更好的方法来验证多个属性吗?

2 个答案:

答案 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赞同。