Допустим, у вас есть следующий объект:
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
почти всегда falseLine1
в коллекции ShippingAddresses
сбрасывается на страницу как name="addr_Line1"
вместо чего-то вроде ShippingAddresses[0]_Line1
, как я ожидал.