2016-04-15 73 views
0

來自winforms,我對MVC和學習很陌生。所以請耐心等待。 我試圖在MVC中以正確的方式做一些驗證。我有一些使用JS的代碼,但我想修改它以使用MVC進行驗證。MVC中對DateTime的驗證

這是我的模型

public class MyViewModel 
{ 

    /// <summary> 
    /// Start Date 
    /// </summary> 
    [DataType(DataType.Date)] 
    [DisplayFormat(DataFormatString = "{0:d}",ApplyFormatInEditMode=true)] 
    [Display(ResourceType = typeof(UIResources.GeneralPurpose), Name = "StartDate")] 
    public DateTime StartDate { get; set; } 

    /// <summary> 
    /// End Date 
    /// </summary> 
    [DataType(DataType.Date)] 
    [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)] 
    [Display(ResourceType = typeof(UIResources.GeneralPurpose), Name = "EndDate")] 
    public DateTime EndDate { get; set; } 
} 

這是我的HTML的外觀

@model MyViewModel 
@using ... 
{ 
    <div id="ErrMsg" class="validation-summary-errors center"> 
    </div> 

    using (Ajax.BeginForm("someAction", "someController", new AjaxOptions())) 
    { 

     @Html.ValidationSummary() 

     <fieldset class="control-set-container no-border"> 
      <ul class="undecorated-list inline-list-items"> 
       <li> 
        @Html.LabelFor(model => model.StartDate) 
        @Html.MyDateTimePicker(model => model.StartDate) 
       </li> 
       <li> 
        @Html.LabelFor(model => model.EndDate) 
        @Html.MyDateTimePicker(model => model.EndDate) 
       </li> 
      </ul> 
     </fieldset> 
    } 

@ Html.MyDateTimePicker寫一些HTML,讓出一個文本框和日期選擇控件(文本框用於以某種日期格式顯示日期)。

這裏就是我試圖驗證,

  1. 如果日期是不正確的格式(DD/MM/YYYY),該errMsg.Html應設置在視圖模型中指定的消息。
  2. 如果startDate大於endDate,則在errMsg.Html中顯示消息。
  3. 雖然我在這裏,但我想驗證日期是否是2種不同格式(dd/MM/yyyy或M/d/yyyy)中的一種,當驗證失敗時顯示錯誤消息。
+0

首先,您需要'@ Html.ValidationMessageFor(m => m.StartDate)'來顯示驗證錯誤消息。 (1)如果你想覆蓋一個無效值的默認錯誤信息,請參考[這個答案](http://stackoverflow.com/questions/6214066/how-to-change-default-validation-error-message-in -Asp淨MVC)。 (2)使用[萬無一失](http://foolproof.codeplex.com/)'[GreaterThan]'或類似的條件驗證屬性。 (3)不可能 - 如果您允許這兩種格式,那麼控制器將如何知道「16/04/2016」是否是有效日期。 –

+0

但是你沒有顯示MyDateTimePicker()的代碼,所以我們不可能知道這是否生成了正確的html,並且具有客戶端驗證所需的適當'data-val- *'屬性。並且在'DisplayFormatAttribute'中包含'ApplyFormatInEditMode = true'是沒有意義的,因爲它只在'EditorFor()'方法中受到尊重,並且它需要是'DataFormatString =「{0:yyyy-MM-dd}」'反正工作。 –

回答

-1
function checkdate(input) { 

    //var validformat = /^\d{4}\-\d{2}\-\d{2}$/; 
    var validformat = /^(\d{4})-(\d{2})-(\d{2})$/; //Basic check for format validity 
    if (input.val() != "") { 
     if (!validformat.test(input.val())) 
      return false; 
     else { //Detailed check for valid date ranges 
      var monthfield = input.val().split("-")[1]; 
      var dayfield = input.val().split("-")[2]; 
      var yearfield = input.val().split("-")[0]; 
      var dayobj = new Date(yearfield, monthfield - 1, dayfield); 
      if ((dayobj.getMonth() + 1 != monthfield) || (dayobj.getDate() != dayfield) || (dayobj.getFullYear() != yearfield)) 
      //alert("Invalid Date Format."); 
       return false; 
      else 
       return true; 
     } 
    } 
    else { 
     return true; 
    } 

} 

的paramiter值 '輸入' 將日期時間控制的對象

var obj=$('#txtDatetime'); 

要驗證Call - CheckDate(obj);

+0

你甚至讀過這個問題嗎?該OP是不是要求JavaScript驗證(甚至不在標籤) – Jcl

+0

我已經有JS,不尋找更多的JS。 MVC主要圍繞保持視圖儘可能簡單。 –

+0

好的,更好的使用數據註解 \t 應用DataAnnotation像: [DisplayFormat(DataFormatString = 「{0:MMM DD,YYYY}」)] – Aswini

1

MVC允許YOUT創建自定義屬性驗證,通過使用要麼是Remote屬性,要麼通過創建新屬性。

Remote屬性允許您在字段驗證期間讓jquery發送一個Ajax調用指定的方法,當onfocusout事件將被拋出。

例如,我有我的UserController的方法,該方法可以確保在應用程序相同的用戶ID不使用兩次:

[Remote("UnicityUserId", "User", ErrorMessageResourceName = "ErrorUnicity", ErrorMessageResourceType = typeof(Resources.Resources), AdditionalFields = "ID")] 
public string UserId {get;set;} 

然後,在我的控制器:

public JsonResult UnicityUserId(string UserId, string ID) 
{ 
    int id = 0; 
    Int32.TryParse(ID, out id); 
    bool ok = false; 

    if (!String.IsNullOrEmpty(UserId)) 
     ok = !UserDb.Exist(this.db, this.Tracer, UserDb.UserId, UserId, id); //Checks wether there is already another user with the same UserId 

    return (Json(ok, JsonRequestBehavior.AllowGet)); 
} 

更多info here

當MVC收到您的POST數據並嘗試將其綁定到您的模型時,將執行其他驗證模式。

對於這種方法,您將不得不創建自己的屬性。

仍從單一性例如:

public class UnicityAttribute : ValidationAttribute 

這個類必須實現一個名爲IsValid方法,將執行驗證並返回ValidationResult到MVC的模型綁定器

爲了確保MVC會調用它,只需將屬性放在您的字段上:

[UnicityAttribute] 
public string UserId {get;set;} 

更多信息here

+0

感謝您的鏈接骨髓。拋開簡單的驗證,我注意到鏈接中的示例提到了服務器端驗證(而不必刷新整個頁面)。這是典型的MVC使用C#和MVC服務器端驗證,而不是客戶端使用JS?所以總是有回電話給服務器。 –

+0

我知道它是否是典型的,但是讓服務器端驗證使得代碼更容易閱讀(View包含更少的JS),並且很多事情在C#中比在JS中更容易管理(日期,小數等。 )。 –

0
enter code here 
using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Web.Mvc; 

namespace Attributes 
{ 
    [AttributeUsage(AttributeTargets.Property)] 
    public sealed class MinimumPaymentDateAttribute : ValidationAttribute, IClientValidatable 
    { 
     private readonly string errorMessage; 
     public string ValidationErrorMessage { get { return errorMessage; } } 
     /// <summary> 
     /// Constructor for intializing variables 
     /// </summary> 
     public MinimumPaymentDateAttribute() 
     { 
     } 

     /// <summary> 
     /// Constructor for intializing variables 
     /// </summary> 
     /// <param name="validationErrorMessage"></param> 
     public MinimumPaymentDateAttribute(string validationErrorMessage) 
     { 
      this.errorMessage = validationErrorMessage; 
     } 
     /// <summary> 
     /// Validation for of Rule implement Client Validation 
     /// </summary> 
     /// <param name="value"></param> 
     /// <param name="validationContext"></param> 
     /// <returns></returns> 
     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      if (null != validationContext) 
      { 
       PaymentInformation paymentInfo = (PaymentInformation)validationContext.ObjectInstance; 
       if (value != null && validationContext != null) 
       { 
        if (paymentInfo.PaymentDate < paymentInfo.MinDate) 
        { 
         return new ValidationResult(this.ValidationErrorMessage); 
        } 
       } 
      } 
      return ValidationResult.Success; 
     } 

     /// <summary> 
     /// Validation rules client side for Minimum Date 
     /// </summary> 
     /// <param name="metadata"></param> 
     /// <param name="context"></param> 
     /// <returns>IEnumerable<ModelClientValidationRule></returns> 
     public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
     { 
      string errorMessage = this.FormatErrorMessage(metadata.DisplayName); 
      ModelClientValidationRule MinDateRule = new ModelClientValidationRule(); 
      DateTime? validationData = GetValidationParameters(context.Controller.ViewData.Model); 
      MinDateRule.ErrorMessage = errorMessage; 
      MinDateRule.ValidationType = "validminpaymentdate";(Java script function name) 
      MinDateRule.ValidationParameters.Add("mindate", validationData); 
      yield return MinDateRule; 
     } 


     /// <summary> 
     /// Checking for Model type for handling Different ViewData 
     /// </summary> 
     /// <param name="model"></param> 
     /// <returns>string[]</returns> 
     private static DateTime? GetValidationParameters(object model) 
     { 
      DateTime? MinDate=null; 
      if (model.GetType() == typeof(PaymentInformation)) 
      { 
       PaymentInformation obj = (PaymentInformation)model; 
       return obj.MinDate; 
      } 
      else if (model.GetType() == typeof(PaymentViewModel)) 
      { 
       PaymentViewModel obj = (PaymentViewModel)model; 
       return obj.PaymentInfo.MinDate; 
      } 
      return MinDate; 
     } 
    } 
} 


$.validator.addMethod("validminpaymentdate", function (value, element, params) { 
    var valid = true; 
    var mindate = new Date(params); 
    var valdate = new Date(value); 
    if (valdate < mindate) { 
     valid = false; 
    } 
    return valid; 

}); 
$.validator.unobtrusive.adapters.addSingleVal("validminpaymentdate", "mindate");