代码之家  ›  专栏  ›  技术社区  ›  Josh

MVC2客户端验证日期时间?

  •  8
  • Josh  · 技术社区  · 14 年前

    在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" />
    

    我可以使用microsoftmvc验证或jQuery验证。如何获取用于验证客户端的DateTime?

    我意识到DataTypeAttribute所做的只是提供格式化提示,实际上并不做任何验证(它将这部分留给ModelBinder)。

    4 回复  |  直到 14 年前
        1
  •  4
  •   maartenba    14 年前

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

    我会这样做:


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

    
        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:
    
        DataAnnotationsModelValidatorProvider
            .RegisterAdapter(typeof(DateFormatAttribute), typeof(DateFormatValidator));
    

    1. 在客户端上添加验证函数。请注意,这必须根据用户的区域设置来实现。以下是荷兰语(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);
            }
        });
    

    应该包括。。。

        2
  •  1
  •   Stefanvds    14 年前

    乔希,

    您的问题是MVC中的一个常见问题,即modelbinder试图将表单中输入的值绑定到模型中。显然,如果它不适合你,你会马上得到一个错误。

    好吧,先读一下菲尔·哈克写的东西。然后你有你的自定义验证。

    你应该做的是,把你的物体做成一个平面物体。

    平面物体很简单。它是一个对象,是内部变量的精确副本,只是inst和datetimes是字符串(因为它们总是绑定在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映射到普通对象。

    我认为这一点,连同菲尔哈克的博客应该给你一个如何做到这一点的手。如果你有问题,不要犹豫问。

        3
  •  0
  •   Terrence    14 年前

    我遇到同样的问题,找不到解决办法。我不敢相信每个人都没有碰到这个问题。我用的是jquery.maskedinput.js 模块,它工作得很好,但是当我开始添加“[数据类型(DataType.Date)]如果为日期时间输入分配class=“text box single line”类,则使用“EditorFor”修饰。添加这个类会破坏maskedinput js。

        4
  •  0
  •   D.J    14 年前

    根据我的经验,对于我们正在开发的一些项目来说,有时microsoftmvc验证或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();

    解决方案2: 使用jqueryui日期选择(我现在使用的解决方案)

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