Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Model.List is null on POST using Razor

Tags:

c#

asp.net-mvc

My view:

@foreach(var item in Model.List)
{
  @Html.HiddenFor(model => item.UserId)
  @Html.HiddenFor(model => item.Name)
  @Html.HiddenFor(model => item.Age)

  @Html.CheckBoxFor(model => item.IsChecked, new { id = item.UserId })
  <label>@item.Name</label>
}

My controller:

[HttpPost]
public ActionResult Create(MyModel Model)
{
..

Model.List is null?

The list populates okay on GET. However, on POST (this particular View is a form) Model.List is null. I've tried using the HiddenFor helper, but have not yet succeeded.

Any suggestions / answers are appreciated. Thanks.

like image 229
Rhys Avatar asked Aug 06 '14 11:08

Rhys


People also ask

Are model user and profilesettings null?

Model.user and model.profilesettings are null. – pookie Jan 26 '15 at 23:44 | Show 3more comments 4 Answers 4 ActiveOldestVotes 2

How do I bind a model to a form in Razor pages?

Razor Pages provides two approaches to leveraging model binding. The first approach involves adding parameters to the handler method. The parameters are named after the form fields, and given an appropriate type for the expected data.

What is pagemodel in ASP NET Core Razor pages?

Note: For beginners in ASP.Net Core Razor Pages, please refer my article ASP.Net Core Razor Pages: Hello World Tutorial with Sample Program example. Following is a Model class named PersonModel with two properties i.e. FirstName and LastName. The PageModel consists of two Action Handler methods.

How to display the value of the name property in razor?

Note: In the Razor PageModel, the Handler method name is OnPostSubmit but here it will be specified as Submit when calling from the Razor HTML Page. Finally, the value of the Name property is displayed using Razor syntax.


1 Answers

You need to use a for loop instead of a foreach loop for data binding to work correctly with collections.

So instead of doing a foreach loop, change your code to something like this:

@for (var i = 0; i < Model.List.Count(); i++)
{
  @Html.HiddenFor(model => Model.List[i].UserId)
  @Html.HiddenFor(model => Model.List[i].Name)
  @Html.HiddenFor(model => Model.List[i].Age)

  @Html.CheckBoxFor(model => Model.List[i].IsChecked, new { id = Model.List[i].UserId })
  <label>@Model.List[i].Name</label>
}

This enables the ModelBinder to track the index of the item in your collection you're trying to bind.

If you look at the generated HTML when you have done this, you will notice that the generated input controls will look something like this:

<input type="hidden" name="List[0].IsChecked" />

This enables the model binder to know to which item in the list, it is binding to.

like image 108
Mark Avatar answered Sep 22 '22 06:09

Mark