Скажем, у вас есть следующий объект:
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» на этой странице, но сначала мне нужно сохранить, чтобы работать - KISS)
Проблемы:
ModelState.IsValid
почти всегда ложно - Элементы формы для элементов коллекции часто имеют одинаковые имена, поэтому в этой демонстрации каждый
Line1
в коллекции ShippingAddresses
выводит на страницу как name="addr_Line1"
вместочто-то вроде ShippingAddresses[0]_Line1
, как я ожидал.