2013-09-25 11 views
4

Я работаю над административной панелью, которая позволит пользователю добавить одного или многих других пользователей. Существует текстовая область, в которой администратор может вводить один или несколько идентификаторов пользователей, которые должны быть добавлены в приложение, что соответствует идентификатору пользователя, присвоенному во время процесса трудоустройства. При представлении приложение вытаскивает имя, адрес электронной почты и т. Д. Из базы данных, содержащей всех сотрудников, и отображает ее на экране для проверки. Также на экране есть некоторые флажки для назначения некоторых разрешений, таких как CanWrite и IsAdmin.Связывание модели с несколькими объектами

Просмотр

using (Html.BeginForm()) 
     { 
      <table> 
       <tr> 
        <th> 
        </th> 
        <th> 
         @Html.DisplayNameFor(model => model.User.First().ID) 
        </th> 
        <th> 
         @Html.DisplayNameFor(model => model.User.First().Name) 
        </th> 
        <th> 
         @Html.DisplayNameFor(model => model.User.First().Email) 
        </th> 
        <th> 
         @Html.DisplayNameFor(model => model.User.First().CanWrite) 
        </th> 
        <th> 
         @Html.DisplayNameFor(model => model.User.First().IsAdmin) 
        </th> 
       </tr> 

       @foreach (var item in Model.User) 
       { 
        <tr> 
         <td> 
          <input type="checkbox" name="id" value="@item.ID" checked=checked/> 
         </td> 
         <td> 
          @Html.DisplayFor(modelItem => item.ID) 
         </td> 
         <td> 
          @Html.DisplayFor(modelItem => item.Name) 
         </td> 
         <td> 
          @Html.DisplayFor(modelItem => item.Email) 
         </td> 
         <td> 
          @Html.CheckBoxFor(modelItem => item.CanWrite) 
         </td> 
         <td> 
          @Html.CheckBoxFor(modelItem => item.IsAdmin) 
         </td> 
        </tr> 
       } 

      </table> 
      <input type="submit" /> 
     } 

ПРИМЕЧАНИЕ: Причина флажком с именем ID, чтобы дать возможность не добавить пользователя, как только имя и другая информация была неправдоподобным, например, пользователь вы не означает, что случайно попал в список идентификаторов.

Модель

public class User 
{ 
    public int ID { set; get; } 
    public string Name { set; get; } 
    public bool IsAdmin { set; get; } 
    public bool CanWrite { set; get; } 
    public string Email{ set; get; } 

} 

Контроллер

[HttpPost] 
public ActionResult Create(IEnumerable<User> model) 
{ 
    //With this code, model shows up as null 
} 

В случае одного пользователя, я знаю, что могу использовать User model в качестве параметра в моем действии контроллера. Как настроить этот код для работы с несколькими пользователями, добавленными сразу? Возможно ли это?

ответ

1

Вы на правильном пути, Джефф. Вам просто нужно расширить то, что у вас есть.

Во-первых, причина, по которой ваша модель null в вашем действии объясняется тем, как поля ввода указаны в вашей форме. Ваши поля будут оказывать по линии этого:

<input id="item_CanWrite" name="item.CanWrite" type="checkbox" value="true" /> 
<input name="item.CanWrite" type="hidden" value="false" /> 

Обратите внимание, что name является item.CanWrite. Проблема здесь в том, что, поскольку вы перебираете всех пользователей в своей модели, вы по существу даете одинаковое имя всем полям ввода. Это предотвращает возможность MVC моделировать привязку к данным POSTed, поскольку не может различать каждый из User.

Для того, чтобы исправить это, необходимо изменить вызовы Html.DisplayFor для того, чтобы позволить MVC обрабатывать каждый User как отдельное юридическое лицо, таким образом, позволяя каждому User «s набор полей, которые будут названы последовательно. Это позволяет привязке модели к соответствующим полям. Как так:

