2016-08-10 37 views
2

我想了解如何將數據傳遞給我創建的自定義驗證。試圖瞭解如何將變量傳遞給CustomValidation?

我有這個模型。

public class MyModel 
{ 
    [Required(ErrorMessage="Please enter a Start Date")] 
    public DateTime StartDate { get; set; } 

    [Required(ErrorMessage="Please enter an End Date")] 
    [CustomValidation(typeof(DateCompareValidation), "ValidateDates")] 
    public DateTime EndDate { get; set; } 
} 

這是我的驗證器。

public class DateCompareValidation 
{ 
    public static ValidationResult ValidateDates(object value, ValidationContext context) 
    { 
     return new ValidationResult("You are wrong"); 
    } 
} 


我第一次有公共靜態的ValidationResult ValidateDates()和它出錯了對

"..must match the expected signature: public static ValidationResult ValidateDates(object value, ValidationContext context)." 

所以我加了必要的參數。

現在調試類我看到變量「值」有我的結束日期。
我不太明白它是如何知道它需要什麼參數的。
此外,我想知道如何通過開始日期或MyModel類,以便我可以在我的驗證邏輯上工作?

+0

你想讓你屬性做什麼?比較'DateTime'是否大於'StartDate'? –

+0

是的。在這種特殊情況下,我只想確保輸入有效的日期範圍。一旦我明白了這一切的作品,我可能需要編寫更復雜的驗證器。 – PrivateJoker

+0

我建議你閱讀[在ASP.NET MVC 3驗證完整指南 - 第2部分](http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp。淨-MVC -3-部分-2) –

回答

0

什麼只是增加了邏輯的類並實現IValidateObject?

public class MyClass : IValidatableObject 
    { 
     [Required(ErrorMessage="Please enter a Start Date")] 
     public DateTime? StartDate { get; set; } 

     [Required(ErrorMessage="Please enter an End Date")] 
     public DateTime? EndDate { get; set; } 

     public IEnumerable<ValidationResult> Validate(ValidationContext context) 
     { 
      if (EndDate < StartDate) 
      { 
       yield return new ValidationResult("Invalid date range: End date must be greater then the Start Date"); 
      } 
     } 
} 
0

這可能會幫助你。

class CustomLengthValidatorAttribute : ValidationAttribute 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="CustomLengthValidatorAttribute" /> class. 
    /// </summary> 
    /// <param name="maxLength">The maximum length.</param> 
    public CustomLengthValidatorAttribute(int maxLength) 
    { 
     this.MaxLength = maxLength; 
    } 

    /// <summary> 
    /// Gets the minimum length. 
    /// </summary> 
    /// <value> 
    /// The minimum length. 
    /// </value> 
    public int MaxLength { get; private set; } 

    /// <summary> 
    /// Validates the specified value with respect to the current validation attribute. 
    /// </summary> 
    /// <param name="value">The value to validate.</param> 
    /// <param name="validationContext">The context information about the validation operation.</param> 
    /// <returns> 
    /// An instance of the <see cref="T:System.ComponentModel.DataAnnotations.ValidationResult" /> class. 
    /// </returns> 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     string fieldName = validationContext.MemberName; 
     if (Convert.ToString(value).Trim().Length > this.MaxLength) 
     { 
      return new ValidationResult(this.ErrorMessage = fieldName + " should not be longer than " + this.MaxLength + " character"); 
     } 

     return ValidationResult.Success; 
    } 
} 
0

雖然它不preciselly回答你的問題,我建議你看一看FluentValidation。 它可以用流利的語法接口(使用用戶定義的驗證器類)完全替換內置的ASP.NET MVC基於屬性的驗證。

例如,如果你想驗證StartDate preceeds EndDate,它可能看起來像:

// validator class for your view model 
public class MyModelValidator : AbstractValidator<MyModel> 
{ 
    public MyModelValidator() 
    { 
     RuleFor(m => m.EndDate).NotNull().WithMessage("Please enter an End Date"); 
     RuleFor(m => m.StartDate).NotNull().WithMessage("Please enter a Start Date") 
      .LessThan(m => m.EndDate).WithMessage("Start Date must preceed End Date"); 
    } 
} 

// declare MyModelValidator as a validator for view model 
[Validator(typeof(MyModelValidator))] 
public class MyModel 
{ 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
} 

如果你有興趣嘗試一下,一定要拿到FluentValidation.MVC5(或適用於您正在使用的MVC版本,在寫這篇文章的時候FluentValidation.MVC6在Beta)nuget。所有你必須然後在Global.asax中註冊它,像這樣:

protected void Application_Start() 
{ 
    ... 
    FluentValidationModelValidatorProvider.Configure(); 
}