2010-07-24 4 views
0

У меня есть приложение Asp.NET MVC, в котором я использую аннотации данных для добавления проверки в некоторых областях:DataAnnotations [Требуется] Атрибут не вызывает исключений быть выброшен

[Required] 
    [DisplayName("Course Name")] 
    string Name { get; set; } 

Однако это не кажется работать так, как я ожидал. В принципе Если на странице есть какие-либо другие ошибки, которые я вручную проверяю и выкидываю новое RuleViolation(), то требуемое нарушение показано в резюме проверки. Если требуемое нарушение является единственной ошибкой, то оно не отображается.

Мой контроллер имеет этот код в нем:

 catch (Exception ex) 
     { 
      ModelState.AddModelError("", ex.Message); 
      ModelState.AddRuleViolations(courseViewModel.Course.GetRuleViolations()); 
      return View(courseViewModel); 
     } 

Но учитывая, что требуемое нарушение не бросать, я никогда не хожу сюда.

Нужно ли мне что-то делать, что я не знаю об ошибках, вызванных нарушением DataAnnotation?

Спасибо за любую помощь

Edit:

Вот действие контроллера:

[HttpPost] 
    [ValidateInput(true)] 
    public ActionResult Edit(int id, CourseViewModel courseViewModel) 
    { 

     var oldCourse = _eCaddyRepository.GetCourse(id); 

     if (courseViewModel.Course == null) 
     { 
      return View("NotFound", string.Format("Course {0} Not Found", id)); 
     } 

     try 
     { 
      courseViewModel.Update(oldCourse); 
      _eCaddyRepository.SubmitChanges(); 

      return RedirectToAction("Index", "Course"); 
     } 
     catch (Exception ex) 
     { 
      ModelState.AddModelError("", ex.Message); 
      ModelState.AddRuleViolations(courseViewModel.Course.GetRuleViolations()); 
      return View(courseViewModel); 
     } 
    } 

Где Обновление:

public class CourseViewModel : BaseViewModel 
{ 
    public Course Course { get; set; } 

    public void Update(Course oldCourse) 
    { 
     oldCourse.Name = this.Course.Name != null ? this.Course.Name.Trim() : string.Empty; 
     oldCourse.Postcode = this.Course.Postcode != null ? this.Course.Postcode.Trim() : string.Empty; 

     for (var i = 0; i < 18; i++) 
     { 
      oldCourse.Holes[i].Par = this.Course.Holes[i].Par; 
      oldCourse.Holes[i].StrokeIndex = this.Course.Holes[i].StrokeIndex; 
     } 
    } 
} 

EDIT: Окончательный код, который работает и проверяет как и ожидалось, с помощью dataannotations. Благодаря кобыле.

[HttpPost] 
    [ValidateInput(true)] 
    public ActionResult Edit(int id, CourseViewModel courseViewModel) 
    { 
     var oldCourse = _eCaddyRepository.GetCourse(id); 

     if (courseViewModel.Course == null) 
     { 
      return View("NotFound", string.Format("Course {0} Not Found", id)); 
     } 

     if (ModelState.IsValid) 
     { 
      try 
      { 
       courseViewModel.Update(oldCourse); 
       _eCaddyRepository.SubmitChanges(); 
       return RedirectToAction("Index", "Course"); 
      } 
      catch (Exception ex) 
      { 
       ModelState.AddModelError("", ex.Message); 
      } 
     } 

     // Return Model with errors 
     ModelState.AddRuleViolations(courseViewModel.Course.GetRuleViolations()); 
     return View(courseViewModel); 
    } 
+0

Это зависит от кода вашего контроллера - в частности, как вы обновляете модель. Можете ли вы опубликовать полный метод действий? – Jon

+0

Привет, Jon, спасибо за ответ hte. Я редактировал исходное сообщение, чтобы включить действие. Я сделал это так, чтобы избежать проблемы, с которой я столкнулся с Linq to Sql при обновлении. Я хотел бы услышать, есть ли там лучший способ? –

+0

Три строки кода в вашем блоке try..catch не имеют ничего общего с моделью Validation и DataAnnotations, привязанными к вашей модели - здесь вы только «пытаетесь» выполнить эти три предложения, и если они работают нормально (и я предполагаю, что они делают потому что у них нет внутренней логики для проверки достоверности модели), тогда исключение не генерируется. Что вам нужно, это ModelState.IsValid, см. Мой ответ. – mare

ответ

3

Интересно, как никто не обратил на это (jfar был близок, но его формулировка была от так chrisp_68 вероятно, не понял, что jfar имел в виду модель государственных нарушений), но вам не хватает этого из контроллера:

 if (ModelState.IsValid) // this check for model validity, not try..catch block 
     { 
      // do your stuff here, update to the datastore and return another view 
     } 

     // you can add additional Model State errors here manually if you wish 
     // with AddModelError() like you do it now 
     return View(editing); // return the same view with errors 

Так что ModelState.IsValid проверить, что вам нужно, потому что DataAnnotations не будет выполнять никаких исключений метания сами по себе.

РЕДАКТИРОВАТЬ: На самом деле, DataAnnotations не делают исключение, потому что это было бы глупо, если бы это произошло, потому что это нарушило бы выполнение вашего приложения, которое, конечно, вы не хотите. Вы хотите вернуться к одному и тому же представлению и дать пользователю возможность исправить свои ошибки.

С другой стороны, вы все равно можете иметь try..catch блок внутри, если (ModelState.IsValid), чтобы поймать РЕАЛЬНОГО исключение как отказ писать на диск или не хранить в базе данных или вставки аннулирует в Столбцы БД, где не допускаются никакие нули, и т. Д.

HTH

+0

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

+0

Если аннотации данных не генерируют исключения, что они делают тогда? Добавляют ли они ошибку в словарь состояния модели? Это не имеет смысла, потому что вы можете делать аннотации данных в приложениях, отличных от mvc. – Chev

+0

, пожалуйста, взгляните на этот вопрос о том, как работа DA и особенности о MVC http://stackoverflow.com/questions/6496705/how-do-data-annotations-work – mare

1

В MVC2 ничего не было, что вызвало бы исключение из-за поля [Обязательное].

Вы получаете типовые нарушения состояния, вот и все. Довольно-таки исключения исключаются только из ручного вызова ModelBinder, когда вы пытаетесь связать «Joel Atwood» с полем DateTime.

+0

Знаете ли вы, как отображаются нарушения состояния модели в конечном итоге. У меня есть Html.ValidationSummary, и они отображаются там, но только если код проходит через вылов выше. –

0

На класса собственности есть у положить аннотацию данных, пространство имен должно быть «YouProject.Model»

+0

Спасибо за комментарий, да, я сделал это, и он работает, но только тогда, когда вызывается другое исключение правил. –

Смежные вопросы