0

I'd like to have a form which related to a object + a list of object with property related

ex : Name and for each x items : Active or not / Price

Note : I know the number of items, it is related to another table. All the data can be edited by the user.

How can I achieve this with ASP .Net MVC ?

public class AddChargeModel
{
    [Required]
    [Display(Name = "Name")]
    public string Nom { get; set; }
    [Required]
    public List<ChargeLotModel> ChargeLot;
}

public class ChargeLotModel
{
    [Required]
    [Display(Name = "IdLot")]
    public int IdLot { get; set; }
    [Display(Name = "Price")]
    public decimal Price { get; set; }
    [Display(Name = "Active")]
    public bool Active { get; set; }
}

I associate the class AddChargeModel with my view :

@model Models.AddChargeModel
@using (Html.BeginForm())
{
  <label>@Html.LabelFor(m => m.Name)</label>
  @Html.EditorFor(m => m.Name)
  @Html.ValidationMessageFor(m => m.Name)

  <table>
   <tr>
    <th>Price</th>
    <th>Active</th>
   </tr>
   @for (var lotindex = 0; lotindex < ViewData.Model.ChargeLot.Count(); lotindex++)
   {
    <tr>
     <td>@Html.EditorFor(model => model.ChargeLot[lotindex].Price) @Html.HiddenFor(model => model.ChargeLot[lotindex].IdLot)</td>
     <td>@Html.EditorFor(model => model.ChargeLot[lotindex].Active)</td>
    </tr>
    }
   </table>
   <input type="submit" value="Valider" class="button" />
}

When I click on the button, then I enter in the controller function :

[HttpPost]
public ActionResult Add(AddChargeModel model)
{
   ...
}

model.Name is filled but not model.ChargeLot == null.

The controls in the array are named like ChargeLot_0__Price on the web page. (and it should work if I well understood)

Do you have the solution to make it work ?

P. Sohm
  • 2,842
  • 2
  • 44
  • 77
  • This was discussed in this thread, take a look: http://stackoverflow.com/questions/11267354/how-to-produce-non-sequential-prefix-collection-indices-with-mvc-html-editor-tem/11267659#11267659 – MiBu Jun 11 '13 at 22:06

1 Answers1

2

Your ChargeLot "property" has no getter or setter, so the model binder can't fill it with the posted data. It's just a standard instance variable rather than a property, and nothing on your model ever sets it. You need instead:

public List<ChargeLotModel> ChargeLot { get; set; }
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Not only that, problem is binding the lists because of indexes. He needs to have different Id/-name for every property of every item in list. It's easy to achieve with some mvvm js framework, else he needs to do something like http://stackoverflow.com/questions/11267354/how-to-produce-non-sequential-prefix-collection-indices-with-mvc-html-editor-tem/11267659#11267659 – MiBu Jun 11 '13 at 22:07
  • @MiBu: No. The form inputs are already named like `ChargeLot_0__Price`. That is the format the model binder expects for relationships. The OP's view code is fine. – Chris Pratt Jun 11 '13 at 22:10
  • I'm not 100% sure if it's correct... shouldn't it be AddChargeModel.ChargeLot instead of just ChargeLot? – MiBu Jun 11 '13 at 22:28
  • Nope. Just the property name. – Chris Pratt Jun 12 '13 at 17:20