Ошибка проверки MVC со строго типизированным представлением - PullRequest
0 голосов
/ 03 июня 2010

У меня есть простая форма, которую я хотел бы проверить при отправке формы. Обратите внимание, что я удалил HTML для удобства просмотра

<%=Html.TextBox("LastName", "")%> //Lastname entry
<%=Html.ValidationMessage("LastName")%>

<%=Html.TextBox("FirstName", "")%>//Firstname entry
<%=Html.ValidationMessage("FirstName")%>

<%=Html.DropDownList("JobRole", Model.JobRoleList)%> //Dropdownlist of job roles

<% foreach (var record in Model.Courses) // Checkboxes of different courses for user to select
   { %>
       <li><label><input type="checkbox" name="Courses" value="<%=record.CourseName%>" /><%= record.CourseName%></label></li>
   <% } %>  

При отправке этой формы я хотел бы проверить, заполнены ли и FirstName, и LastName (то есть ненулевая длина).

В моем контроллере у меня есть:

public ActionResult Submit(string FirstName, string LastName)
{
   if (FirstName.Trim().Length == 0)
   ModelState.AddModelError("FirstName", "You must enter a first name");

   if (LastName.Trim().Length == 0)
   ModelState.AddModelError("LastName", "You must enter a first name");

   if (ModelState.IsValid)
    {
      //Update database + redirect to action
    }

   return View(); //If ModelState not valid, return to View and show error messages
}

К сожалению, эта логика кода выдает ошибку, которая гласит, что для JobRole и Courses.

не найдено никаких объектов.

Если я удаляю выпадающий список и флажки, все работает нормально.

Кажется, проблема в том, что когда я возвращаю View, представление ожидает объекты для dropwdownlist и флажков (что разумно, поскольку это то, что есть в моем коде представления)

Как мне преодолеть эту проблему?

Вещи, которые я рассмотрел:

  1. В моем контроллере я мог бы создать объект JobRoleList и Course для передачи в View, чтобы в нем были объекты для рендеринга. Проблема заключается в том, что он перезапишет все выпадающие списки / флажки, которые пользователь уже сделал.
  2. В параметрах моего метода контроллера Submit я мог бы также захватить объект JobRoleList и Course, чтобы передать их обратно в View. Снова, не уверен, что это захватит любые элементы, которые пользователь уже выбрал.

Я много гуглил и читал, но не могу найти хорошего ответа. Когда я смотрю на примеры в книгах или онлайн (например, Nerddinner), все примеры валидации включают простые формы с входными данными TextBox и, кажется, не показывают экземпляры с несколькими флажками и выпадающими списками.

Я что-то упустил здесь очевидное? Что будет лучшей практикой в ​​этой ситуации?

Спасибо

Ответы [ 2 ]

1 голос
/ 03 июня 2010

Лучшей практикой будет принятие модели для конкретного вида.У вас может быть общая модель, которая имеет как свойства, необходимые для отображения страницы, так и свойства, необходимые для публикации или отдельных моделей для отображения и принятия параметров публикации.Я обычно использую совместно используемую модель, так как это означает, что я могу просто вернуть полученную модель, соответствующим образом повторно заполненную любыми данными, необходимыми для создания меню (например, JobList и Courses).Часто у меня будет метод, который берет модель этого типа и возвращает представление с заполненными свойствами меню.

   public ActionResult JobsView( JobsViewModel model )
   {
        model.JobList = db.Jobs.Select( j => new SelectListItem 
                                             {
                                                  Text = j.Name,
                                                  Value = j.ID.ToString()
                                             });
        ...
        return View( model );
   }

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

   // on error, return the view
   return JobsView( model );

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

  public class JobsViewModel
  {
       [Required]
       public string FirstName { get; set; }

       [Required]
       public string LastName { get; set; }

       public int JobRole { get; set; }

       [ScaffoldColumn(false)]
       public IEnumerable<SelectListItem> JobRoleList { get; set; }

       ...
  }

  public ActionResult Submit( JobsViewModel model )
  {
       if (ModelState.IsValid)
       {
           ... convert model to entity and save to DB...
       }

       return JobsView( model );
  }

Затем включите проверку в своем HTML

...
<script type="text/javascript" src="<%= Url.Content( "~/scripts/MicrosoftMvcValidation.js" ) %>"></script>

<% Html.EnableClientValidation(); %>

... begin form...

<%=Html.TextBoxFor( m=> m.LastName )%>
<%=Html.ValidationMessageFor( m => m.LastName )%>

<%=Html.TextBoxFor( m=> m.FirstName )%>
<%=Html.ValidationMessageFor( m => m.FirstName )%>

<%=Html.DropDownListFor( m=> m.JobRole, Model.JobRoleList)%>

<% foreach (var record in Model.Courses) // Checkboxes of different courses for user to select
   { %>
       <li><label><input type="checkbox" name="Courses" value="<%=record.CourseName%>" /><%= record.CourseName%></label></li>
   <% } %>  
0 голосов
/ 03 июня 2010

При простой проверке MVC вы должны передать строго типизированный объект, другими словами, модель ваших представлений.

Пример:

public ActionResult Update(Employees employee)
{

if (employee.Name.Trim().Length == 0)
        ModelState.AddModelError("Name", "Name is required.");

// ETC....

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