Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

View model with complex type is null when passed to controller

I am trying to pass a view model with complex types to my controller. I have researched everything I can top to bottom over this subject and I am still confused.

The Problem:

When I click my submit button, the view model is passed in but the List of MacroInfo property is null.

UpdateIndexViewModel

public class UpdateIndexViewModel
{
    //This view model will become larger later
    public List<MacroInfo> MacrosToUpdate { get; set; }
}

MacroInfo

public class MacroInfo
{
    public bool IsSelected { get; set; }
    public string FullPath { get; set; }
    public string Id { get; set; }
    public DateTime CreatedAt { get; set; }
}   

Controller Action

[HttpPost]
public ActionResult Submit(UpdateIndexViewModel updateIndexViewModel)
{
    //updateIndexViewModel.MacrosToUpdate is null ??
}

Index View

@model EplanInterface.Core.ViewModels.UpdateIndexViewModel

@using (Html.BeginForm("Submit", "Update", FormMethod.Post))
{
    <table style="width:100%" , class="table-bordered">
        <thead>
            <tr>
                <th>#</th>
                <th>Macro Path</th>
                <th>Created At</th>
                <th>Update</th>
            </tr>
        </thead>
        @for (int i = 1; i < Model.MacrosToUpdate.Count; i++)
        {
            <tr>
                <td>@Html.TextBoxFor(m =>Model.MacrosToUpdate[i].FullPath)</td>
                <td>@Html.TextBoxFor(m => Model.MacrosToUpdate[i].CreatedAt)</td>
                <td>@Html.CheckBoxFor(b => Model.MacrosToUpdate[i].IsSelected)</td>
            </tr>
        }
    </table>
    <input type="submit" class="btn btn-primary" value="Submit"/>
}

What I have tried

I tried changing the controller actions property being passed in to List<MacroInfo> macrosToUpdate, but when doing this the property is still null.

Chrome network inspection

enter image description here

Final Remarks

I am not sure if I need to be using an AJAX post to do this, or if my variable names just are not formatted correctly. I am pretty sure it is a binding issue I am not understanding.

If anyone could point me in the right direction I would really appreciate it.

like image 238
JKufa Avatar asked Aug 08 '19 19:08

JKufa


1 Answers

This part of your template is bit wrong.

@for (int i = 1; i < Model.MacrosToUpdate.Count; i++)
{
    <tr>
        <td>@Html.TextBoxFor(m =>Model.MacrosToUpdate[i].FullPath)</td>
        <td>@Html.TextBoxFor(m => Model.MacrosToUpdate[i].CreatedAt)</td>
        <td>@Html.CheckBoxFor(b => Model.MacrosToUpdate[i].IsSelected)</td>
    </tr>
}

Please change with following and try again.

@for (int i = 0; i < Model.MacrosToUpdate.Count; 
{
        <tr>
            <td>@i</td>
            <td>@Html.TextBoxFor(m => m.MacrosToUpdate[i].FullPath)</td>
            <td>@Html.TextBoxFor(m => m.MacrosToUpdate[i].CreatedAt)</td>
            <td>@Html.CheckBoxFor(b => b.MacrosToUpdate[i].IsSelected)</td>
        </tr>
 }

First you were starting the loop with 1, which was the root cause. Model binder wasn't able to bind the list properly due to missing zeroth index.

like image 171
Muhammad Hannan Avatar answered Nov 04 '22 01:11

Muhammad Hannan