0

I have a viewmodel that contains a List, such as this:

class School
{
    public List<Student> Students { get; set; }
}
class Student
{
    public int Id { get; set; } 
    public String Name { get; set; } 
}

I have a form on which I am submitting multiple students info related to single school. Now I can add/remove a single student from the form.

Adding works fine, but my issue and my question is related to deletion of a student.

So let me explain this with an example:

Lets say I add 3 students then there names and Ids will be binded to the model in this way:

Students[0].Id = "1"

Students[0].Name = "Student A"

Students[1].Id = "2"

Students[1].Name = "Student B"

Students[2].Id = "3"

Students[2].Name = "Student C"

If I save this it works just fine. But lets say I delete the student with Id ="2".On submitting what is happening is that only the student with id = "1" is getting binded and rest after deleted index(that is student with id="3") is not getting binded.

My question is that : Is it at all possible to bind that id="3" after deletion of id="2" ? Or In proper terms is it possible to bind/submit a list with skipped indices.

I found below mentioned articles on stackoverflow itself but what I can infer from them is bit contradicting or maybe I am not understanding them properly.

Skipping Not possible

Skipping possible

I am not good with explaining problems. So please tell me if I can add anything to make it more descriptive.
Thank you. Example Delete Code: Fiddle for delete Js code

Mudit Garg
  • 36
  • 8
  • Currently as a fix I have added a boolean property named IsDeleted in my student model and On click of delete button I am just making it IsDeleted true and hiding the content from Ui – Mudit Garg Apr 09 '19 at 08:23
  • What do you mean by "binded", are you saying that when you delete student with ID=2 then the ID=3 also gets removed from the list? Also all your list index are 0, probably a typo? – peeyush singh Apr 09 '19 at 08:41
  • Also if you can post the code for adding/deleting the items it would be more useful, without the code its difficult to tell where the problem lies – peeyush singh Apr 09 '19 at 08:43
  • By binding I mean that on clicking of "Submit" button the values that are being posted. So if I delete student with Id = "2" only Students[0].Id and Students[0].Name are getting posted to server and rest is not posted – Mudit Garg Apr 09 '19 at 10:26
  • I have added the simple html/js code for add/delete. So if I add 5 student and delete 1 at index[3] then just the values till index [2] are being posted. Hopefully this is a little more useful. – Mudit Garg Apr 09 '19 at 10:52

1 Answers1

0

I am posting this answer for future reference for anyone else who is having same doubts.

So if you have a collection like this:

public class Book {
    public string Title { get; set; }
    public string Author { get; set; }
    public DateTime DatePublished { get; set; }
}

//Action method on HomeController
public ActionResult UpdateProducts(ICollection<Book> books) {
    return View(books);
}

And your form after adding 3 books looks like this:

<form method="post" action="/Home/Create">

    <input type="text" name="[0].Title" value="Curious George" />
    <input type="text" name="[0].Author" value="H.A. Rey" />
    <input type="text" name="[0].DatePublished" value="2/23/1973" />

    <input type="text" name="[1].Title" value="Code Complete" />
    <input type="text" name="[1].Author" value="Steve McConnell" />
    <input type="text" name="[1].DatePublished" value="6/9/2004" />

    <input type="text" name="[2].Title" value="The Two Towers" />
    <input type="text" name="[2].Author" value="JRR Tolkien" />
    <input type="text" name="[2].DatePublished" value="6/1/2005" />

    <input type="submit" />
</form>

Now If you guys want to add delete functionality such that your form might contain non-sequential entries, then something like this can be done:

<form method="post" action="/Home/Create">

    <input type="hidden" name="products.Index" value="cold" />
    <input type="text" name="products[cold].Name" value="Beer" />
    <input type="text" name="products[cold].Price" value="7.32" />

    <input type="hidden" name="products.Index" value="123" />
    <input type="text" name="products[123].Name" value="Chips" />
    <input type="text" name="products[123].Price" value="2.23" />

    <input type="hidden" name="products.Index" value="caliente" />
    <input type="text" name="products[caliente].Name" value="Salsa" />
    <input type="text" name="products[caliente].Price" value="1.23" />

    <input type="submit" />
</form>

In the example above, we provide a hidden input with the .Index suffix for each item we need to bind to the list. This will give the model binder a nice collection of indices to look for when binding to the list.

Mudit Garg
  • 36
  • 8
  • More Info on the same can be found here. https://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ – Mudit Garg Apr 10 '19 at 05:05