Vikram
Vikram

Reputation: 2069

Passing a List from View to Controller in Model

I am trying to pass a complex data structure from Controller to View and Back to Controller which contains Lists. I can see the list items in View. I want to edit those and send it back to the controller. I am able to edit some properties but for lists, I am getting null value in the controller.

Here is an example (simulation) of what I am trying to achieve:

Consider Model -

using System.Collections.Generic;

namespace WebApplication1.Models
{
    public class StudentViewModel
    {
        public string StudentId { get; set; }
        public string FeedBack { get; set; }
        public List<ScoreCard> ScoreCards;
    }

    public class ScoreCard
    {
        public string Subject { get; set; }
        public string Marks { get; set; }
    }
}

Controller -

public class StudentController : Controller
{
    public ActionResult Index()
    {
        var model = new StudentViewModel();
        model.StudentId = "Some Student";
        model.ScoreCards = new List<ScoreCard>
        {
            new ScoreCard()
            {
                Marks = "0",
                Subject = "English"
            },
            new ScoreCard()
            {
                Marks = "0",
                Subject = "Maths"
            }
        };
        return View("View", model);
    }

    public ActionResult SubmitScore(StudentViewModel model)
    {
        /* Some Code */
    }
}

View -

@model WebApplication1.Models.StudentViewModel
@{
    ViewBag.Title = "Title";
}

@using (Html.BeginForm("SubmitScore", "Student", FormMethod.Post))
{
    @Html.DisplayName(@Model.StudentId)<br />
    <label>Comment:</label><br/>
    @Html.EditorFor(m => m.FeedBack, new { htmlAttributes = new { @type = "text", id = @Model.FeedBack} })<br />
    for (var i = 0; i < @Model.ScoreCards.Count; i++)
    {
        @Html.DisplayName(@Model.ScoreCards[i].Subject) <br/>
        @Html.EditorFor(m => m.ScoreCards[i].Marks, new { htmlAttributes = new { @type = "number", @min = 0, id = @Model.ScoreCards[i].Marks} })<br />
    }
    <input class="btn btn-primary" type="submit" value="Submit" />
}

When I run the application -

enter image description here

When I click submit, I am able to see model.FeedBack but the list is set to null.

enter image description here

Something similar is achieved in this question & it's answer; I am not sure what exactly I am missing here.

Upvotes: 2

Views: 3489

Answers (1)

Nkosi
Nkosi

Reputation: 247581

you send no input for the Subject . You'll need a hidden input for that along with any other value you want returned to the controller when the form is posted. Also a simple text box should work for the marks.

@using (Html.BeginForm("SubmitScore", "Student", FormMethod.Post))
{
    @Html.DisplayName(@Model.StudentId)<br />
    @Html.HiddenFor(m => m.StudentId)
    <label>Comment:</label><br/>
    @Html.EditorFor(m => m.FeedBack, new { htmlAttributes = new { @type = "text", id = @Model.FeedBack} })<br />
    for (var i = 0; i < @Model.ScoreCards.Count; i++) {
        @Html.HiddenFor(m => m.ScoreCards[i].Subject)
        @Html.DisplayName(@Model.ScoreCards[i].Subject) <br/>
        @Html.TextBoxFor(m => m.ScoreCards[i].Marks, new { htmlAttributes = new { @type = "number", @min = 0} })<br />
    }
    <input class="btn btn-primary" type="submit" value="Submit" />
}

Finally you need to use properties in order for the model binding to work. You currently have ScoreCards as a field so update it to a property.

public class StudentViewModel {
    public string StudentId { get; set; }
    public string FeedBack { get; set; }
    public List<ScoreCard> ScoreCards { get; set; }
}

Upvotes: 2

Related Questions