Question

I have Model class "Customer". One of its properties is a collection of object lets say "Order". I want that during edit I can modify the list of orders associated with the selected Customer that I want to update but when I submit the modified customer and modified orders the order object is null. Please help how can I send the modified orders on edit. Here's my code

Class

  public class Customer
    {
        public int CustomerId { get; set; }
        public string CustomerName { get; set; }
        public List<Order> Orders { get; set; }
    }

    public class Order
    {
        public int OrderId { get; set; }
        public string OrderName { get; set; }
    }

Edit View

@model MVCTestApp.Models.Customer
@{
    ViewBag.Title = "Edit";
}

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Customer</legend>
        @Html.HiddenFor(model => model.CustomerId)
        <div class="editor-label">
            @Html.LabelFor(model => model.CustomerName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.CustomerName)
            @Html.ValidationMessageFor(model => model.CustomerName)
        </div>
        @foreach (var order in Model.Orders)
        {
            <div class="editor-label">
                @Html.Label(order.OrderName)
            </div>
            <div class="editor-field">
                @Html.Editor(order.OrderName, new { id = order.OrderId })
            </div>
        }
        <p><input type="submit" value="Save" /> </p>
    </fieldset>
}

Submitted Edited View

enter image description here

enter image description here

Was it helpful?

Solution

Use a for-loop instead of foreach:

@for (var i=0;i<Model.Orders.Count();i++)
{
    <div class="editor-label">
        @Html.Label(Model.Orders[i].OrderName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(m=> Model.Orders[i].OrderName)
    </div>
}

The reason for this issue can be easily seen on the rendered html of the foreach approach. The names of the elements do not have an index and they all have the same name. The model binder cannot infer how to pass it to your controller. Using a for-loop you are somewhat forcing (if that's the right term) the markup/html to have an index on your Orders objects. Having done that, the model binder can now properly map your inputs to the Orders field.

Oh by the way. Now that you are using a for-loop you need to verify that your Orders collection is not null. But I'm sure you can easily do that.

OTHER TIPS

I'd recommend you to get orders in action like this:(check if order_OrderName is the name of the input filed in form, see the source for example with firebug or something)

public ActionResult Edit(int id, string[] order_OrderName , Customer customer )
{
  //////
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top