@for (int i = 0; i < Model.Count(); i++) 
{ 
    <tr> 
     <td> 
      <input type="checkbox" name="id" value="@Model[i].ID" checked=checked/> 
     </td> 
     <td> 
      @Html.DisplayFor(m => m[i].ID) 
     </td> 
     <td> 
      @Html.DisplayFor(m => m[i].Name) 
     </td> 
     <td> 
      @Html.DisplayFor(m => m[i].Email) 
     </td> 
     <td> 
      @Html.CheckBoxFor(m => m[i].CanWrite) 
     </td> 
     <td> 
      @Html.CheckBoxFor(m => m[i].IsAdmin) 
     </td> 
    </tr> 
} 

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

<input checked="checked" data-val="true" data-val-required="The CanWrite field is required." name="[0].CanWrite" type="checkbox" value="true" /> 
<input name="[0].CanWrite" type="hidden" value="false" /> 
<input checked="checked" data-val="true" data-val-required="The CanWrite field is required." name="[1].CanWrite" type="checkbox" value="true" /> 
<input name="[1].CanWrite" type="hidden" value="false" /> 

Как вы можете видеть, каждый User имеет свой собственный отдельный индекс. Я использовал простую испытательную установку с помощью следующего метода контроллера, который подобран правильное количество записей в моей тестовой модели:

[HttpPost] 
public ActionResult Index(IEnumerable<User> model) 
{ 
    // Process your data. 

    return View(model); 
} 

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

  1. Создать DisplayTemplates папку внутри текущей папки вашего зрения в (например, если ваш взгляд Home\Index.cshtml, создайте папку Home\DisplayTemplates).
  2. Создайте строго типизированный вид в этом каталоге с именем, которое соответствует вашей модели (т. Е. В этом случае вид будет называться User.cshtml).
  3. Поместите повторную логику в вид.

Ваш шаблон должен теперь выглядеть следующим образом (запрещающее пространство имен, где ваша User модель проживает):

@model User 

<tr> 
    <td> 
     <input type="checkbox" name="id" value="@Model.ID" checked=checked/> 
    </td> 
    <td> 
     @Html.DisplayFor(m => m.ID) 
    </td> 
    <td> 
     @Html.DisplayFor(m => m.Name) 
    </td> 
    <td> 
     @Html.DisplayFor(m => m.Email) 
    </td> 
    <td> 
     @Html.CheckBoxFor(m => m.CanWrite) 
    </td> 
    <td> 
     @Html.CheckBoxFor(m => m.IsAdmin) 
    </td> 
</tr> 

Теперь в вашем первоначальном виде, вы можете заменить все петли с этим:

@using (Html.BeginForm()) 
{ 
    <table> 
     @Html.DisplayForModel() 
    </table> 
    <input type="submit" value="Submit" /> 
} 

Если вы хотите узнать больше о привязке к коллекции, пожалуйста, см an answer я предоставил еще один вопрос.

1

Я только начинаю ASP.NET MVC, но я думаю, вам нужно только создать класс модели представления, который имеет свойство типа IEnumerable<User>, где вы храните свою коллекцию пользователей. А затем передайте это на свое мнение и вернитесь к своему обработчику POST.

1

попробовать что-то вроде этого:

Модель

public class Employee 
{ 
    public IEnumerable<User> Employees { set; get; } 
} 

public class User 
{ 
    public int ID { set; get; } 
    public string Name { set; get; } 
    public bool IsAdmin { set; get; } 
    public bool CanWrite { set; get; } 
    public string Email{ set; get; } 
} 

Посмотреть

@model Employee 

@using(Html.BeginForm() 
{ 
    // build HTML table, not much different from yours 
} 

Контроллер

[HttpPost] 
public ActionResult Create(Employee model) 
{ 
    // model will have an IEnumerable property with the User info 
} 
+0

Точно, что я имею в виду. Хороший пример. – meilke

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