Сохранение серии созданных форм с помощью одной кнопки отправки в ASP.Net MVC
-
13-09-2019 - |
Вопрос
Чтобы дать некоторую предысторию по моему вопросу:
У меня есть 3 таблицы под названием Products, Packages и PackageContents.Я могу зайти в свое приложение и добавить продукты, а затем создать из них пакеты.Одним из этапов настройки пакета является создание всего содержимого пакета.Чтобы сделать это, я создал представление, которое просматривает все продукты и настраивает новое содержимое пакета для каждого, помещая PackageID и ProductID в скрытые поля.Затем пользователь может выбрать выпадающий список для каждого из них, чтобы указать, есть ли продукт в упаковке или нет.
Вот в чем моя проблема:
При этом для каждого продукта отображается отдельная форма, у каждого из которых есть своя кнопка сохранить.Я бы хотел иметь одну кнопку отправки, которая сохраняла бы все содержимое нового пакета сразу.Может кто-нибудь привести мне пример того, как написать мой метод POST для перебора и сохранения всего содержимого нового пакета и как я мог бы создать кнопку на мой взгляд, которая сохраняет их все сразу?
Моя Модель:
public class PackageContentViewModel
{
//Properties
public IEnumerable<Product> products { get; set; }
public Product product { get; set; }
public Package package { get; set; }
public PackageContent packageContent { get; set; }
//Constructor
public PackageContentViewModel(int id)
{
CustomerRepository customerRepository = new CustomerRepository();
package = customerRepository.GetPackage(id);
products = customerRepository.FindAllProducts().ToList();
foreach (var product in products)
{
PackageContent packageContent = new PackageContent();
{
packageContent.PackageID = id;
packageContent.ProductID = product.ProductID;
}
}
}
Контроллер:
public ActionResult AddContents(int id)
{
Package package = customerRepository.GetPackage(id);
return View(new PackageContentViewModel(id) { });
}
Вид из окна:
<% foreach (var product in Model.products)
{ %>
<% using (Html.BeginForm())
{%>
<fieldset>
<legend><%= Html.Encode(product.ProductName) %></legend>
<%= Html.Hidden("PackageContentsID") %>
<%= Html.ValidationMessage("PackageContentsID", "*") %>
<%= Html.Hidden("PackageID", Model.package.PackageID) %>
<%= Html.ValidationMessage("PackageID", "*") %>
<%= Html.Hidden("ProductID", product.ProductID) %>
<%= Html.ValidationMessage("ProductID", "*") %>
<label for="InPackage">InPackage:</label>
<%= Html.TextBox("InPackage") %>
<%= Html.ValidationMessage("InPackage", "*") %>
<label for="Restricted">Restricted:</label>
<%= Html.TextBox("Restricted") %>
<%= Html.ValidationMessage("Restricted", "*") %>
<input type="submit" value="Create" />
</fieldset>
<% } %>
<% } %>
Редактировать
Я решил опубликовать код, который в итоге сработал у меня, на случай, если кто-нибудь еще придет и ему понадобится такая же помощь:
Мой Взгляд:
<% int i = 0; using (Html.BeginForm("CreateContents", "Packages", new { id = Model.package.PackageID }))
{
foreach (var product in Model.products)
{
%>
<fieldset>
<legend><%= Html.Encode(product.ProductName)%></legend>
<%= Html.Hidden("PackageContents[" + i + "].PackageContentsID")%>
<%= Html.ValidationMessage("PackageContentsID", "*")%>
<%= Html.Hidden("PackageContents[" + i + "].PackageID", Model.package.PackageID)%>
<%= Html.ValidationMessage("PackageID", "*")%>
<%= Html.Hidden("PackageContents[" + i + "].ProductID", product.ProductID)%>
<%= Html.ValidationMessage("ProductID", "*")%>
<label for="InPackage">InPackage:</label>
<%= Html.TextBox("PackageContents[" + i + "].InPackage", "yes")%>
<%= Html.ValidationMessage("InPackage", "*")%>
<label for="Restricted">Restricted:</label>
<%= Html.TextBox("PackageContents[" + i + "].Restricted", "no")%>
<%= Html.ValidationMessage("Restricted", "*")%>
</fieldset>
<%
++i; } %>
<input type="submit" value="Add Contents" />
<% } %>
Мой Контроллер:
public RedirectToRouteResult CreateContents(int id, IList<PackageContent> PackageContents)
{
Package package = customerRepository.GetPackage(id);
foreach (var packageContent in PackageContents)
{
customerRepository.Add(packageContent);
customerRepository.Save();
}
return RedirectToAction("SetPrice", new { id = package.PackageID });
}
Решение
Здесь вы можете прочитать о привязке к списку: Привязка модели к списку
Эта статья старая, в более новой версии MVC вам не нужно определять <input type="hidden" name="products.Index" value="0" />
, но остальное действительно.
Редактировать
Ответ на комментарий:
Если единственное, что вы делаете, это выбираете, есть ли продукт в упаковке или нет, вы можете использовать MultiSelectList .
Если вы хотите указать количество или другие атрибуты, вы можете написать:
<% int i = 0; using (Html.BeginForm()) {%>
<% foreach (var product in Model.products) { %>
<label for="Restricted"><%= product.Name %></label>
<%= Html.Hidden("products[" + i + "].ProductId",product.id) %>
<%= Html.TextBox("products[" + i + "].Quantity",0) %>
<br/>
<% ++i; } %>
<% } %>
Действие после публикации:
[HttpPost]
public ActionResult Edit(IList<PackageContent> products)
где находится PackageContent
class PackageContent
{
int ProductId{get;set;}
int Quantity{get;set;}
}