Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Из предыдущих тем мы узнали, как передавать отдельные объекты из представления в методы действия контроллера в качестве параметров.
Но в реальности может возникнуть ситуация, что потребуется передать в метод не один объект типа int
или какой-нибудь модели, а
сразу несколько объектов. Посмотрим на некоторые возможные случаи.
Определим следующую форму в представлении:
@using (Html.BeginForm()) { @Html.TextBox("names") @Html.TextBox("names") @Html.TextBox("names") @Html.TextBox("names") <input type="submit" /> }
Таким образом, у нас в html-разметке будет создано четыре элемента input
<form action="/Home/Array" method="post"> <input id="names" name="names" type="text" value="" /> <input id="names" name="names" type="text" value="" /> <input id="names" name="names" type="text" value="" /> <input id="names" name="names" type="text" value="" /> <input type="submit" /> </form>
Поэтому при отправке формы будет формироваться коллекция из names
, состоящая из четырех элементов. И в методе контроллера
мы сможем получить все эти элементы:
[HttpPost] public string Array(List<string> names) { string fin=""; for (int i = 0; i < names.Count; i++) { fin += names[i] + "; "; } return fin; }
Мы можем передать в представление массив объектов некоторой модели, например, модели Book
:
[HttpGet] public ActionResult Add() { return View(db.Books.ToList()); }
Чтобы вывести объекты для редактирования в представление мы можем использовать следующую конструкцию:
@model List<BookStore.Models.Book> ....................................... @using (Html.BeginForm()) { for(int i=0; i<Model.Count; i++) { <h4>Книга № @(i+1)</h4> @: Name: @Html.EditorFor(m=>m[i].Name) @: Author: @Html.EditorFor(m => m[i].Author) @: Price: @Html.EditorFor(m => m[i].Price) } <input type="submit" /> }
Так мы сгенерируем для каждого объекта набор полей для редактирования его свойств. И после нажатия кнопки весь данный массив отправится на сервер, где его можно получить таким образом:
[HttpPost] public string Add(List<Book> books) { //........................ }
В предыдущем случае мы передавали коллекцию объектов модели Book
. Однако может возникнуть ситуация, когда мы должны разграничить
как-то переданные объекты, а не рассматривать их как одну коллекцию. Например, метод контроллера может выглядеть так:
[HttpPost] public string Add(Book book, Book myBook) { //........................ }
Мы используем два отдельных объекта Book. Как мы можем передать их из представления в контроллер? Допустим, теперь, что один объект мы передаем в качестве модели представления, а другой создаем в том же представлении:
@using BookStore.Models @model Book @{ ViewBag.Title = "Array"; } @{ Book myBook = new Book() { Name = "Мартин Иден", Author = "Джек Лондон", Price = 190 }; } <h2>Книги</h2> @using (Html.BeginForm()) { @Html.EditorFor(m=>myBook) @Html.EditorForModel() <input type="submit" /> }
Одну модель мы передаем из контроллера в представление:
[HttpGet] public ActionResult Array() { Book firstBook = db.Books.ToList<Book>().FirstOrDefault(); return View(firstBook); }
Вторую модель - myBook
мы создаем уже в самом представлении. Все поля модели генерируются с помощью хелпера @Html.EditorFor(m=>myBook)
.
Обратите внимание на имя модели - myBook. Так как мы ожидаем, что данный объект должен быть передан в метод в качестве параметра myBook
,
то он должен иметь точно такое же имя, а не произвольное.
Таким образом, мы можем передать на сервер два разных объекта одной модели.
Допустим, у нас есть следующая модель:
public class Book { public int Id { get; set; } public string Name { get; set; } } public class Author { public int Id { get; set; } public string Name { get; set; } public ICollection<Book> Books { get; set; } }
Модель автора содержит ссылку на коллекцию книг. В контроллере мы получаем эту модель:
[HttpPost] public ActionResult GetAuthor(Author author) { return View(); }
Тогда представление могло бы выглядеть так:
@model ArrayPostApp.Models.Author <h2>Добавление книг</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="authorBlock"> <label>Имя автора</label> <input type="text" name="name" /> </div> <div id="booksBlock"> <div class="bookItem"> <h4>Книга № 1</h4> <div> <label>Название</label> <div> <input type="text" name="Books[0].name" /> </div> </div> </div> </div> <p><a class="addLink">Добавить новый элемент</a></p> <p><input type="submit" value="Добавить" /></p> } @section Scripts { <script> $(function () { var i = 0; $('.addLink').click(function() { i++; var html2Add= "<div class='bookItem'>"+ "<h4>Книга № "+(i+1) + "</h4>"+ "<div><label>Название</label><div>"+ "<input type='text' name='Books["+i+"].name' />"+ "</div></div></div>"; $('#booksBlock').append(html2Add); }) }) </script> }
Так как модель Author содержит набор книг в свойстве Books, то атрибут name соответствующих текстовых элементов должно иметь следующую форму:
name="Books[0].name"
. С помощью кода javascript мы можем динамически добавить новые элементы: