4

他の検証属性を呼び出すカスタム検証属性を作成したいと思います。

たとえば、。という属性を作成したいとしますPasswordValidationAttribute。で定義されているプロパティとRequiredAttribute、定義されているさまざまなパラメーター(パスワードの正規表現、文字列の最大長と最小長など)を装飾する必要があります。RegularExpressionAttributeStringLengthAttribute

私はどこから始めればよいのか、どれだけの作業が必要かを確認し、それが可能かどうかを判断するのに苦労しています。この属性がプロパティに適用されたら、ValidationMessageFor HtmlHelper正しく処理してサーバー側の呼び出しを実行したいと思います。私はそれらを再定義する必要がないことを望んでいます(そうでなければ、それはあまりにも多くの作業になります)。

4

1 に答える 1

5

.net 4の場合、次のようになります。

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class MyValidationAttribute : ValidationAttribute
{
    private readonly bool isRequired;

    public string Regex { get; set; }

    public int StringLength { get; set; }

    public MyValidationAttribute(bool isRequired)
    {
        this.isRequired = isRequired;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var composedAttributes = ConstructAttributes().ToArray();
        if (composedAttributes.Length == 0) return ValidationResult.Success;

        var errorMsgBuilder = new StringBuilder();
        foreach (var attribute in composedAttributes)
        {
            var valRes = attribute.GetValidationResult(value, validationContext);
            if (valRes != null && !string.IsNullOrWhiteSpace(valRes.ErrorMessage))
                errorMsgBuilder.AppendLine(valRes.ErrorMessage);
        }
        var msg = errorMsgBuilder.ToString();
        if (string.IsNullOrWhiteSpace(msg))
            return ValidationResult.Success;
        return new ValidationResult(msg);
    }

    private IEnumerable<ValidationAttribute> ConstructAttributes()
    {
        if (isRequired)
            yield return new RequiredAttribute();
        if (Regex != null)
            yield return new RegularExpressionAttribute(Regex);
        if (StringLength > 0)
            yield return new StringLengthAttribute(StringLength);
    }
}

使用法:

[MyValidationAttribute(true, Regex = "[a-z]*", StringLength = 3)]
public string Name { get; set; }

.net 3.5には、基になる属性からメッセージ値を動的に構築できないという制限があります(少なくとも私はそれを通り抜けることができませんでした)。属性全体に設定できるメッセージは1つだけです。

変更されたものはすべてメソッド内にありIsValidます。

public override bool IsValid(object value)
{
    var composedAttributes = ConstructAttributes().ToArray();
    if (composedAttributes.Length == 0) return true;
    return composedAttributes.All(a => a.IsValid(value));
}

ErrorMessage

IsValid.net3.5のメソッドの戻り値はでValidationAttributeはありませValidationResultbool。を設定しようとするとErrorMessage、というエラーが発生しましたvalue can be set only once

于 2013-02-02T22:45:26.643 に答える