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/