Редактирование и сохранение сложных объектов
Скажем, у вас есть следующий объект:
public class Address
{
public String Line1 { get; set; }
public String Line2 { get; set; }
public String City { get; set; }
public String State { get; set; }
public String ZipCode { get; set; }
public Address()
{
}
}
public class Contact
{
public String FirstName { get; set; }
public String LastName { get; set; }
public String Telephone { get; set; }
public Address BillingAddress { get; set; }
public List<Address> ShippingAddresses { get; set; }
public Contact()
{
// Assume anything that _could_ be null wouldn't be. I'm excluding
// most "typical" error checking just to keep the examples simple
this.BillingAddress = new Address();
this.ShippingAddresses = new List<Address>();
}
}
Предположим, что свойства украшены[Required]
, [Display]
и другие атрибуты.
Тогда мой контроллер (упрощенный ради демо):
public ActionResult Edit(String id)
{
Contact contact = ContactManager.FindByID(id);
return View(model: contact);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Contact contact)
{
if (ModelState.IsValid) //always fails
{
ContactManager.Save(contact);
return RedirectToAction("Saved");
}
return View(model,: contact);
}
Я продолжаю видеть демонстрации по редактированию подобного объекта в MVC, но они постоянно разбивают коллекции объектов на их собственную форму (например, редактируют контакт, затем редактируют определенный адрес из контакта). Я, с другой стороны, пытаюсь отредактировать всю эту информацию на той же странице, но безуспешно. Например:
@model Contact
// simplified for brevity
@using (Html.BeginForm())
{
@Html.LabelFor(x => x.FirstName): @Html.EditorFor(x => x.FirstName)
@Html.LabelFor(x => x.LastName): @Html.EditorFor(x => x.LastName)
@Html.LabelFor(x => x.Telephone): @Html.EditorFor(x => x.Telephone)
<div>
@Html.LabelFor(x => x.BillingAddress.Line1): @Html.EditorFor(x => x.BillingAddress.Line1)
@Html.LabelFor(x => x.BillingAddress.Line2): @Html.EditorFor(x => x.BillingAddress.Line2)
@Html.LabelFor(x => x.BillingAddress.City): @Html.EditorFor(x => x.BillingAddress.City)
@Html.LabelFor(x => x.BillingAddress.State): @Html.EditorFor(x => x.BillingAddress.State)
@Html.LabelFor(x => x.BillingAddress.ZipCode): @Html.EditorFor(x => x.BillingAddress.ZipCode)
</div>
<div>
@foreach (Address addr in Model.ShippingAddresses)
{
<div>
@Html.LabelFor(x => addr.Line1): @Html.EditorFor(x => addr.Line1)
@Html.LabelFor(x => addr.Line2): @Html.EditorFor(x => addr.Line2)
@Html.LabelFor(x => addr.City): @Html.EditorFor(x => addr.City)
@Html.LabelFor(x => addr.State): @Html.EditorFor(x => addr.State)
@Html.LabelFor(x => addr.ZipCode): @Html.EditorFor(x => addr.ZipCode)
</div>
}
</div>
}
Проблема, с которой я продолжаю работать, состоит в том, чтоModelState.IsValid
никогда не проходит, когда я иду, чтобы сохранить информацию обратно. Есть ли уловка, чтобы сделать это, или это только вне области MVC? Я хотел бы взять объект какContact
и выгрузить всю информацию на одной странице для редактирования и успешно ее повторно сохранить, но я не могу заставить ее работать. (Мой следующий шаг - связать ajax, чтобы вы могли динамически добавлять / удалять «ShipingAddresses» на этой странице, но сначала мне нужно сохранить, чтобы работать - K.I.S.S)
Проблемы:
ModelState.IsValid
почти всегда ложноЭлементы формы для элементов коллекции часто имеют одинаковые имена, поэтому в этой демонстрации каждыйLine1
вShippingAddresses
сбор дампов на страницу какname="addr_Line1"
вместо чего-то вродеShippingAddresses[0]_Line1
как я и ожидал.