2014-12-30 2 views
0

У меня есть следующий ViewModel:Модель проверки не работает со всеми свойствами

public class MyViewModel:IValidatableObject 
    { 
     public int Id { get; set; } 

     public string Name { get; set; } 

     public DateTime? Birthday { get; set; } 

     public int Status { get; set; } 

     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
     { 
      if (string.IsNullOrWhiteSpace(Name)) 
       yield return new ValidationResult("Please fill the name", new string[] { "Name" }); 

      if (Birthday.HasValue == false) 
       yield return new ValidationResult("Please fill the birthday", new string[] { "Birthday" }); 

      if(Status <= 0) 
       yield return new ValidationResult("Please fill the status", new string[] { "Status" }); 
     } 
    } 

Контроллер:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Create([Bind(Include = "Id,Name,Birthday,Status")] MyViewModel myViewModel) 
{ 
    if (ModelState.IsValid) 
    { 
     db.MyViewModels.Add(myViewModel); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(myViewModel); 
} 

Я хотел бы, чтобы отобразить все сообщения проверки в то же время, однако он показывает первый статус, а затем два других свойства.

enter image description here

enter image description here

ответ

1

Это связано с порядком, в котором происходит проверка. Сначала ModelBinder выполняет свою работу, и если это пройдет, поскольку вы создали самомодифицируемую модель просмотра, реализуя IValidatableObject, вызывается метод Validate. На первом скриншоте процесс привязки модели не работает, поэтому Validate никогда не вызывается. Во втором скриншоте модельная привязка преуспевает, но Validate() терпит неудачу.

Вы можете решить эту проблему с помощью DataAnnotations вместо реализации IValidatableObject так:

public class MyViewModel:IValidatableObject 
    { 
     public int Id { get; set; } 
     [Required] 
     public string Name { get; set; } 
     [Required] 
     public DateTime Birthday { get; set; } 
     [Required, Range(0, Int32.MaxValue)] 
     public int Status { get; set; } 
    } 
+0

Можно ли добиться того же результата, сохраняя IValidatableObject? –

+0

Если вы выполнили всю свою проверку с помощью метода Validate(), да. Просто сделайте все свойства на viewmodel необязательными и напишите свои правила в Validate(). – joelmdev

+0

изменение на публичный int? Статус {get; задавать; } Он отображает только сообщения о подтверждении имени и дня рождения. Пс: Вся моя проверка выполняется с использованием Valida из IValidatableObject –