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

私はあなたのコードを見ることができるの問題がいくつかあります。最初の1:

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

ダーリンさん、ありがとうございました。その作業: – HKGR

+0

@DarinDimitrov「モデルに定義されているエラーではなく、常に同じエラーが表示されるため、エラーメッセージがここに表示されます。 –

+0

わかった。これは 'String.Format(ErrorMessage、metadata.GetDisplayName()、this.Min)'となります。 –

関連する問題