2012-07-13 100 views
0

我一直试图使EmailAddress自定义数据注释属性正确验证电子邮件,它似乎并没有在我的测试中为我工作。服务器端自定义数据注释验证MVC 3

这里的测试:

[Test] 
    public void ModelStateValidation() 
    { 
     var invalidEmails = new[] { "testtestcom", "[email protected]", "testtest.com" }; 
     var validEmail = "[email protected]"; 

     //Invalid Email addresses 
     foreach (var invalidEmail in invalidEmails) 
     { 
      var subscription = new SubscriberModel() { FirstName = "f", LastName = "l", Email = invalidEmail, ConfirmEmail = invalidEmail, DateSubscribed = DateTime.Now }; 
      ValidateModelAsFalse(subscription); 
     } 

     var subscription2 = new SubscriberModel() { FirstName = "f", LastName = "l", Email = "t", ConfirmEmail = "t", DateSubscribed = DateTime.Now }; 
     ValidateModelAsFalse(subscription2); 

     //Valid Email address 
     var subscription3 = new SubscriberModel() { FirstName = "f", LastName = "l", Email = validEmail, ConfirmEmail = validEmail, DateSubscribed = DateTime.Now }; 
     ValidateModelAsTrue(subscription3); 

     //Last Name doesn't exists 
     var subscription4 = new SubscriberModel() { FirstName = "f", LastName = "", Email = validEmail, ConfirmEmail = validEmail, DateSubscribed = DateTime.Now }; 
     ValidateModelAsFalse(subscription4); 

     //First Name doesn't exists 
     var subscription5 = new SubscriberModel() { FirstName = "", LastName = "l", Email = validEmail, ConfirmEmail = validEmail, DateSubscribed = DateTime.Now }; 
     ValidateModelAsFalse(subscription5); 

     //Email addresses are equal 
     var subscription6 = new SubscriberModel() { FirstName = "f", LastName = "l", Email = "[email protected]", ConfirmEmail = "[email protected]", DateSubscribed = DateTime.Now }; 
     ValidateModelAsFalse(subscription6); 
    } 

    private static void ValidateModelAsFalse(SubscriberModel subscription3) 
    { 
     SubscriptionController controller = new SubscriptionController(); 
     controller.ValidateModel(subscription3); 
     AssertIsFalse(controller); 
    } 

    private static void ValidateModelAsTrue(SubscriberModel subscription3) 
    { 
     SubscriptionController controller = new SubscriptionController(); 
     controller.ValidateModel(subscription3); 
     AssertIsTrue(controller); 
    } 

    private static void AssertIsTrue(SubscriptionController controller) 
    { 
     Assert.That(controller.ModelState.IsValid, Is.True); 
    } 

    private static void AssertIsFalse(SubscriptionController controller) 
    { 
     Assert.That(controller.ModelState.IsValid, Is.False); 
    } 

这里的ValidateModel方法:

<!-- language: c# --> 
public static void ValidateModel<T>(this Controller controller, T model) 
    { 
     var validationContext = new ValidationContext(model, null, null); 
     var validationResults = new List<ValidationResult>(); 
     Validator.TryValidateObject(model, validationContext, validationResults); 
     foreach (var validationResult in validationResults) 
     { 
      controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage); 
     } 
    } 

型号:

<!-- language: c# --> 
public partial class SubscriberModel 
{ 
    public int SubscriberID { get; set; } 

    [Required] 
    [DisplayName("First Name")] 
    public string FirstName { get; set; } 

    [Required] 
    [DisplayName("Last Name")] 
    public string LastName { get; set; } 

    [Required] 
    [EmailAddress] 
    [Compare("ConfirmEmail", ErrorMessage = "The emails must match")] 
    [DisplayName("E-mail")] 
    public string Email { get; set; } 

    [Required] 
    [DisplayName("Confirm E-mail")] 
    public string ConfirmEmail { get; set; } 

    [Required] 
    [DisplayName("Date Subscribed")] 
    public DateTime DateSubscribed { get; set; } 
} 

控制器:

public partial class SubscriptionController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    [CaptchaValidator] 
    [HttpPost] 
    public ActionResult Index(SubscriberModel subscription, bool captchaValid) 
    { 
     subscription.DateSubscribed = DateTime.Now; 
     ModelStateValid = ModelState.IsValid; 

     if(captchaValid) 
     { 
      if (ModelState.IsValid) 
      { 
       var test = ""; 
      } 
     } 

     return View(subscription); 
    } 
} 

EmailAttribute类:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] 
public sealed class EmailAddressAttribute : ValidationAttribute, IClientValidatable 
{ 
    private static Regex _regex = new Regex(@"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$", RegexOptions.Compiled | RegexOptions.IgnoreCase); 

    public EmailAddressAttribute() 
     : base() 
    { 
     ErrorMessage = "Invalid Email"; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { 
     yield return new ModelClientValidationRule { 
      ValidationType = "email", 
      ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()) 
     }; 
    } 

    public override bool IsValid(object value) 
    { 
     if (value == null) { 
      return false; 
     } 

     string valueAsString = value as string; 
     return _regex.Match(valueAsString).Success; 
    } 
} 

的IsValid的方法似乎验证了电子邮件地址,我打算,但由于某些原因,当我去跑在Controller.ValidateModel单元测试,它不会返回false和匹配我的断言。

回答

0

我曾经使用过类似的东西,实现IClientValidatable接口只是第一步。那么我不得不在客户端添加jQuery验证。我认为,定制验证只能使用jQuery

这里的客户端上执行是一个例子:

<script type="text/javascript"> 
    (function ($) { 
     $.validator.addMethod("yourValidationTypeName", function (value, element) { 
      //do validation here 
     }); 
     $.validator.unobtrusive.adapters.addBool("yourValidationTypeName"); 
    } (jQuery)); 
</script> 

使用内置的属性[正则表达式]与unobtusive JavaScript和客户端验证启用可能会解决你的问题。

纠正我,如果我错了,但我不是MVC3专家

+0

谢谢你,但客户端验证工作正常,它只是我不能让服务器端验证测试,以通过 – 2012-07-13 13:57:23

+0

是提交表单时访问您的IsValid()方法? – 2012-07-13 14:04:36

+0

是的,当我在IsValid方法中设置断点时,代码似乎在我提交表单时正确流动 – 2012-07-13 14:16:18

相关问题