Miguel Moura
Miguel Moura

Reputation: 39374

Model properties are null when the form is submitted

On an ASP.NET MVC 5 project I have the following model:

public class ScheduleIndexModel {

  public IPageList<DataModel> Data { get; set; }
  public FormModel Form { get; set; }

  public class DataModel {
    public Int32 Id { get; set; }
    public String[] Attendees { get; set; }
    public String Location { get; set; }
    public DateTime Date { get; set; }
  } // DataModel

  public class FormModel {      
    public String Location { get; set; }
    public String Date { get; set; }      
  } // FormModel

}

The view is the following:

<form action="@Url.Action(MVC.Schedule.Index())" method="post">
  @Html.LabelFor(x => x.Form.Date, "Date")
  @Html.TextBoxFor(x => x.Form.Date)
  @Html.LabelFor(x => x.Form.Location, "Location")
  @Html.TextBoxFor(x => x.Form.Location)
  @Html.SubmitButton("Filter", "Index", new { @class = "submit" })
  @Html.AntiForgeryToken()
</form>

Then the HTTPPost controller action is as follows:

[HttpPost]
public virtual ActionResult Index(ScheduleIndexModel.FormModel model, Int32 p = 1) {
  return View();
} // Index

When I submit the form the model is not null but its properties are even if I write something on the TextBoxes.

Does anyone knows what am I doing wrong?

Upvotes: 1

Views: 696

Answers (2)

Big Daddy
Big Daddy

Reputation: 5224

You may need to use a binding prefix because your viewmodel is nested. Something like this may work:

public virtual ActionResult Index([Bind(Prefix = "Form")] FormModel model) 

Upvotes: 1

user3559349
user3559349

Reputation:

Your html helpers (e.g. @Html.TextBoxFor(x => x.Form.Date) will be generating html like this

<input name="Form.Date" .../>

but because your post method accepts parameter of type FormModel it cant match up (FormModel only has property Date, not property Form that has property Date).

You can either change you action method to

public virtual ActionResult Index(ScheduleIndexModel model,... 
{
  FormModel form = model.Form; // get the FormModel

or use the [Bind(Prefix..)] as suggested by Big Daddy

Upvotes: 1

Related Questions