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。但是,如果它不为 NULL,则 EmailAddress 需要验证字符串长度并通过 Regex 电子邮件验证。

有人可以告诉我缺少什么或我在此验证中做错了吗?

编辑

请注意,这不在 MVC 模型中,而是在类对象中。此属性是 DTO 的一部分,而不是页面模型(此层不使用 DataAnnotations 类)。

谢谢!

4

5 回答 5

2

因此,感谢您提供的所有解决方案,但基于 Tuzo 提供的链接。我必须实施:

[HasSelfValidation]
public class SomeDTO
{
    public string BillingEmailAddress { get; set; }
}

到班级。然后我不得不实施:

[SelfValidation]
public void Validation(ValidationResults results)
{
    if (!Utility.IsValidEmailAddress(this.BillingEmailAddress))
    {
        results.AddResult(new ValidationResult(Constants.ERROR_INVALID_EMAILADDRESS, this, "", "", null));
    }
}

作为类的方法。

我希望这可以帮助遇到同样问题的人。

于 2012-12-20T22:46:14.523 回答
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 回答
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>

您还可以通过编程方式创建嵌套验证器。请参阅使用复合验证器进行验证@ 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");

另一种方法是创建您自己的处理空值的验证器。

于 2012-12-19T07:44:07.067 回答
0

我自己从来不需要这样做,但我认为您可以创建自己的 DataAnnotations Validation 上下文。看到这个帖子:

检查模型在控制器之外是否有效

然后你只需要制作一个验证属性。我使用自定义验证器在我的应用程序中对电子邮件地址做了类似的事情。这是我的代码,经过修改以更好地满足您的问题。

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 回答
-1

有一个NullIgnoringValidatorWrapper 类

于 2014-07-03T15:47:28.413 回答