2015-01-27 6 views
2

По какой-то причине ModelState.IsValid чека в моем контроллере возвращается правда, даже если мое лицо и ViewModel свойства имеют [обязательно] атрибут на поле, которое равно 0.ModelState.IsValid игнорирования [Требуется] атрибут

Это сущность:

public class Ticket 
{ 
    public int Id { get; set; } 

    [Required] 
    public int FareId { get; set; } 
    public virtual Fare Fare { get; set; } 
} 

И ViewModel, который использует мое мнение:

public class BaseTicketViewModel 
{ 
    [Required, Display(Name = "Fare")] 
    public int FareId { get; set; } 
    public Fare Fare { get; set; } 
} 

на мой взгляд, я использовал ряд переключателей вместо падения DOW п список, то, что может быть причиной проблемы, я просто не знаю, как:

<div class="form-group"> 
    @Html.LabelFor(model => model.FareId, htmlAttributes: new { @class = "control-label col-md-2" }) 
    <div class="col-md-10"> 
     @foreach (FareGroup fareGroup in Model.FareList) 
     { 
      <h5><strong>@fareGroup.Name</strong></h5> 

      foreach (Fare fare in fareGroup.Fares) 
      { 
       <label class="checkbox-inline"> 
        @Html.RadioButtonFor(model => model.FareId, fare.Id) 
        @fare.Name 
       </label> 
      } 
     } 
     @Html.ValidationMessageFor(model => model.FareId, "", new { @class = "text-danger" }) 
    </div> 
</div> 

Когда я отправить форму без выбора тарифа, мой контроллер поднимает DbUpdateException, который говорит мне, что заявление INSERT противоречие с ограничением FOREIGN KEY, в основном, что Fare с ID-не существует:

"{заявления INSERT конфликтного с ограничением FOREIGN KEY "FK_dbo.Tickets_dbo.Fares_FareId". Конфликт произошел в базе данных «отредактированный», таблица «dbo.Fares», столбец «Id». \ Г утверждение \ NThe было прервано. "}

По моему разумению, если FareId собственности на ViewModel/объект билета 0, то ModelState.IsValid должно быть ложным из-за [Required] аннотацию на это имущество?

+0

Вставьте код вашего контроллера. – gabsferreira

+2

'0' является допустимым int. Поскольку 'int' не может быть null, вы всегда будете проходить тест' Required'. Вы хотите использовать 'int? 'Или nullable int. – Jonesopolis

+0

Ну, 0 все еще значение. Когда он говорит, что Required означает, что он не может быть Null. – mattfetz

ответ

6

Integers по умолчанию будет 0, так как они являются типами значений. в результате, он отвечает требованиям атрибута требуется, хотя довольно плохо для вашего сценария.

В Required Attribute документации говорится:

Атрибут RequiredAttribute указывает, что, когда поле на форме проверяется, поле должно содержать значение. Исключение проверки возникает, если свойство равно null, содержит пустую строку (""), или содержит только символы пробела.

Поскольку ваш int не имеет значения NULL, и поскольку он явно не может быть пустой строкой, он проходит проверку.

Если вы хотите, чтобы ваш идентификатор не был значением по умолчанию, вы можете использовать атрибут Range, хотя, если у вас есть идентификатор 0, это вызовет проблемы.

[Range(1, int.MaxValue, 
    ErrorMessage = "Value for {0} must be between {1} and {2}.")] 

Наконец, как Крис Петерсон отметил, если FareId обнуляемым, он сможет правильно использовать атрибут требуется, так как по умолчанию будет нулевое значение, если значение не отвечал, запуская проверку.

[Required] 
public int? FareId { get; set; } 
+0

Я урезал свой объект/модель просмотра для целей этого сообщения, и у меня также есть другое свойство под названием «TimetableId», определенное так же, как «FareId», только это представлено выпадающим списком в представлении. Это * также * отправляет значение '0', когда вы ничего не выбираете, но' ModelState.IsValid' работает тогда, как я ожидал бы (возвращает false, когда 'TimetableId == 0'). Какая разница? –

+1

@ChrisWhite Должен быть другой сценарий, связанный с TimetableId, но так как вы не разместили какой-либо код относительно TimetableId, невозможно сказать вам, в чем разница. –

+0

Другим вариантом было бы использовать нулевое значение int с обязательным атрибутом. –

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