2016-04-20 3 views
0

У меня есть форма с несколькими значениями для настраиваемого вопроса. Идея, являющаяся пользователем, может создавать собственный пользовательский вопрос с пользовательскими ответами. Одним из свойств объекта Модель представляет собой список объектов:Как использовать обязательную аннотацию данных для списка текстовых полей

public class CustomQuestion 
{ 
    public int Id { get; set; } 
    [Required] 
    public string QuestionName{ get; set; } 
    public virtual List<CustomQuestionAnswer> Answers { get; set; } 

} 

public class CustomQuestionAnswer 
{ 
    public int Id { get; set; } 
    [Required] 
    public string Answer { get; set; } 

} 

Теперь у меня есть это бритва, которая работает, чтобы создать ответы (я опустил остальную часть вопроса):

foreach (var answer in Model.Answers) 
{ 
    if (answer.IsActive) 
    { 
     <div class="form-group answer"> 
      <div class="col-md-10"> 
       @Html.Hidden("answers[" + count + "].Id", answer.Id) 
       @Html.TextBox("answers[" + count + "].Answer", answer.Answer, new { @class = "form-control" }) 
       validation code will go here 
      </div> 
      <div class="col-md-2"> 
       @Html.CheckBox("answers[" + count + "].IsActive", answer.IsActive) 
      </div> 
     </div> 
     count++; 
    } 
} 

Теперь все работает нормально и сохраняется в базе данных, за исключением того, что проверка данных не работает. У меня есть сообщения проверки данных, работающие для QuestionName CustomQuestion (поэтому я знаю, что это не проблема загрузки jquery), но не для ответов. Я попытался поместить эти линии в бритвенную форму:

@Html.ValidationMessageFor(m => answer.Answer, "", new { @class = "text-danger" }) 
@Html.ValidationMessage("Answers[" + count + "].Answer", "", new { @class = "text-danger" }) 

Но не работает. Кроме того, когда я нажимаю на кнопку сохранить, я получаю сообщение об ошибке в консоли браузера:

Failed to load resource: the server responded with a status of 400 ({"Answers[0].Answer":["The Answer field is required."]}) 

Любые идеи относительно того, что мне нужно для проверки кода?

+1

Если вы используете ViewModel почему вы не используйте 'ValidationMessageFor',' TextBoxFor' и 'CheckBoxFor' помощники? Они будут генерировать правильную разметку для вас. –

+0

Ознакомьтесь с моим обновленным ответом. – Dilip

ответ

2

Если ваша модель (или содержит) индексированной коллекции, то лучше использовать for -loop наряду с полностью указанными переменными и с ...For помощникам, как это:

for (var i = 0; i < Model.Answers.Count; i++) 
{ 
    if (Model.Answers[i].IsActive) 
    { 
     <div class="form-group answer"> 
      <div class="col-md-10"> 
       @Html.HiddenFor(m => Model.Answers[i].Id) 
       @Html.TextBoxFor(m => Model.Answers[i].Answer, new { @class = "form-control" }) 
       @Html.ValidationMessageFor(m => Model.Answers[i].Answer, null, new { @class = "text-danger" }) 
      </div> 
      <div class="col-md-2"> 
       @Html.CheckBoxFor(m => Model.Answers[i].IsActive) 
      </div> 
     </div> 
    } 
} 

Это может показаться неудобным или даже ненужным, чтобы ссылаться на полный Model.Answers[i] везде, но MVC использует отражение этих выражений, чтобы придумать полные имена для вывода, которые необходимы для привязки модели к успеху ed, а также для сопряжения его с ModelState, который использует ту же структуру объектов.
Использование временной или вспомогательной переменной, такой как ваш answer, приведет к тому, что MVC больше не сможет этого делать, а затем бремя становится вашим собственным.

+0

Я не могу отредактировать его, но в строке '@ Html.CheckBoxFor (m => Model.Answers [i] .IsActive") есть дополнительная отметка о кавычке '' –

+0

Спасибо, исправил ее. –

0

Для Validation вы можете использовать этот код:

@Html.ValidationMessageFor(m => answer.Answer,null, new { @class = "text-danger" }) 

Пожалуйста, проверьте его и дайте мне знать ..

2

Вы должны использовать сильно типизированных хелперы, если у вас есть ViewModel. Чтобы сделать правильный поворот, вы должны использовать цикл for вместо foreach.

Как это:

for (int i = 0; i < Model.Answers.Count(); i++) 
{ 
    if (Model.Answers[i].IsActive) 
    { 
     <div class="form-group answer"> 
      <div class="col-md-10"> 
       @Html.HiddenFor(x => Model.Answers[i].Id) 
       @Html.TextBoxFor(x => Model.Answers[i].Answer, new { @class = "form-control" }) 
       @Html.ValidationMessageFor(m => x => Model.Answers[i].Answer, null, new { @class = "text-danger" }) 
      </div> 
      <div class="col-md-2"> 
       @Html.CheckBox(x => Model.Answers[i].IsActive) 
      </div> 
     </div> 
    } 
} 
0

вы можете настроить вам сообщение в модели как:

 [Required] 
     [DataType(DataType.EmailAddress, ErrorMessage = "You need a valid email adress")] 
     [MaxLength(40, ErrorMessage = "the length of an Email address must be at least 40 chars")] 
     [Display(Name = "Email")] 
     public string CurrentMail { get; set; } 

, а затем вы делаете простой

@Html.TextBoxFor(m => m.CurrentMail) 

вместо того, чтобы @Html.TextBox(m => m.CurrentMail)

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