-1

I pass a List to a partial view and it works fine, it shows all the data but when I save the Model, the List returns null, what am I missing?

  • Dont pay attention to the objects, I wrote fake ones for the example.

This the cshtml:

@model ViewModels.StudentVM

@using (Html.BeginForm("SaveStudent", "StudentsView", FormMethod.Post}))
{
    @Html.AntiForgeryToken();
    <div class="row">
        <span>Student name:</span>
        @Html.TextBoxFor(s => s.Name)
    </div>
    <div>
        @Html.Partial("StudentsList", Model.Students)
    </div>
    <div class="form-group">
        <input type="submit" value="Save" class="btn">
    </div>
}

When loading the view I get all the students to the View Model:

vm.Students = await _studentController.GetAllStudents(); // returned 20 Students.

The partial view:

@model IEnumerable<Entities.Students>

<table class="table-bordered">
    @foreach (var item in Model)
    {
        <tr>
            <td>
               @Html.CheckBoxFor(modelItem => item.IsSelected)
            </td>
            <td>
               @Html.DisplayFor(modelItem => item.Name)
            </td>
        </tr>
    }
</table>

I would like to get all selected students, so lets say I will select 3 students. And then click on the save button. Result: the Model.Students is null although it I selected 3 students. How can I get those students?

Misha Zaslavsky
  • 8,414
  • 11
  • 70
  • 116
  • 1
    You cannot use a partial to generate controls for a complex object unless you pass the `HtmlFieldPrefix` (refer [this answer](http://stackoverflow.com/questions/29808573/getting-the-values-from-a-nested-complex-object-that-is-passed-to-a-partial-view/29809907#29809907)), but the correct approach is to use an `EditorTemplate` for typeof `Students` (refer [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) for an example) –  Aug 28 '16 at 22:21
  • 1
    And note a checkbox on its own wont post anything meaningful - you will need an input for the ID property of the `Students` object –  Aug 28 '16 at 22:22

2 Answers2

1

Your current code of partial view has only the Call to DisplayNameFor helper method which will only render the display name as a label. If you want to submit the data of each item, you need to generate input form fields with matching names with your view model property structure.

Assuming your StudentVM has a Students collection of type IEnumerable<Students>

If your HttpPost action method's parameter is of type StudentVm, you need to make sure that your partial view is generating the input form fields with name like 'Students[0].Name, 'Students[1].Name etc. You can use the Html.TextBox helper method and specify this custom names

@model IEnumerable<Students>
<table class="table-bordered">
    @{
        var counter = 0;
    }
    @foreach (var student in Model)
    {
        <tr>
            <th>Name</th>
            <td>@Html.TextBox("Students[" + counter + "].Name", student.Name)</td>
        </tr>
        counter++;
    }
</table>

If you are simply displaying the names of existing students, you do not need the text fields, you can simply display those inside the loop. In that case, when form submits,why do you worry about the Students collection being null ? You are trying to save a new Student which will be in .Name property. So if you need the existing students again (but why ? ), you can call the GetAllStudents method.

Shyju
  • 214,206
  • 104
  • 411
  • 497
  • I forgot to write the main - I updated my post. I actually have a checkbox near each student and I want get all selected students but it returns null. For example: If I select 1 student then I will see in my List: Name: "Student Name", IsSelected: true. And all other students will be IsSelected: false. – Misha Zaslavsky Aug 28 '16 at 19:04
  • 1
    You should consider using editor templates. Take a look at [How to know the selected checkboxes from within the HttpPost Create action method?](http://stackoverflow.com/questions/38961222/how-to-know-the-selected-checkboxes-from-within-the-httppost-create-action-metho) – Shyju Aug 28 '16 at 19:15
  • @Shyju why not use a for loop instead of the counter? – Dawood Awan Sep 11 '16 at 17:51
0

maybe you used 2 Different model in view ...... you can use 2 model in 1 viewmodel It is not necessary partial view

ViewModels.StudentVM != IEnumerable<Entities.Students>

you can all data (many model) passed in 1 view model :

var vm = new TestViewModel();
vm.one = db.one.tolist();
vm.two = db.two.tolist();