汎用プロパティ検証アプリケーションブロックの検証

私たちはGenericsプロパティを持っています

 public class BE
    {
        private List _Admin_Fee = new List();
        [StringLengthValidator(3,
        MessageTemplate = "Fund City Can't be more than 3 Chars")]  
        public MyProperty FUND_CITY { get; set; }

        public MyProperty SomeOtherProperty { get; set; }

        public List MyDataPoints { get; set; }

    }

Generic Propertyで StingLengthValidator VAB
を使用してエラーを取得したい:

値は予期しないタイプです

助けてもらえますか?

ベストアンサー

The reason why you are getting an error is fairly straight
forward: you are trying to use a StringLengthValidator
against a type that isn’t a string (it is actually
MyProperty).

質問は、プロパティを検証するために何をすべきか?バリデーション・アプリケーション・ブロックの設計では、デザインが実際にはうまく適合しないため、扱いにくいです。

通常、 MyProperty クラスを検証するために
ObjectValidator を適用するだけですが、この場合は実際には適合しません。
code>を使用してさまざまな値をそれぞれ異なるルールで保持するので、バリデータの属性を実際に
MyProperty に適用することはできません。

私はカスタムバリデーターであなたが望むものを達成できると思います。私はあなたのカスタムバリデータの中に既存のバリデータをラップすることができると思っています。

ここでは、 MyProperty が次のようになっていると仮定しています。

public class MyProperty
{
    public T Value { get; set; }
}

次に、カスタムバリデータMyPropertyValidatorを作成できます。

public class MyPropertyValidatorAttribute : ValidatorAttribute
{
    Microsoft.Practices.EnterpriseLibrary.Validation.Validator validator;

    public MyPropertyValidatorAttribute(Type validator, params object[] validatorArgs)
    {
        this.validator = Activator.CreateInstance(validator, validatorArgs) 
            as Microsoft.Practices.EnterpriseLibrary.Validation.Validator;    
    }

    protected override Microsoft.Practices.EnterpriseLibrary.Validation.Validator DoCreateValidator(Type targetType)
    {
        return new MyPropertyValidator(validator);
    }
}

public class MyPropertyValidator : Microsoft.Practices.EnterpriseLibrary.Validation.Validator
{
    Microsoft.Practices.EnterpriseLibrary.Validation.Validator validator;

    public MyPropertyValidator(Microsoft.Practices.EnterpriseLibrary.Validation.Validator validator)
        : this(validator.MessageTemplate, validator.Tag)
    {
        this.validator = validator;
    }

    public MyPropertyValidator(string message, string tag) : base(message, tag)
    {
    }

    protected override string DefaultMessageTemplate
    {
        get { return ""; }
    }

    public override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults)
    {
        var val = objectToValidate;

        Type t = objectToValidate.GetType();
        var propInfo = t.GetProperty("Value");

        if (propInfo != null)
        {
            val = propInfo.GetValue(objectToValidate, null);
        }

        validator.DoValidate(val, currentTarget, key, validationResults);
    }
}

次に、クラスに注釈を付けることができます。

public class BE
{
    [MyPropertyValidator( 
        typeof(StringLengthValidator), 
        0, RangeBoundaryType.Ignore,
        3, RangeBoundaryType.Inclusive,
        "Fund City Can't be more than 3 Chars",
        false)]
    public MyProperty FUND_CITY { get; set; }

    [MyPropertyValidator(
        typeof(RangeValidator),
        0, RangeBoundaryType.Inclusive,
        10, RangeBoundaryType.Inclusive,
        "Must be between 0 and 10", 
        false)]
       public MyProperty SomeOtherProperty { get; set; }
}

私はそれを広範囲にテストしていないが、うまくいくようだ。それにはいくつかの欠点があります:

  • 柔軟性がありません。たとえば、コンポジットバリデータやその他のより複雑なシナリオをサポートしていません。おそらくすべてのケースを実装することができますが、それは乱雑になるでしょう。
  • 実装にはリフレクションを使用していますが、回避する方がよいでしょう。
  • 価値タイプの潜在的なボクシング

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です