Редактирование и сохранение сложных объектов

Скажем, у вас есть следующий объект:

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 как я и ожидал.

Ответы на вопрос(1)

Ваш ответ на вопрос