0

In my ASP.NET MVC 5.2 application running .NET Framework v4.5.2, my AdminController has an InventoryQueryList method that accepts the model:

[HandleError]
[HttpPost]
public ActionResult InventoryQueryList(CheckInventoryQueryModel model)
{
    // ...
}

My view contains the model and calls the InventoryQueryList method on POST:

@model CCNRebuild.Models.CheckInventoryQueryModel
@{
    ViewBag.Title = "InventoryQuery";
    Layout = "~/Views/Shared/_ConsoleLayout.cshtml";
}

@using (Html.BeginForm("InventoryQueryList", "Admin", FormMethod.Post))
{
    @Html.AntiForgeryToken();
    <label>
        Dealer:@Html.DropDownListFor(m => m.DealerID, Model.Dealerships)
    </label>
    ...
    <input type="submit" value="Submit" />
}

But, whenever I click the submit button, I get an error:

MissingMethodException: No parameterless constructor defined for this object.

screenshot

Why is the view not passing my model parameter to the controller?

The controller has never had a parameterless constructor in the 3 months that I have been working here.

NOTE: I tried to only show relevant code, and I left out anything unnecessary. If there is anything missing that needs to be seen, please comment and I'll try to oblige.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Does `CheckInventoryQueryModel` have a parameterless constructor? The error indicates that it needs one, but does not have one, and the question doesn't demonstrate either way. – David Jan 03 '23 at 17:09
  • @David, it does not. I've been contracted to change wording on a page that looks like this, but I cannot get it to load. Perhaps a previous contractor broke it and nobody has noticed. –  Jan 03 '23 at 17:49
  • Answer is pretty straight forward, if you are going to have the framework bind `CheckInventoryQueryModel`, then it needs a parameterless constructor. – mxmissile Jan 03 '23 at 18:25
  • @jp2code: That's probably the case that it simply wasn't noticed then. Because the model binder always needs a parameterless constructor. (Unless someone wrote a custom model binder for that type.) It sounds like overall the question is just a mistake in code you weren't working on, not something directly related to the content of the question, and should probably just be deleted? – David Jan 03 '23 at 18:26
  • @David. I'd like to fix it. I was hired to fix their website. So, if I add a parameterless method for the form POST, how do I get the model data from the form? Am I asking that right? –  Jan 03 '23 at 18:46
  • @mxmissile, same question: How do I get the model data from the form with a parameterless method? –  Jan 03 '23 at 18:47
  • @jp2code: Well, at that point you're kind of asking how does ASP.NET MVC work *at all*, which is a bit too broad to be meaningfully answered here. *In general*, the data posted to the server in the HTTP request is what the framework uses to populate properties on the model (or parameters in the action method). In your browser's debugging tools you can observe the HTTP requests being made. When conducting a POST request from a form for example, that request body includes key/value pairs from the form elements. – David Jan 03 '23 at 18:49
  • Did you try simply adding a parameterless constructor? Adding that should not break any existing code. – mxmissile Jan 03 '23 at 20:30
  • @mxmissile, I did, but that did not change anything. In this answer (https://stackoverflow.com/a/14124732/153923) like most others, there is a model passed to the HTTP Post method. –  Jan 03 '23 at 20:53

1 Answers1

2

The error is telling you that CheckInventoryQueryModel doesn't have a parameterless constructor, and it needs one. So you would either:

  1. Remove whatever non-parameterless constructor(s) it does have (and update related code accordingly), or
  2. Add a parameterless constructor.

The model binder needs a parameterless constructor in order to construct an instance of the model. (Unless you write a custom model binder for this type. Which probably isn't the road you want to take, but is an option.) This is a fairly common pattern in frameworks that automate model instance creation. Entity Framework, for example.


As for the actual questions being asked...

How does Controller get the Model from the View FormMethod.Post?

and

Why is the view not passing my model parameter to the controller?

It just sounds like you were misinterpreting the error. I see no reason to suggest that the page isn't passing the form value(s) to the server. Though you can always confirm this in your browser's debugging tools by observing the HTTP request being made when posting the form.

The request sends the data to the server, and can do so in a variety of ways. Form posts are generally key/value pairs. The ASP.NET MVC framework's model binder uses those key/value pairs to populate properties on the model. It just couldn't do that in this case because it couldn't create an instance of the model to be populated.

David
  • 208,112
  • 36
  • 198
  • 279
  • You are probably right. I haven't worked much with ASP.NET MVC before this project. Every other `[HttpPost]` method takes one of the Model parameters, so I'm probably misunderstanding something. I just don't know how to ask it. The Admin Controller is the controller for about 20 different Views, each with a different class model. I'll have to keep searching. –  Jan 03 '23 at 19:17
  • @jp2code: It's not really clear what else you're searching for in this case, and it sounds like you may be over-thinking it. The number of methods in a controller, the model used to populate any given view, etc. aren't relevant to how the framework handles any given request *from* a client. The data in the request (URL query string values, form values, JSON, etc.) is used to populate the parameters for the action method handling the request. Is something else not working, outside the scope of the error in the question above? – David Jan 03 '23 at 19:28
  • No, everything else is working - that I know of. I just happened across this one that crashed the site while trying to find something in an unrelated request. This was one of the possible paths to the request described in the ticket. –  Jan 03 '23 at 19:38
  • 1
    OH! The Model needed a ParameterLess constructor!!!! I thought it was complaining about the Controller not having a ParameterLess constructor to display the Model information. Yes, I did edit the Model. I fixed that, and the problem is gone. Whew! –  Jan 03 '23 at 22:06