8

您推荐什么方法在 MVC 的客户端验证 DateTime?

假设我有一个模型,其属性名为DateOfBirtha 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

4 回答 4

4

如上所述,请关注 Phil Haack 关于自定义验证的帖子: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;
      }
    }

  1. 添加一个“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 };
      }
    }

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

那应该涵盖的东西...

于 2010-09-03T13:07:51.727 回答
1

乔希,

您的问题在 MVC 中是一个很常见的问题,即模型绑定器试图将输入的值从表单绑定到模型中。显然,如果它不“适合”,您将立即收到错误消息。

那么如何让模型绑定器使用我的自定义验证呢?并返回我的错误信息?

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

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

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

flatObject 非常简单。它是一个对象,是内部变量的精确副本,只有 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; }
    }
}

我唯一的整数来自下拉列表,因为如果下拉列表中的值是整数,那些不会失败。日期(datum)是一个字符串。我对此字符串进行自定义验证。modelbinder 绑定到此 FlatNieuw 对象。

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

我认为这与 phil haack 的博客一起应该可以帮助您了解如何做到这一点。如果您有问题,请不要犹豫。

于 2010-09-06T08:13:19.810 回答
0

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

于 2010-08-17T19:38:25.317 回答
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();

解决方案2:使用Jquery UI Date Pick(我现在使用的解决方案)

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

于 2010-09-09T05:16:26.377 回答