Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

278
Views
Asp.net MVC 4.5 Add Object to List in ViewModel with EditorFor, Button Click

I'm currently working on an ASP.NET MVC 4.5 application. I want to add objects to a List<T> dynamically on a button click, using a @Html.EditorFor and send the data to the Controller with a Form submit.

However, my problem, only the 1st element of the populated list gets sent to the controller when I submit my Form.

The area in my view where I add Elements looks like this:

<div id="addTarget" data-target="@Url.Action("AddTarget", "Offer")">

    @for(var i = 0; i < Model.Targets.Count(); i++)
    {
        @Html.EditorFor(m => m.Targets[i])
    }
</div>

My Controller looks like that:

...

public OfferVm NewOffer { get; set; } = new OfferVm();

[HttpGet]
public ActionResult Create()
{
    // ...here I add my first initial target to OfferVm
    NewOffer.Targets.Add(new TargetVm());

    return View(NewOffer);
}

public ActionResult AddTarget()
{
    // ...here I add a target to my NewOffer
    NewOffer.Targets.Add(new TargetVm());
    return PartialView("~/Views/Shared/EditorTemplates/TargetVm.cshtml");
}

[HttpPost]
public ActionResult Create(OfferVm offerVM)
{
   //... here only 1 target is in my offerVM
}

My OfferVm class looks like this:

public class OfferVm
{
    public OfferVm()
    {
        this.Targets = new List<TargetVm>();
    }

    public List<TargetVm> Targets { get; set; }
}

Do you have an idea how I can add a new target to my NewOffer.Targets List, and get the data in my controller, when I post the form?

about 4 years ago · Santiago Trujillo
1 answers
Answer question

0

The reason only the first TargetVm in your collection is being bound in the POST method, is that your AddTarget() method your calling to add a new item is generating form controls with name that are identical to those your have previously generated. Assuming TargetVm has a property named ID, then your have multiple elements with

<input ... name="Targets[0].ID" ... />

and the DefaultModelBinder only binds the first name/value pair from the request, and ignores any subsequent duplicate names. In order to bind to a collection, your name attributes need to have indexers that start at zero and be consecutive.

<input ... name="Targets[0].ID" ... /> // first TargetVM
<input ... name="Targets[1].ID" ... /> // second TargetVM
<input ... name="Targets[2].ID" ... /> // third TargetVM

Note you can also include an extra input for each item in the collection - <input type="hidden" name="Targets.Index value="xx" /> (where xx is the value of the indexer) to bind non-consecutive indexers as discussed in Model Binding To A List.

Using the EditorFor() method will not work in the case where your dynamically adding new collection items, unless you were to use javascript to update the value of the indexer in the name attribute when its added.

Solutions include using a javascript MVVM framework such as knockout, using the BeginCollectionItem() helper, or using a client side template and javascript to dynamically add new form controls. The latter two options are discussed in this answer, and a more complete example using BeginCollectionItem() is shown in this answer.

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!