MVC2 DateTime的客户端验证?

时间:2010-08-14 21:41:44

标签: javascript datetime asp.net-mvc-2 asp.net-mvc-2-validation client-side-validation

您建议使用什么方法在MVC中验证客户端的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" />

我可以使用Microsoft MVC验证或jQuery验证。如何让DateTime验证客户端?

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

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

你有什么建议?

4 个答案:

答案 0 :(得分:4)

如上所述,请按照Phil Haack关于自定义验证的帖子:http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

我将如何做到这一点:


  1. 添加“DateFormatAttribute”类,如下所示:
  2. 
        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;
          }
        }
    

    1. 添加“DateFormatValidator”类,如下所示:
    2. 
          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 };
            }
          }
      

      1. 在Global.asax.cs中注册上述类:
      2. 
            DataAnnotationsModelValidatorProvider
                .RegisterAdapter(typeof(DateFormatAttribute), typeof(DateFormatValidator));
        

        1. 在客户端上添加验证功能。请注意,这必须在实现用户的区域设置时实现。以下是荷兰语(nl-NL,nl-BE)客户端验证功能:
        2. 
              /*
               * 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);
                  }
              });
          

          那应该涵盖的事情......

答案 1 :(得分:1)

乔希,

你的问题在MVC中是一个非常普遍的问题,即模型绑定器试图将输入的值从表单绑定到模型中。很明显,如果它“不合适”,你会马上得到一个错误。

那么如何让modelbinder使用我的自定义验证呢?并返回我的错误消息?

好吧,首先阅读并做一些由phil haack写的东西。然后你有自定义验证。

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

你应该做的是,制作你对象的flatObject。

flatObject非常简单。它是一个对象,内部变量的精确副本,只有,inst和datetimes是字符串(因为它们总是在模型绑定器中绑定)

示例:

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; }
    }
}
如果下拉列表中的值是整数,那么我所拥有的唯一一个是来自下拉列表,因为那些不会失败。 date(datum)是一个字符串。我对此字符串进行自定义验证。 modelbinder绑定到此FlatNieuw对象。

我的Nieuw类与此类具有完全相同的字段名称。因此,当您使用UpdateModel()时,这仍然有效。 如果要创建新条目,则可以使用automapper将此flatObject映射到普通对象。

我认为这与phil haack的博客一起应该让你知道如何做到这一点。如果您有任何疑问,请不要犹豫。

答案 2 :(得分:0)

我遇到了同样的问题,无法找到解决方案。我不敢相信每个人都没有遇到过这个问题。我正在使用jquery.maskedinput.js模块并且效果很好,但是当我开始使用“EditorFor”添加“[DataType(DataType.Date)]”装饰时,如果为datetime输入分配了一个class =“text-box单线”。添加此类会破坏maskedinput js。 它还将我的较低日期格式化为“2/3/1010”,然后将我的jquery面具吹成“99/99/9999”。

答案 3 :(得分: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. 将class ='date'添加到您的输入中 框
  2. 调用插件 $("#yourInput").alidateInput();
  3. 解决方案2:使用Jquery UI日期选择(我现在使用的解决方案)

         <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>
    

    有关解决方案2的更多详细信息:http://www.gregshackles.com/2010/03/templated-helpers-and-custom-model-binders-in-asp-net-mvc-2/