1

我是mvc 3.0和jquery的新手。我試圖在客戶端和服務器端使用自定義驗證屬性驗證'日期'。它在服務器端運行良好,但無法使其在客戶端工作。MVC 3.0 - 不顯眼的客戶端驗證不適用於自定義屬性

上午使用mvc 3.0,jquery,IE 7.0。 我們是否需要在MVC 3.0中的global.ascx中註冊任何東西?

請讓我知道我錯了。 TIA。

這裏是我的代碼:

驗證屬性

public class FutureDateAttribute : ValidationAttribute, IClientValidatable 
{ 
     private const string DateFormat = "mm/dd/yyyy"; 
     private const string DefaultErrorMessage = "'{0}' must be a date between {1:d} and current date."; 

     public DateTime Min { get; set; } 
     public DateTime Max { get; set; } 

     public FutureDateAttribute(string min) 
      : base(DefaultErrorMessage) 
     { 
      Min = ParseDate(min); 
      Max = DateTime.Now; 
     } 

     public override bool IsValid(object value) 
     { 
      if (value == null || !(value is DateTime)) 
      { return true; } 
      DateTime dateValue = (DateTime)value; 
      return Min <= dateValue && dateValue <= Max; 
     } 

     private static DateTime ParseDate(string dateValue) 
     { 
      return DateTime.ParseExact(dateValue, DateFormat, System.Globalization.CultureInfo.InvariantCulture); 
     } 

     public override string FormatErrorMessage(string name) 
     { 
      return String.Format(System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Min); 
     } 

     public class ModelClientValidationFutureDateRule : ModelClientValidationRule 
     { 
      public ModelClientValidationFutureDateRule(string errorMessage, 
       DateTime min) 
      { 
       ErrorMessage = errorMessage; 
       ValidationType = "futuredate"; 
       ValidationParameters["min"] = min.ToString("mm/dd/yyyy"); 
       ValidationParameters["max"] = DateTime.Now.ToString("mm/dd/yyyy"); 
      } 
     } 

     public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
     { 
      var rule = new ModelClientValidationFutureDateRule("Error message goes here", this.Min); 
      yield return rule; 
     } 

jQuery的

(function ($) { 
$.validator.addMethod('futuredate', function (value, element, param) { 
    if (!value) return false; 
    var min = $(param.min).val(); 
    var max = $(param.max).val(); 
    if (value < min || value > max) { 
     return false; 
    } 
    return true; 
}); 

$.validator.unobtrusive.adapters.add(
    'futuredate', ['min', 'max'], 
    function (options) { 
     var params = { 
      min: options.params.min, 
      max: options.params.max 
     }; 

     options.rules['futuredate'] = params; 
     if (options.message) { 
      options.messages['futuredate'] = options.message; 
     } 
    }); 
} (jQuery)); 

參考

<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> 
///reference path="jquery-1.5.1.min.js" /> 
///reference path="jquery.validate.js" /> 
///reference path="jquery-ui-1.8.11.js" /> 
    ///reference path="jquery.validate.unobtrusive.min.js" /> 
///reference path="jquery.validate-vsdoc.js" /> 

型號:

[DisplayName("Assigned Date :")] 
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)] 
    [Required(ErrorMessage = "Assigned Date is required")] 
    [DataType(DataType.Date)] 
    [FutureDate("12/31/1899", ErrorMessage = "'{0}' must be a date between {1:d} and current date.")] 
    public DateTime? AssignedDate { get; set; } 

回答

2

有幾個問題我可以用你的代碼中看到。第一招:

ValidationParameters["min"] = min.ToString("mm/dd/yyyy"); 
ValidationParameters["max"] = DateTime.Now.ToString("mm/dd/yyyy"); 

一定是真的:

ValidationParameters["min"] = min.ToString("MM/dd/yyyy"); 
ValidationParameters["max"] = DateTime.Now.ToString("MM/dd/yyyy"); 

因爲mm意味着分鐘而不是幾個月。

相同的註釋爲:

private const string DateFormat = "mm/dd/yyyy"; 

必須是:

private const string DateFormat = "MM/dd/yyyy"; 

