Default model binding throwing "No paramaterless constructor defined for this object"

asp.net-mvc, asp.net-mvc-3, asp.net-mvc-4

Solution

Without a doubt it is the `SelectList`. I had the same problem just yesterday.

If you look at the SelectList all of it's constructors require a parameter. http://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist(v=vs.108).aspx

The problem is when your `Action` is called `public ActionResult Index(TradeSpendingEntryViewModel vm)`

The controller tries to bind the data sent back on `POST` to `TradeSpendingEntryViewModel` upon which it needs to set the value for `PlanningYears` which it tires to do by creating a new `SelectList`

To fix the problem, you either need to make the SelectList a private variable aka a backing field, and then set it to an empty list by default. This gives it the parameterized constructor it needs:

    //select list
    private SelectList planningYears = new SelectList(new List<YourObject>());

    public SelectList PlanningYears 
    {
        get
        {
            return planningYears;
        }
        set
        {
            locations = planningYears;
        }
    }

Or change PlanningYears to a List<> and convert it to a select list on the view.

@Html.DropDownListFor(m => m.PlanningYears , new SelectList(Model.PlanningYears ), "choose", null)

Problem

I have a form where we want to enter multiple deals for a single customer. The viewmodel for the form looks like this: ``` public class TradeSpendingEntryViewModel { public TradeSpendingEntryViewModel() { Records = new List<TradeSpendingEntryViewModelRecord>(); } public string CustomerNumber { get; set; } public DateTime Date { get; set; } public SelectList PlanningYears { get; set; } public List<TradeSpendingEntryViewModelRecord> Records { get; set; } } ``` We want to be able to add and remove record entry rows dynamically with javascript. Each record in the collection is: ``` public class TradeSpendingEntryViewModelRecord { public TradeSpendingEntryViewModelRecord() { } public string LOB { get; set; } public string ProductCode { get; set; } public SelectList AllowType { get; set; } public int Cases { get; set; } public bool EndCurrentDeal { get; set; } public Single DealRate { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Comments { get; set; } } ``` When I attempt to post data to my controller, I get an error indicating "No parameterless constructor defined for this object: ``` [HttpPost] public ActionResult Index(TradeSpendingEntryViewModel vm) { try { if (ModelState.IsValid) { return RedirectToAction("Index"); } // TODO: Add insert logic here return View(vm); } catch { return View(); } } ``` Stack trace indicates it happens during the model binding: [MissingMethodException: No parameterless constructor defined for this object.] System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232 System.Activator.CreateInstance(Type type, Boolean nonPublic) +83 System.Activator.CreateInstance(Type type) +6 System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +183 My issue must be stemming from how I've setup my view, the markup of which I have based off this article http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx ``` @using (Html.BeginForm()) { <header class="clearfix"> <img src="../../Content/images/logo.png" alt="Irving Consumer Products" /> <h1>Enter Customer Deals</h1> </header> <hr /> <fieldset> <legend>Customer details</legend> <table> <tr> <th> Date: </th> <td> <input type="date" disabled="disabled" value="@DateTime.Today.ToShortDateString()" /> </tr> <tr> <th> Customer Number: </th> <td> @Html.TextBoxFor(m => m.CustomerNumber, new { id = "customer-number" }) <a href="#" id="change-customer-number">Change me</a> </td> </tr> <tr> <th> Customer Name: </th> <td> <input type="text" id="customer-name" disabled="disabled" /> </td> <tr> <th> Planning Year: </th> <td> @Html.DropDownList("PlanningYear", Model.PlanningYears) <a href="#" id="change-planning-year">Change me</a> </td> </tr> </table> </fieldset> <div class="buttonGroup"> <input type="button" value="Add line" id="add-line"> <input type="button" value="Copy line" id="copy-line"> <input type="button" value="Delete line" id="delete-line"> </div> <hr /> <table id="tradeSpendingEntry"> <thead> <tr> <th> </th> <th> Line of business </th> <th> Product Code </th> <th> Product Description </th> <th> Allowance <br /> Type </th> <th> Cases </th> <th> End Current Deal </th> <th> Start Date </th> <th> End Date </th> <th> Rate </th> </tr> </thead> @foreach (var r in Model.Records) { <tbody data-entry-index="0"> <tr> <td> <input type="checkbox" /> </td> <td> <input type="text" name="records[0].LOB" class="lobSelect" value="@r.LOB"> </td> <td> <!--<input type="hidden" name="records[0]ProductCodeSelected" value="@r.ProductCode" />--> <input type="text" name="records[0].ProductCode" value="@r.ProductCode"> </td> <td> <input type="text" class="product-description" disabled="disabled" /> </td> <td> @Html.DropDownList("records[0].AllowType", r.AllowType) </td> <td> <input name="records[0].Cases" type="number" /> </td> <td> <select name="records[0].EndCurrentDeal"> <option value="true" selected="selected">Yes</option> <option value="false">No</option> </select> </td> <td> <input type="date" name="records[0].StartDate" /> </td> <td> <input type="date" name="records[0].EndDate" /> </td> <td> <input type="text" name="records[0].DealRate" /> </td> </tr> <tr> <td></td> <td> Comments: </td> <td colspan="8"> <input type="text" class="comment" name="records[0].Comments" /> </td> </tr> </tbody> } </table> <footer> <div class="buttonGroup"> <input type="submit" value="Submit Changes"> <input type="button" value="Main Menu"> <input type="button" value="View Customer Deals"> </div> </footer> } ``` So, my hope was that the fields in the first fieldset would map to the immediate properties of the TradeSpendingEntryViewModel object (CustomerName, Date, PlanningYears). Then, for each representing a TradeSpendingEntryViewModelRecord would be bound as an item in the TradeSpendingEntryViewModel.Records collection. Instead, I just get a mysterious "No parameterless constructor defined" exception, despite both the ViewModel and the record object both having paramaterless constructors. My question is, can I use the default model binder using the conventions indicated in the aforementioned article, or do I need to build a custom model binder for this purpose? For completeness sake, the following is the markup of the form that gets generated after a user dynamically adds a line to the form via javascript: ``` <form method="post" action="/TradeSpendingEntry/Index"> <header class="clearfix"> <img alt="Irving Consumer Products" src="../../Content/images/logo.png"> <h1>Enter Customer Deals</h1> </header> <hr> <fieldset> <legend>Customer details</legend> <table> <tbody> <tr> <th> Date: </th> <td> <input id="dp1363608756704" class="hasDatepicker" type="date" value="18/03/2013" disabled="disabled" style="background-color: rgb(238, 238, 238);"> </td> </tr> <tr> <th> Customer Number: </th> <td> <input id="customer-number" type="text" value="" name="CustomerNumber"> <a id="change-customer-number" href="#">Change me</a> </td> </tr> <tr> <th> Customer Name: </th> <td> <input id="customer-name" type="text" disabled="disabled" style="background-color: rgb(238, 238, 238);"> </td> </tr> <tr> <th> Planning Year: </th> <td> <select id="PlanningYears" name="PlanningYears"> <option value="2011">2011</option> <option value="2012">2012</option> <option value="2013">2013</option> <option value="2014">2014</option> </select> <a id="change-planning-year" href="#">Change me</a> </td> </tr> </tbody> </table> </fieldset> <div class="buttonGroup"> <input id="add-line" type="button" value="Add line"> <input id="copy-line" type="button" value="Copy line"> <input id="delete-line" type="button" value="Delete line"> </div> <hr> <table id="tradeSpendingEntry"> <thead> <tr> <th> </th> <th> Line of business </th> <th> Product Code </th> <th> Product Description </th> <th> Allowance <br> Type </th> <th> Cases </th> <th> End Current Deal </th> <th> Start Date </th> <th> End Date </th> <th> Rate </th> </tr> </thead> <tbody data-entry-index="0"> <tr> <td> <input type="checkbox"> </td> <td> <input class="lobSelect" type="text" name="records[0].LOB"> </td> <td> <input type="text" name="records[0].ProductCode"> </td> <td> <input class="product-description" type="text" disabled="disabled" style="background-color: rgb(238, 238, 238);"> </td> <td> <select id="records_0__AllowType" name="records[0].AllowType"> <option selected="selected">BillBack$</option> <option>Billback%</option> <option>O&A%</option> <option>Coop%</option> <option>VR%</option> <option>Lump - O&A$</option> <option>Lump - CP$</option> <option>Lump - VR$</option> <option>Lump - BB$</option> </select> </td> <td> <input type="number" name="records[0].Cases"> </td> <td> <select name="records[0].EndCurrentDeal"> <option selected="selected" value="true">Yes</option> <option value="false">No</option> </select> </td> <td> <input id="dp1363608756707" class="hasDatepicker" type="date" name="records[0].StartDate"> </td> <td> <input id="dp1363608756708" class="hasDatepicker" type="date" name="records[0].EndDate"> </td> <td> <input type="text" name="records[0].DealRate"> </td> </tr> <tr> <td></td> <td> Comments: </td> <td colspan="8"> <input class="comment" type="text" name="records[0].Comments"> </td> </tr> </tbody> <tbody data-entry-index="1"> <tr> <td> <input type="checkbox"> </td> <td> <input class="lobSelect" type="text" name="records[1].LOB"> </td> <td> <input type="text" name="records[1].ProductCode"> </td> <td> <input class="product-description" type="text" disabled="disabled" style="background-color: rgb(238, 238, 238);"> </td> <td> <select id="records_0__AllowType" name="records[1].AllowType"> <option selected="selected">BillBack$</option> <option>Billback%</option> <option>O&A%</option> <option>Coop%</option> <option>VR%</option> <option>Lump - O&A$</option> <option>Lump - CP$</option> <option>Lump - VR$</option> <option>Lump - BB$</option> </select> </td> <td> <input type="number" name="records[1].Cases"> </td> <td> <select name="records[1].EndCurrentDeal"> <option selected="selected" value="true">Yes</option> <option value="false">No</option> </select> </td> <td> <input id="dp1363608756709" class="hasDatepicker" type="date" name="records[1].StartDate"> </td> <td> <input id="dp1363608756710" class="hasDatepicker" type="date" name="records[1].EndDate"> </td> <td> <input type="text" name="records[1].DealRate"> </td> </tr> <tr> <td></td> <td> Comments: </td> <td colspan="8"> <input class="comment" type="text" name="records[1].Comments"> </td> </tr> </tbody> </table> <footer> <div class="buttonGroup"> <input type="submit" value="Submit Changes"> <input type="button" value="Main Menu"> <input type="button" value="View Customer Deals"> </div> </footer> </form> ```

Original source