Я часто создаю модели-оболочки, чтобы справиться с подобной ситуацией, например
public class CustomerWrapperModel
{
public Customer Customer { get; set;}
public Accounts Accounts { get; set;}
public List<Address> AddressList { get; set}
//Add
public CustomerWrapperModel()
{
}
//Add/Edit
public CustomerWrapperModel(Customer customer, Accounts accounts, List<Address> addressList)
{
this.Customer = customer;
this.Accounts = accounts;
this.AddressList = addressList;
}
}
затем объявите представление типа CustomerWrapperModel и используйте такие редакторы, как:
@model MyNamespace.CustomerWrapperModel
@Html.EditorFor(model => model.Customer)
@Html.EditorFor(model => model.Accounts)
@Html.EditorFor(model => model.AddressList)
и иметь контроллер для получения сообщения, которое выглядит следующим образом:
[HttpPost]
public ActionResult(Customer customer, Accounts accounts, List<Address> addressList)
{
//Handle db stuff here
}
Что касается динамического добавления адресов, я нашел лучший способ сделать это, если вы используете проверку MVC и хотите правильно структурировать список с правильными индексами списка, чтобы в вашем контроллере был параметр List, а именно: отправить текущие адреса на вспомогательный контроллер следующим образом:
[HttpPost]
public PartialResult AddAddress(List<Address> addressList)
{
addressList.Add(new Address);
return PartialView(addressList);
}
затем получим частичное представление, которое просто снова отображает поля адреса:
@model List<MyNamespace.Address>
@{
//Hack to get validation on form fields
ViewContext.FormContext = new FormContext();
}
@Html.EditorForModel()
убедитесь, что все поля адресов находятся в одном контейнере, а затем вы можете просто перезаписать существующие поля возвращенными данными, и ваши новые поля адреса будут добавлены внизу. После того, как вы обновили свой контейнер, вы можете сделать что-то вроде этого для повторной проверки:
var data = $("form").serialize();
$.post("/Customer/AddAddress", data, function (data) {
$("#address-container").html(data);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
});
NB. Я знаю, что у некоторых людей есть проблема с этим, так как требуется добавление полей на страницу со стороны сервера, которые могут быть легко добавлены на стороне клиента (я всегда делал это на стороне клиента, но пробовал один раз с этим метод и никогда не возвращался). Причина, по которой я это делаю, заключается в том, что это самый простой способ сохранить правильность индексов в элементах списка, особенно если у вас есть вставки, а также добавления, и у ваших объектов много свойств. Кроме того, используя частичное представление для визуализации данных, вы можете гарантировать, что проверка будет сгенерирована для новых полей для вас из коробки, вместо того, чтобы вручную вырезать проверку для вновь добавленных полей на стороне клиента. Компромисс в большинстве случаев - незначительный объем данных, передаваемых во время запроса ajax.
Вы также можете выбрать более точные поля, которые вы отправляете в контроллер AddAddress, как вы можете видеть, я просто отправляю всю форму на контроллер и игнорирую все, кроме полей адреса, я использую быстрые серверы и дополнительные (незначительные) накладные расходы на нежелательные поля формы незначительны по сравнению со временем, которое я мог бы потратить впустую, кодируя функциональность этого типа более эффективным способом пропускной способности.