如何在Model字段中添加其他验证?

时间:2014-12-16 07:10:19

标签: c# asp.net-mvc validation

我还有第二件事:

<td>
    @Html.LabelFor(m => m.Number, titleHtmlAttrs)
</td>
<td>
    <span class="element-value2">
        @Html.EditorFor(m => m.Number)
        @Html.ValidationTooltipFor(m => m.Number)
    </span>
</td>

这就是这个领域在模型中的样子:

[Display(Name = "Special Number")]
[StringLength(20)]
public string Number { get; set; }

这意味着如果我想更改此字段,我可以将任何值从空到20。 没关系,但现在我需要额外的验证。 在模型中我有一些领域:

public DateTime? TimeOf { get; set; }
public bool HasType { get; set; }

如果TimeOf不为null且HasType为true,则新验证应该 ONLY 。新验证应该防止Number中的空值。基本上,改变(从空到20)到(从1到20)。

我怎样才能正确地完成这个?

P.S抱歉我的英语不好。

2 个答案:

答案 0 :(得分:2)

对于复杂的验证逻辑,请查看ViewModel中的实施IValidatableObject,然后将条件验证逻辑放在Validate方法中。 (警告,这显然是服务器端)

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (this.HasType)
    {
       // Do other conditional validation
       if (validationFails)
       {
           yield return new ValidationResult("descriptive error goes here");
       }
    } 
    // Other validation here.

答案 1 :(得分:0)

更新 我似乎误解了这个问题。正如另一个答案已经指出的那样,您可以实现IValidatableObject来实现此目的。类似的东西:

public class YourModelName : IValidatableObject
{
  [StringLength(20)]
  public string Number{ get; set; }

  [Required]
  public DateTime? TimeOf { get; set; }

  public bool HasType { get; set; }

  public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
  { 
    var results = new List<ValidationResult>();

    if (TimeOf != null && HasType)
       Validator.TryValidateProperty(this.Number,
            new ValidationContext(this, null, null) { MemberName = "Number" },
            results);    

    if (TimeOf == null) 
       results.Add(new ValidationResult("Date Time must have a value"));
    if (!HasType)
       results.Add(new ValidationResult("Must be true"));

    return results;
  }

}

OLD ANSWER: 您可以为更复杂的验证条件编写自定义验证器。类似的东西:

public class SomeCustomValidator : ValidationAttribute
{
   protected override ValidationResult IsValid(object value, ValidationContext validationContext)
   {
      string number = value as string;
      if (value == null) throw new InvalidOperationException("Can only be used on string properties");

      if (!value.IsEmpty && value.Length <= 20)
      {
          return ValidationResult.Success;
      }

      return new ValidationResult("Name must be a non-empty string smaller than 20 chars"));
   }
}

对于HasType,另一个自定义的:

public class IsTrueAttribute : ValidationAttribute
{

  public override bool IsValid(object value)
  {
      if (value == null) return false;
      if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties.");

      return (bool) value == true;
  }

}

在TimeOf上,您可以使用required属性来确保它具有值:

[Required(ErrorMessage="Must have value")]
public DateTime? TimeOf {get;set;}

并在另外两个上使用自定义属性:

[SomeCustomValidator(ErrorMessage="Error msg...")]
public string Number {get;set;}

[IsTrueAttribute(ErrorMessage="Must be true")]
public bool HasType {get;set;}