8

你推荐什么方法来验证MVC中客户端的DateTime?MVC2 DateTime的客户端验证?

比方说,我有一个名为DateOfBirth的属性的模型,即DateTime

public class UserModel 
{ 
    [DataType(DataType.Date)] 
    public DateTime DateOfBirth {get;set;} 
} 

在视图,我有一个简单

<%: Html.LabelFor(model=>model.DateOfBirth) %> 
<%: Html.EditorFor(model=>model.DateOfBirth) %> 
<%: Html.ValidationMessageFor(model=>model.DateOfBirth) %> 
<input type="submit" value="Submit" /> 

我可以使用微软MVC验证或jQuery的验证。我如何获得DateTime来验证客户端?

我意识到所有的DataTypeAttribute所提供的格式化提示并没有真正做任何验证(它将该部分留给了ModelBinder)。

基本上我想复制ModelBinder在试图将发布的值放入模型的DateOfBirth属性时所做的工作。

您有哪些建议?

+0

先发制人:是的,我已经看到了,读,并热爱菲尔哈克的定制验证。 HTTP:// haacked。com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx – Josh 2010-08-14 22:25:37

回答

4

正如上文所述,请按照菲尔哈克的帖子自定义验证:http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

这是我会怎么做:


  1. 添加 “DateFormatAttribute” 类,如下所示:

    public class DateFormatAttribute : ValidationAttribute { 
     public override bool IsValid(object value) {  
     if (value == null) { 
      return true; 
     } 

     // Note: the actual server side validation still has to be implemented :-) 
     // Just returning true now... 

     return true; 
     } 
    } 

  • 添加 “DateFormatValidator” 类,像这样:
  • 
        public class DateFormatValidator : DataAnnotationsModelValidator 
        { 
         string message; 
    
         public PriceValidator(ModelMetadata metadata, ControllerContext context 
         , DateFormatAttribute attribute) 
         : base(metadata, context, attribute) 
         { 
         message = attribute.ErrorMessage; 
         } 
    
         public override IEnumerable GetClientValidationRules() 
         { 
         var rule = new ModelClientValidationRule { 
          ErrorMessage = message, 
          ValidationType = "date" // note that this string will link to the JavaScript function we'll write later on 
         }; 
    
         return new[] { rule }; 
         } 
        } 
    

  • 注册上述类别某处全球。 asax.cs:
  • 
        DataAnnotationsModelValidatorProvider 
         .RegisterAdapter(typeof(DateFormatAttribute), typeof(DateFormatValidator)); 
    

  • 甲dd客户端上的验证功能。请注意,这必须在用户的区域设置中实现。以下是荷兰(NL-NL,NL-BE)客户端验证功能:
  • 
        /* 
        * Localized default methods for the jQuery validation plugin. 
        * Locale: NL 
        */ 
        jQuery.extend(jQuery.validator.methods, { 
         date: function(value, element) { 
          return this.optional(element) || /^\d\d?[\.\/-]\d\d?[\.\/-]\d\d\d?\d?$/.test(value); 
         } 
        }); 
    

    这应该涵盖的东西...

    +0

    +1很不错,完整的解释 – 2010-09-06 01:19:24

    +0

    我还没试过,但看起来不错。问题:由于新属性没有添加DataType(DataType.Date)属性在服务器端尚未执行的任何操作,是否可以扩展该属性? – Josh 2010-09-07 13:24:23

    +0

    还没有尝试过,但可能会工作... – maartenba 2010-09-08 07:41:01

    0

    我遇到了同样的问题,找不到解决方案。我不相信每个人都没有遇到这个问题。我使用的是jquery.maskedinput.js模块,它工作的很好,但是当我开始添加“[DataType(DataType.Date)]”的时候,如果将datetime输入分配给class =“text-box单线”。添加这个类打破了maskedinput js。 它还将我的较低日期格式设置为“2/3/1010”,然后我的jquery掩码为“99/99/9999”。

    1

    乔希,

    你的问题是在MVC,这是该模型绑定器正试图从形式到模型绑定输入值,一个相当普遍的问题。显然,如果它不适合,你会马上得到一个错误。

    那么如何让模型绑定器使用我的自定义验证?并返回我的错误信息?嗯,先读一下phil haack写的东西吧。那么你有你的自定义验证。

    接下来的事情是。不要在你的模型中使用整数和日期时间! 如果用户可以在文本框中输入任何他想要的内容,这总会带来问题。

    你应该做的是做一个你的对象的flatObject。

    flatObject很简单。这是一个对象,里面的变量的精确副本,只有中,瞬时和日期时间是字符串(COS那些总是在ModelBinder的绑定)

    例如:

    namespace MVC2_NASTEST.Models { 
    
        public partial class FlatNieuw { 
         public int Niw_ID { get; set; } 
         public string Niw_Datum { get; set; } 
         public string Niw_Titel { get; set; } 
         public string Niw_Bericht { get; set; } 
         public int Niw_Schooljaar { get; set; } 
         public bool Niw_Publiceren { get; set; } 
        } 
    } 
    

    唯一的整数我有距离下拉,如果下拉列表中的值是整数,则这些不会失败。 日期(数据)是一个字符串。我做这个字符串的自定义验证。 modelbinder绑定到此FlatNieuw对象。

    我的Nieuw类与这个类具有完全相同的字段名称。所以当你使用UpdateModel()时,这仍然有效。 如果您正在创建新条目,则可以使用automapper将此flatObject映射到正常的Object。

    我认为这件事,连同phil haack的博客应该给你一个如何做到这一点的手。如果你有问题不要犹豫,问。

    0

    根据我的经验,有些时候Microsoft MVC验证或jQuery验证对于我们正在开发的一些项目来说是过度杀手。这就是为什么有时候我自己编码/抓小的。

    解决方法一: 自定义插件(你可以把它变成适合你的方式)

    (function($) { 
        $.fn.extend({ 
          ValidateInput: function() { 
           var bValid = true; 
           this.removeClass('ui-state-error'); 
           this.each(function() { 
            if ($(this).hasClass('date')) { 
    
              var valdate = checkRegexp($(this), /^(([0-2]\d|[3][0-1])\/([0]\d|[1][0-2])\/[1-2]\d{3})$/, "date format is wrong, please input as dd/MM/yyyy, e.g. 02/28/2010"); 
              if (!valdate) { 
               $(this).val("input in 'dd/mm/yyyy' format"); 
              } 
              bValid = bValid && valdate; 
           return bValid; 
    
             } 
           }); 
    
        }}); 
    
        function checkRegexp(o, regexp, n) { 
         if (!(regexp.test(o.val()))) { 
          o.addClass('ui-state-error'); 
          //updateTips(n); 
          return false; 
         } else { 
          return true; 
         } 
         } 
    
    })(jQuery); 
    

    您的看法:

    1. 添加类= '日期' 您输入 方框
    2. 调用插件 $("#yourInput").alidateInput();

    解决方案2:使用jQuery UI日期拾取(我现在使用的解决方案)的解决方案2

     <script language="javascript" type="text/javascript"> 
          $(function() { 
    // use date picker to your textbox input 
           $(".yourInput").datepicker(); 
           $(".yourInput").datepicker('option', { dateFormat: "dd/mm/yy" }); 
    // disable any human input to the textbox input 
           $(".yourInput").keyup(function() { 
            $(this).val(""); 
           }); 
          }); 
         </script> 
    

    更多详细信息:http://www.gregshackles.com/2010/03/templated-helpers-and-custom-model-binders-in-asp-net-mvc-2/