2010-06-03 3 views
0

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

<%=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, чтобы передать его обратно в Вид. Опять же, не уверен, что это захватит все элементы, которые пользователь уже выбрал.

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

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

Благодаря

ответ

1

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

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

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

+0

@ Remnant. Как я уже сказал, у вас могут быть отдельные модели (с использованием подкласса, если необходимо) для отображения/публикации, но тогда вам понадобится способ преобразования между ними, когда у вас есть ошибка, а не просто заполнение отсутствующих бит. – tvanfosson

0

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

Пример:

public ActionResult Update(Employees employee) 
{ 

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

// ETC.... 

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