11

我問類似的問題here但在這個問題上我用另一種實現方式,正是this way以下代碼顯示我的實現:ASP.NET MVC實現自定義的驗證器使用IClientValidatable

型號:

public class Department { 

    public long Id { get; set; } 

    [IsDateAfter("Date2", true, ErrorMessage = "O My")] 
    public DateTime Date1 { get; set; } 
    public DateTime Date2 { get; set; } 
    public string Name1 { get; set; } 
    public string Name2 { get; set; } 

} 

定製驗證器:

public sealed class IsDateAfter : ValidationAttribute, IClientValidatable { 

    private readonly string testedPropertyName; 
    private readonly bool allowEqualDates; 

    public IsDateAfter(string testedPropertyName, bool allowEqualDates = false) 
    { 
     this.testedPropertyName = testedPropertyName; 
     this.allowEqualDates = allowEqualDates; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext 
validationContext) { 
     var propertyTestedInfo = 
validationContext.ObjectType.GetProperty(this.testedPropertyName); 
     if (propertyTestedInfo == null) { 
      return new ValidationResult(string.Format("unknown property 
{0}", this.testedPropertyName)); 
     } 

     var propertyTestedValue = 
propertyTestedInfo.GetValue(validationContext.ObjectInstance, null); 

     if (value == null || !(value is DateTime)) { 
      return ValidationResult.Success; 
     } 

     if (propertyTestedValue == null || !(propertyTestedValue is 
DateTime)) { 
      return ValidationResult.Success; 
     } 

     // Compare values 
     if ((DateTime)value >= (DateTime)propertyTestedValue) { 
      if (this.allowEqualDates) { 
       return ValidationResult.Success; 
      } 
      if ((DateTime)value > (DateTime)propertyTestedValue) { 
       return ValidationResult.Success; 
      } 
     } 

     return new 
ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
    } 

    public IEnumerable<ModelClientValidationRule> 
GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { 
     var rule = new ModelClientValidationRule { 
      ErrorMessage = this.ErrorMessageString, 
      ValidationType = "isdateafter" 
     }; 
     rule.ValidationParameters["propertytested"] = 
this.testedPropertyName; 
     rule.ValidationParameters["allowequaldates"] = 
this.allowEqualDates; 
     yield return rule; 
    } 
} 

腳本:

$.validator.unobtrusive.adapters.add(
'isdateafter', ['propertytested', 'allowequaldates'], function (options) { 
    options.rules['isdateafter'] = options.params; 
    options.messages['isdateafter'] = options.message; 
}); 
$.validator.addMethod("isdateafter", function (value, element, params) { 
alert(params.propertytested); 
var startdatevalue = $('input[name="' + params.propertytested + '"]').val(); 
if (!value || !startdatevalue) return true; 
return (params.allowequaldates) ? Date.parse(startdatevalue) <= Date.parse(value) : 
Date.parse(startdatevalue) < Date.parse(value); 
}, ''); 

和我的_layout頁(主頁)

<!DOCTYPE html> 
<html> 
<head> 
<title>@ViewBag.Title</title> 
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> 
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/MicrosoftMvcValidation.js")" 
type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" 
type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" 
type="text/javascript"></script> 
</head> 
<body> 
<div class="page"> 
    <div id="header"> 
     <div id="title"> 
      <h1> 
       My MVC Application</h1> 
     </div> 
     <div id="logindisplay"> 
      @Html.Partial("_LogOnPartial") 
     </div> 
     <div id="menucontainer"> 
      <ul id="menu"> 
     <li>@Html.ActionLink("Departments", "Index", "Department")</li> 
      </ul> 
     </div> 
    </div> 
    <div id="main"> 
     @RenderBody() 
    </div> 
    <div id="footer"> 
    </div> 
</div> 
</body> 
</html> 
當然,在編輯的

,並創建查看頁面其他腳本源如下:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> 
</script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" 
type="text/javascript"></script> 

Create Page Dom的一部分:

<fieldset> 
<legend>Department</legend> 
<div class="editor-label"> 
<label for="Date1">Date1</label> 
</div> 
<div class="editor-field"> 
<input id="Date1" class="text-box single-line valid" type="text" value="" name="Date1" 
data-val-required="The Date1 field is required." data-val-isdateafter- 
propertytested="Date2" data-val-isdateafter-allowequaldates="False" data-val- 
isdateafter="O My" data-val="true"> 
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg- 
    for="Date1"></span> 
</div> 
<div class="editor-label"> 
<label for="Date2">Date2</label> 
</div> 
<div class="editor-field"> 
<input id="Date2" class="text-box single-line valid" type="text" value="" name="Date2" 
data-val-required="The Date2 field is required." data-val="true"> 
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg- 
for="Date2"></span> 
</div> 

我嘗試所有的實施是相同的here但在客戶端無法正常工作,需要回傳,我沒有任何其他的實現,例如在Global.asax中 註冊像this,請問任何人都知道嗎?我真的很困惑,我嘗試了2種方式,但沒有人給出真正的答案。

回答

9

你弄亂了你的腳本包含。在你_layout已包含在順序以下腳本:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" type="text/javascript"></script> 

現在很明顯jquery.validate.min.jsjquery.validate.js代表相同的腳本,首先是縮小的版本。但是由於您沒有包含jquery.validate.unobtrusive.js腳本(這在您的視圖中稍後完成),您的自定義jQuery.IsDateAfter.js腳本將包含錯誤,因爲它不會知道您正在使用的對象$.validator.unobtrusive.adapters。因此,這裏是你的佈局腳本應該是什麼樣子:

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

你也可以在末尾添加自定義jQuery.IsDateAfter.js腳本的佈局,如果你的情況下,希望它在許多視圖中使用,如果沒有,你可以添加它到視圖:

<script src="@Url.Content("~/Scripts/jQuery.IsDateAfter.js")" type="text/javascript"></script> 

這是你應該在視圖中唯一的腳本。您應該從編輯和創建視圖頁面中刪除任何其他jquery.*腳本包含。

備註:您還會注意到我已經從佈局中刪除了所有Microsoft*.js腳本。它們已經過時,不應該再用於ASP.NET MVC 3.

+2

我跟着這個,可以看到驗證錯誤消息,而我編輯的表單很棒。一個奇怪的事情,它不停止形式發佈,即使有無效的字段與適當的驗證錯誤消息,但是服務器不承認ModelState.IsValid爲false ...這是正常的行爲還是我錯過了什麼? – afr0