我在类的属性中设置了一个属性列表,如下所示:
[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 Email验证。
有人可以告诉我在此验证中缺少什么或我做错了吗?
修改
请注意,这不是MVC模型,而是类对象。此属性是DTO的一部分,而不是页面模型(此层不使用DataAnnotations类)。
谢谢!
答案 0 :(得分: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));
}
}
作为课堂的一种方法。
我希望这可以帮助有同样问题的人。
答案 1 :(得分: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();
}
}
这与View Model有关。现在,为了满足您对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
答案 2 :(得分: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");
另一种方法是创建自己的验证器来处理空值。
答案 3 :(得分:0)
我自己从未这样做,但我认为您可以创建自己的DataAnnotations验证上下文。看这篇文章:
Check if Model is valid outside of 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; }
答案 4 :(得分:-1)