在你有一對夫婦的問題,以及客戶端。在您的驗證方法中,您似乎在做var min = $(param.min).val();,這意味着var min = $('12/31/1899').val();顯然沒有多大意義。在能夠比較它們之前,您必須將這些值解析爲javascript Date實例。

因此,這裏就是我會建議你:

@model MyViewModel 

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> 
<script type="text/javascript"> 
    (function ($) { 
     var parseDate = function (str) { 
      var m = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/); 
      return (m) ? new Date(m[3], m[1] - 1, m[2]) : null; 
     }; 

     $.validator.addMethod('futuredate', function (value, element, param) { 
      if (!value) return false; 

      var min = parseDate(param.min); 
      var max = parseDate(param.max); 
      var current = parseDate(value); 

      if (min == null || max == null || current == null) { 
       return false; 
      } 

      return (current >= min && current <= max); 
     }); 

     $.validator.unobtrusive.adapters.add('futuredate', ['min', 'max'], function (options) { 
      var params = { 
       min: options.params.min, 
       max: options.params.max 
      }; 

      options.rules['futuredate'] = params; 
      if (options.message) { 
       options.messages['futuredate'] = options.message; 
      } 
     }); 
    } (jQuery)); 
</script> 

@using (Html.BeginForm()) 
{ 
    @Html.LabelFor(x => x.AssignedDate) 
    @Html.EditorFor(x => x.AssignedDate) 
    @Html.ValidationMessageFor(x => x.AssignedDate) 
    <button type="submit">OK</button> 
} 

和這裏的驗證的完整代碼屬性我已經用了我的測試案例:

public class FutureDateAttribute : ValidationAttribute, IClientValidatable 
{ 
    private const string DateFormat = "MM/dd/yyyy"; 
    private const string DefaultErrorMessage = "'{0}' must be a date between {1:d} and current date."; 

    public DateTime Min { get; set; } 
    public DateTime Max { get; set; } 

    public FutureDateAttribute(string min) 
     : base(DefaultErrorMessage) 
    { 
     Min = ParseDate(min); 
     Max = DateTime.Now; 
    } 

    public override bool IsValid(object value) 
    { 
     if (value == null || !(value is DateTime)) 
     { return true; } 
     DateTime dateValue = (DateTime)value; 
     return Min <= dateValue && dateValue <= Max; 
    } 

    private static DateTime ParseDate(string dateValue) 
    { 
     return DateTime.ParseExact(dateValue, DateFormat, System.Globalization.CultureInfo.InvariantCulture); 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return String.Format(System.Globalization.CultureInfo.CurrentCulture, ErrorMessageString, name, Min); 
    } 

    public class ModelClientValidationFutureDateRule : ModelClientValidationRule 
    { 
     public ModelClientValidationFutureDateRule(string errorMessage, 
      DateTime min) 
     { 
      ErrorMessage = errorMessage; 
      ValidationType = "futuredate"; 
      ValidationParameters["min"] = min.ToString("MM/dd/yyyy"); 
      ValidationParameters["max"] = DateTime.Now.ToString("MM/dd/yyyy"); 
     } 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var rule = new ModelClientValidationFutureDateRule("Error message goes here", this.Min); 
     yield return rule; 
    } 
} 

和模型:

public class MyViewModel 
{ 
    [DisplayName("Assigned Date :")] 
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)] 
    [Required(ErrorMessage = "Assigned Date is required")] 
    [DataType(DataType.Date)] 
    [FutureDate("12/31/1899", ErrorMessage = "'{0}' must be a date between {1:d} and current date.")] 
    public DateTime? AssignedDate { get; set; } 
} 

和控制器:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel 
     { 
      AssignedDate = DateTime.Now.AddDays(2) 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 
+0

非常感謝Darin,它的工作:) – HKGR 2012-02-21 05:32:22

+0

@DarinDimitrov什麼將代替''錯誤信息到這裏來''因爲我總是得到相同的錯誤,而不是模型中定義的錯誤? – 2015-05-15 09:57:15

+0

好的。瞭解。它將是'String.Format(ErrorMessage,metadata.GetDisplayName(),this.Min)' – 2015-05-15 10:27:47

相關問題