3

次のようなプロパティのクラスに設定されたプロパティのリストがあります。

[ValidatorComposition(CompositionType.Or, Ruleset = "BillingEmail", MessageTemplate = Constants.ERROR_INVALID_EMAILADDRESS)]
[NotNullValidator(Negated = true, Ruleset = "BillingEmail")]
[StringLengthValidator(0, RangeBoundaryType.Exclusive, 255, RangeBoundaryType.Inclusive, Ruleset = "BillingEmail")]
[RegexValidator(@"^[A-Z0-9._%-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$", RegexOptions.IgnoreCase, Ruleset = "BillingEmail")]
public string BillingEmailAddress { get; set; }

私が抱えている問題は、私が入力することです:

someone@blah

メールアドレスは引き続き検証に合格します。

私が望むルールは、BillingEmailAddress が NULL の場合、それは VALID です。ただし、NOT NULL の場合、EmailAddress は文字列の長さを確認し、正規表現の電子メール検証にも合格する必要があります。

この検証で何が欠けているか、または間違っているかを誰かに教えてもらえますか?

編集

これは MVC モデルではなく、クラス オブジェクトであることに注意してください。このプロパティは DTO の一部であり、ページ モデルではありません (DataAnnotations クラスはこのレイヤーでは使用されません)。

ありがとう!

4

5 に答える 5

1

ValidatorComposition問題は、複数の属性をネストできないことだと思います。

構成ベースのアプローチを使用して、必要なことを確実に行うことができます。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    </configSections>
    <validation>
        <type name="ConsoleApplication.Order" defaultRuleset="Validation Ruleset"
            assemblyName="ConsoleApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
            <ruleset name="Validation Ruleset">
                <properties>
                    <property name="BillingEmailAddress">
                        <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.AndCompositeValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                            name="And Composite Validator">
                            <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.OrCompositeValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                                name="Or Composite Validator">
                                <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                                    negated="true" name="Not Null Validator" />
                                <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                                    upperBound="255" lowerBound="5" lowerBoundType="Exclusive"
                                    name="String Length Validator" />
                            </validator>
                            <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.OrCompositeValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                                name="Or Composite Validator 2">
                                <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                                    negated="true" name="Not Null Validator" />
                                <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.RegexValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                                    pattern="^[A-Z0-9._%-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$" options="IgnoreCase"
                                    name="Regular Expression Validator" />
                            </validator>
                        </validator>
                    </property>
                </properties>
            </ruleset>
        </type>
    </validation>
</configuration>

ネストされたバリデーターをプログラムで作成することもできます。Composite Validator による検証 @ http://msdn.microsoft.com/en-us/library/ff953182(v=pandp.50).aspxのセクションを参照してください。

別の方法として、複数のルールセットを使用することもできます:

    [ValidatorComposition(CompositionType.Or, Ruleset = "BillingEmailStringLength", MessageTemplate = Constants.ERROR_INVALID_EMAILADDRESS)]
    [StringLengthValidator(5, RangeBoundaryType.Exclusive, 255, RangeBoundaryType.Inclusive, Ruleset = "BillingEmailStringLength")]
    [NotNullValidator(Negated = true, Ruleset = "BillingEmailStringLength")]
    [ValidatorComposition(CompositionType.Or, Ruleset = "BillingEmailStringFormat", MessageTemplate = Constants.ERROR_INVALID_EMAILADDRESS)]
    [RegexValidator(@"^[A-Z0-9._%-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$", RegexOptions.IgnoreCase, Ruleset = "BillingEmailStringFormat")]
    [NotNullValidator(Negated = true, Ruleset = "BillingEmailStringFormat")]
    public string BillingEmailAddress { get; set; }

次に、検証する複数のルールセットを指定できます。

var vrs = Validation.Validate(objectToValidate, 
              "BillingEmailStringLength", "BillingEmailStringFormat");

もう 1 つの方法は、null 値を処理する独自のバリデータを作成することです。

于 2012-12-19T07:44:07.067 に答える
1

属性を使って検証を行っている人を見ると、目が痛くなります。繰り返しますが、 FluentValidationを使用することをお勧めします。モデルはよりきれいになり、検証は次のようになります。

public class CustomerValidator: AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        RuleFor(customer => customer.BillingEmailAddress)
            .NotEmpty()
            .WithMessage("You must specify Email Address.")
            .Length(1, 255)
            .WithMessage("Email address is too long.")
            .EmailAddress();
    }
}

これはビューモデルに関するものです。ここで、これが DTO であるという事実についての要件をカバーします。次のように、検証を個別にトリガーできます。

Customer customer = // get your customer from whatever source
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);
if(results.Errors.Count() > 0)
    // do whatever in case your customer class does not validate
于 2012-12-18T22:34:33.223 に答える
0

私はこれを自分で行う必要はありませんでしたが、独自の DataAnnotations Validation コンテキストを作成できると思います。この投稿を参照してください。

Model が Controller の外部で有効かどうかを確認する

次に、検証属性を作成するだけです。カスタムバリデーターを使用して、アプリケーションの電子メールアドレスで同様のことを行いました。これが私のコードで、あなたの質問により適したものに変更されています。

public class MyEmailValidationAttribute : RegularExpressionAttribute
{
    public MyEmailValidationAttribute ()
        : base(@"^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-zA-Z0-9]{1}[a-zA-Z0-9\-]{0,62}[a-zA-Z0-9]{1})|[a-zA-Z])\.)+[a-zA-Z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$")
    {
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        Regex RegexObj = new Regex(this.Pattern);

        if (value == null)
        {
            return ValidationResult.Success;
        }           

        Match match = RegexObj.Match((string)value);

        if (!match.Success)
        {
            return new ValidationResult("Email not in correct format.");
        }

        return ValidationResult.Success;     
    }
}

次に、モデルに次を追加します。

//You may be able to remove some of your other attributes 
//by going this route so I won't include them all.
[MyEmailValidationAttribute()]
public string BillingEmailAddress { get; set; }
于 2012-12-18T21:36:49.177 に答える