简体   繁体   English

MVC2客户端验证DateTime吗?

[英]MVC2 Client-side validation for a DateTime?

What approach do you recommend for validating a DateTime on the client side in MVC? 您建议使用哪种方法在MVC的客户端上验证DateTime?

Let's say I have a model with a property named DateOfBirth that is a DateTime , like so. 假设我有一个带有名为DateOfBirth的属性的模型,该属性是一个DateTime ,就像这样。

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

On the View, I have a simple 在视图上,我有一个简单的

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

I can use either the Microsoft MVC validations or the jQuery validations. 我可以使用Microsoft MVC验证或jQuery验证。 How do I get the DateTime to validate client-side? 如何获取DateTime以验证客户端?

I realize all the DataTypeAttribute does is provide formatting hints and doesn't really do any validation (it leaves that part to the ModelBinder). 我意识到DataTypeAttribute所做的所有事情都是提供格式提示,并且实际上并没有做任何验证(它将这部分留给了ModelBinder)。

Basically I want to duplicate what the ModelBinder does when it tries to put the posted value into the model's DateOfBirth property. 基本上,我想复制ModelBinder尝试将发布的值放入模型的DateOfBirth属性时的操作。

What are your recommendations? 您有什么建议?

As suggested above, follow Phil Haack's post on custom validations: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx 如上所述,请遵循Phil Haack关于自定义验证的文章: http : //haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

Here's how I would do it: 这是我的处理方式:


  1. Add a "DateFormatAttribute" class, like so: 添加一个“ 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. Add a "DateFormatValidator" class, like so: 添加一个“ 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. Register the above classes somewhere in Global.asax.cs: 在Global.asax.cs中的某处注册上述类:

    DataAnnotationsModelValidatorProvider
        .RegisterAdapter(typeof(DateFormatAttribute), typeof(DateFormatValidator));

  1. Add a validation function on the client. 在客户端上添加验证功能。 Note that this will have to be implemented attributng the locale of the user. 请注意,这必须在用户的语言环境中实现。 The following is a Dutch (nl-NL, nl-BE) client-side validation function: 以下是荷兰语(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);
        }
    });

That should cover things... 那应该涵盖...

Josh, 乔希

your problem is quite a common problem in MVC, which is that the modelbinder is trying to BIND the inputted values from the form into the model. 您的问题是MVC中的一个普遍问题,这是Modelbinder试图将输入的值从表单绑定到模型中。 obviously, if it doesnt 'fit' you'll get an error straight away. 显然,如果它不适合,您将立即得到一个错误。

so how do I make the modelbinder use my custom validation? 那么如何使Modelbinder使用我的自定义验证? and return my error message? 并返回我的错误信息?

well, first read and do the things written by phil haack. 好吧,首先阅读并做由phil haack写的事情。 then you have your custom validation. 那么您就可以进行自定义验证了。

the next thing is. 接下来是。 dont use Integers and datetimes in your model! 不要在模型中使用整数和日期时间! If the user can input whatever he wants in a textbox, this always will give problems. 如果用户可以在文本框中输入任何内容,这总是会带来问题。

what you should do is, make a flatObject of your object. 您应该做的是,使对象成为flatObject。

a flatObject is pretty simple. flatObject非常简单。 It's an object, an exact copy of the variables inside, only, the inst and datetimes are strings (cos those always bind in the modelbinder) 它是一个对象,内部变量的精确副本,仅inst和datetimes是字符串(cos始终绑定在modelbinder中)

example: 例:

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

the only ints i have are from the dropdowns, cos those dont fail, if the value in the dropdowns are ints. 我唯一的整数是来自下拉列表,因为下拉列表中的值是整数,所以这些不会失败。 the date (datum) is a string. 日期(基准)是一个字符串。 i do the custom validation on this string. 我对此字符串进行自定义验证。 the modelbinder binds to this FlatNieuw object. modelbinder绑定到此FlatNieuw对象。

my Nieuw class has exactly the same names of fields as this class. 我的Nieuw类具有与该类完全相同的字段名称。 so when you are using UpdateModel() this still works. 因此,当您使用UpdateModel()时,此方法仍然有效。 if you are making a new entry, you can use automapper to map this flatObject to your normal Object. 如果要输入新条目,则可以使用自动映射器将此flatObject映射到普通对象。

i think this, together with phil haack's blog should give you a hand on how to do this. 我认为,这与phil haack的博客一起应该可以帮助您实现这一目标。 if you have questions dont hesitate to ask. 如果您有任何疑问,请随时提出。

I am up against the same issue and can not find a solution. 我遇到了同样的问题,无法找到解决方案。 I can't believe everyone has not run into this issue. 我无法相信每个人都没有遇到这个问题。 I was using the jquery.maskedinput.js module and it worked great, but when I started adding the "[DataType(DataType.Date)]" decoration with "EditorFor" if assigns the datetime input a class of class="text-box single-line". 我正在使用jquery.maskedinput.js模块,但效果很好,但是当我开始使用“ EditorFor”添加“ [DataType(DataType.Date)]”修饰时,如果为日期时间输入分配了class =“ text-box”类单线”。 Adding this class breaks the maskedinput js. 添加此类会破坏maskedinput js。 It also formats my lower dates as "2/3/1010" which then blows my jquery mask of "99/99/9999". 它还将我的低日期格式设置为“ 2/3/1010”,然后将我的jquery掩码改为“ 99/99/9999”。

according to my experience some times either Microsoft MVC validations or the jQuery validations is a over kill for some projects that we are developing. 根据我的经验,对于我们正在开发的某些项目,无论是Microsoft MVC验证还是jQuery验证都是过分的。 that is why some times i code/grab small ones by my self. 这就是为什么有时候我会自己编写/抓取小代码的原因。

Solution One: Custom plugin(you can change it into the way suits you) 解决方案一:自定义插件(您可以将其更改为适合您的方式)

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

on your view: 在您看来:

  1. add class='date' to your input box 在您的输入框中添加class ='date'
  2. call the plugin $("#yourInput").alidateInput(); 调用插件$("#yourInput").alidateInput();

Solution 2: Use Jquery UI Date Pick (the solution i am using now) 解决方案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>

More Details on Solution 2: http://www.gregshackles.com/2010/03/templated-helpers-and-custom-model-binders-in-asp-net-mvc-2/ 解决方案2的详细信息: http : //www.gregshackles.com/2010/03/templated-helpers-and-custom-model-binders-in-asp-net-mvc-2/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM