2012-07-13 133 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

相關問題