joym8
joym8

Reputation: 4202

MVC model not binding on post

Can't figure out what I'm doing wrong. When the form in the view is posted the model properties turn out to be null.

Model

public class RegistrationModel
{
    public RegistrationModel()
    {
        Registration = new REGISTRATION();
        AddPayment = true;
    }
    public REGISTRATION Registration { get; set; }
    public bool AddPayment { get; set; }
}

View

@model Client.Models.RegistrationModel

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(excludePropertyErrors: false)

    <div class="form-group">
        @Html.DropDownList("SECTION_ID", null, string.Empty, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.DropDownList("STUDENT_ID", null, string.Empty, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.DropDownList("STATUS_ID", null, string.Empty, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.CheckBoxFor(model => model.AddPayment)
    </div>

    <p>
        <input type="submit" class="btn btn-success" value="Create" />
    </p>
}

Controller

    public ActionResult Create()
    {
        //code to populate view dropdowns
        return View();
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(RegistrationModel model)
    {
        WriteFileLog(_logPath, Newtonsoft.Json.JsonConvert.SerializeObject(model));
    }

In the controller's Create action that handles the post model properties are null.

Registration Class (autogenerated by EF from database):

public partial class REGISTRATION
{
    public REGISTRATION()
    {
        this.REGISTRATION_AUDIT = new HashSet<REGISTRATION_AUDIT>();
    }

    public int ID { get; set; }
    public int SECTION_ID { get; set; }
    public int STUDENT_ID { get; set; }
    public int STATUS_ID { get; set; }

    public virtual ICollection<REGISTRATION_AUDIT> REGISTRATION_AUDIT { get; set; }
    public virtual SECTION SECTION { get; set; }
    public virtual V_REGISTRATION_STATUS V_REGISTRATION_STATUS { get; set; }
    public virtual PERSON PERSON { get; set; }
}

Upvotes: 0

Views: 4249

Answers (1)

Tieson T.
Tieson T.

Reputation: 21191

I would recommend using the strongly-typed helpers, like so:

@Html.DropDownListFor(m => m.Registration.SECTION_ID, null, string.Empty, new { @class = "form-control" })

Otherwise, you need to adjust the names you're using to

@Html.DropDownList("Registration.SECTION_ID", null, string.Empty, new { @class = "form-control" })

You can probably simplify what you're doing by duplicating the Registration class's members into your view model, replacing the Registration property.

As @StephenMuecke points out, you're missing a few parts from your model/markup. The template for the DropDownList helper you're using is

DropDownListFor(
    [model property to bind], 
    [collection of possible values to bind], 
    [option label], 
    [HTML attributes])

Passing null for that second parameter means you have no values to populate the generated <select> element with, and should normally generate an exception.

I'm not a fan of using ViewBag to pass collections into the view, so I'd recommend something like

public class RegistrationModel
{
    public RegistrationModel()
    {
        Registration = new REGISTRATION();
        AddPayment = true;
    }
    public REGISTRATION Registration { get; set; }
    public bool AddPayment { get; set; }

    public SelectList Sections { get; set; }

    public SelectList Students { get; set; }

    public SelectList Statuses { get; set; }
}

and then adjust the markup accordingly:

@Html.DropDownListFor(m => m.Registration.SECTION_ID, Model.Sections, string.Empty, new { @class = "form-control" })

Upvotes: 1

Related Questions