0

My MVC page is used for both Insert and Update. So far it works fine for displaying the data but when the submit button is clicked, it errors:

 "No parameterless constructor defined for this object."

 MissingMethodException: No parameterless constructor defined for this object.]

It will hit the paramaterless constructor, it is commented out right now. There are 50 extra fields on the viwemodel that are used for display only and not needed in insert/update. There are less form fields on the form than in the viewmodel.

Is there working code example that handle this situation? I have seen the accepted answer here that may work, but I need a complete working example since I'm new to do this:

ASP.NET MVC - Proper usage of View Model and Command pattern

    <form action="/incident/SaveIncident" method="post">  
       <div>
                <input class="btn btn-primary" type="submit" value="SubmitSave" />
               <br />
                 <select id="drpSite">
                        <option value="0">Pick a site...</option>
                        @foreach (var site in Model.Sites)
                        {
                            <option value="@site.SiteId">
                                @site.SiteName
                            </option>
                        }
                    </select>
                   <br />
                   upsert:@Html.TextBoxFor(model => model.objIncidentUpsert.UpsertBemsId, new { @class = "form-control" })
                  <br /> 
                  viewBOIncDesc1: @Html.TextBoxFor(model => Model.objIncident.IncidentModel.IncidentDescription1, new { @class = "form-control" })) 
       </div>
    </form>

IncidentViewModel.cs

    public class IncidentViewModel
{
    public int IncidentId { get; set; }
    public IncidentModelBO objIncident  { get; set; }
    public IncidentModelUpsert objIncidentUpsert { get; set; }
    public IncidentViewModel(int incidentId)
    {
        if (incidentId == 0)
        {
            objIncident = new IncidentModelBO();
        }
        else
        {
            IncidentId = incidentId;
            objIncident = IncidentModelBO.Get(incidentId);
        }
    }

     public IEnumerable<SiteModel> Sites {get; set;}
}

IncidentController.cs:

    //[HttpPost]
    //[ActionName("SaveIncident")]
    //public ActionResult SaveIncident()
    //{
    //    return new HttpStatusCodeResult(400, "Problem with inputxxx ");
    //}

    [HttpPost]
    [ActionName("SaveIncident")]
    public ActionResult SaveIncident(IncidentViewModel objIncidentBO)
    {
        string loggedinbemsid = System.Web.HttpContext.Current.Session[Utility.SessionKeyIndex.BEMSID.ToString()].ToString();
        try
        {

            objIncidentBO.objIncident.Create(loggedinbemsid, null);

            IncidentViewModel vwIncidentData = new IncidentViewModel(objIncidentBO.objIncident.IncidentModel.IncidentId);
            return View("index", vwIncidentData);
        }
        catch (Exception e)
        {
            return new HttpStatusCodeResult(400, "Problem with input: " + e.Message);
        }
Community
  • 1
  • 1
Remy
  • 407
  • 3
  • 17
  • As Robert's answer states, you must have a parameterless constructor, because the `DefaultModelBinder` initializes you model(s) using `Activator.CreateInstance()` which throws the exception if you do not have one. But despite the name of your model, its is not a view model in the context of MVC. A view model should not contain data models and never contain database access code. Suggest you read [What is ViewModel in MVC?](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) –  Apr 03 '16 at 22:43
  • thank you very much for explaining what I was missing. I have a lot to learn. – Remy Apr 03 '16 at 23:39

2 Answers2

3

The error message is very clear: you need a parameterless constructor in your model class.

So you need to add another constructor without a parameter in your IncidentViewModel class or you need to remove the parameter from the existing one.

Rob
  • 11,492
  • 14
  • 59
  • 94
  • Robert, - You may have not seen part of my description above, I had mentioned that a constructor without a paramater was added and the it uses that constructor. It needs to hit the constructor with the model as the paramater shown above for saving data – Remy Apr 03 '16 at 18:44
  • 1
    Sorry, looks like you were right and so was hrdrdiab. Thank you everyone. This has helped. – Remy Apr 03 '16 at 23:41
2

I think you have to remove the constructor from your ViewModel .I think that viewmodels have nothing to do with data methods and constructors.Controllers are responsible for such duties, you can simply replace the constructor by something like this in the controller action :

IncidentViewModel vwIncidentData = new IncidentViewModel();
if(objIncidentBO.objIncident.IncidentModel.IncidentId !=0)
{
vwIncidentData.IncidentId = objIncidentBO.objIncident.IncidentModel.IncidentId;
vwIncidentData.objIncident = IncidentModelBO.Get(incidentId);
}

Anyway this line may be causing you the execution error problem,so check it and be sure it is not null:

objIncidentBO.objIncident.IncidentModel.IncidentId
hdrdiab
  • 343
  • 1
  • 11