Some Background
What you want to do is not hard but you need to have a good understanding of web and MVC so you can make this to work. I will try and explain.
When the user requests the view, the request will arrive at your controller and your controller will return a view to the user like shown below:
public ActionResult Index()
{
students.Add(new Student());
return View(students);
}
// Hypothetical Student class
public class Student
{
public string Name { get; set; }
}
And here is the razor view:
@model Student
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<form>
@Html.TextBoxFor(model => model.Name)
<input type="submit" />
</form>
That razor view will be rendered by the MVC engine and HTML will be returned to the user. The part we are interested in is shown below:
<form>
<input name="Name" type="text" value="">
<input type="submit">
</form>
Please note the name
of input
above is Name
. When the user fills out the form and submits it, it will post the value of the Name
to the backend controller.
Your Problem
You are adding NOT one student like above, but many students. So here is what you need to do. When the request initially comes, you need to return a view that has a list of students but the list has only one student like shown below:
public ActionResult Index()
{
var students = new List<Student>();
students.Add(new Student());
return View(students);
}
And here is the razor view:
@model List<Student>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<form>
@for (int i = 0; i < this.Model.Count(); i++)
{
@Html.TextBoxFor(model => this.Model[i].Name)
}
<input type="submit" />
</form>
Please note the for
loop. If you use foreach
, it will not work. Here is the HTML which will be rendered by the MVC engine:
<form>
<input name="[0].Name" type="text" value="">
<input type="submit">
</form>
Please note that now the name
is [0].Name
. In plain English, this input box is for the name of the student at index 0 (first student).
So in JavaScript code, you need to add more input
boxes like above but you need to make sure they are named like [1].Name
, [2].Name
and so on. You need to do that for each and every property not just for Name
.
Then when the user posts the form, you need an action which will serve a POST request for one or many students. Here is the what the controller action should look like:
[HttpPost]
public ActionResult Index(List<Student> students) { ... }
The DefaultModelBinder for MVC will figure out that the form which is posted has elements such as [x].Name
within the form so it is smart enough to take each element and create Student
objects from it and then add it to the a list and pass it to the above action.