13

The callstack shows the following:

[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) +86
System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) +230
System.Activator.CreateInstance(Type type, Boolean nonPublic) +67
System.Activator.CreateInstance(Type type) +6
System.Web.Mvc.DefaultModelBinder.CreateModel(ModelBindingContext bindingContext, Type modelType) +277
System.Web.Mvc.<>c__DisplayClass1.<BindModel>b__0() +98
System.Web.Mvc.ModelBindingContext.get_Model() +51
System.Web.Mvc.DefaultModelBinder.BindModelCore(ModelBindingContext bindingContext) +2600
System.Web.Mvc.DefaultModelBinder.BindModel(ModelBindingContext bindingContext) +1067
System.Web.Mvc.DefaultModelBinder.BindProperty(ModelBindingContext parentContext, Type propertyType, Func`1 propertyValueProvider, String propertyName) +208
System.Web.Mvc.DefaultModelBinder.BindModelCore(ModelBindingContext bindingContext) +1787
System.Web.Mvc.DefaultModelBinder.BindModel(ModelBindingContext bindingContext) +1067
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ParameterInfo parameterInfo) +355
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(MethodInfo methodInfo) +439
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +288
System.Web.Mvc.Controller.ExecuteCore() +180
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +96
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +36
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +377
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +71
System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +36
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

I have a tiny form with a bunch of hidden fields and one submit button. When I press it, I never even hit the requested method.

How do I go on and debug this? It would be a great start if I knew WHAT object didn't have a parameterless constructor. Where is this object? How can I solve this? I know the question is rather vague, but currently it's all I've got..

--EDIT--
In my form I added Html.Hidden() inputs. Depending on previous actions, these can have a value of "". The action makes use of ModelBinding. Whenever the value is "" and the datatype is a SelectList, the modelbinder goes berzerk on me.

I feel more and more uncomfortable with how the SelectList is doing it's thing... The idea is good, but there are some issues with it.

Boris Callens
  • 90,659
  • 85
  • 207
  • 305

6 Answers6

7

For those Googling this exception, here is a more general way to diagnose it:

The only easy way I've found to diagnose this problem is to override MVC as close to the exception as possible with your own code. Then your code will break inside Visual Studio when this exception occurs, and you can read the Type causing the problem from the stack trace.

This seems like a horrible way to approach this problem, but it's very fast, and very consistent.

For example, if this error is occurring inside the MVC DefaultModelBinder (which you will know by checking the stack trace), then replace the DefaultModelBinder with this code:

public class MyDefaultModelBinder : System.Web.Mvc.DefaultModelBinder
{
    protected override object CreateModel(System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext, Type modelType)
    {
        return base.CreateModel(controllerContext, bindingContext, modelType);
    }
}

And update your Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
{
...
    protected void Application_Start(object sender, EventArgs e)
    {
        ModelBinders.Binders.DefaultBinder = new MyDefaultModelBinder();
    }
}

Now the next time you get that exception, Visual Studio will stop inside your MyDefaultModelBinder class, and you can check the "modelType" property to see what type caused the problem.

The example above works for when you get the "No parameterless constructor defined for this object" exception during model binding, only. But similar code can be written for other extension points in MVC (e.g. controller construction).

Josh Mouch
  • 3,480
  • 1
  • 37
  • 34
  • I have been searching for this for a really long time. Thank you! Everyone: save yourself time and try this first. I called mine "DebuggableModelBinder" and I'm just going to comment it out of Global.asax.cs and leave it in there for the next time this bites me. – Andrew Kvochick Aug 10 '15 at 17:28
7

I solved the issue which is caused of SelectList object because it does not provide the default constructor so we cant have in out ViewModel.

Gripsoft
  • 2,570
  • 7
  • 27
  • 30
6

I also have properties on my view model class that return SelectList instances. I decorated my class with the Bind attribute to exclude these properties like this:

[Bind(Exclude = "Countries")] public class MyViewModel { ...

public SelectList Countries { get; set; }

}

Hope that helps, Roger

6

Your custom classes in the action args must have a parameterless constructor in order to use the default model binder. Otherwise, either (1) create a custom model binder or (2) pass primitive types instead of custom classes to the Action.

Craig Stuntz
  • 125,891
  • 12
  • 252
  • 273
  • Thanks for the answer. This was actually the first thing I checked because it was the most obvious thing that could go wrong. They do have a parles ctor. I use the same objects throughout the rest my site sucessfully. – Boris Callens Dec 01 '08 at 20:39
1

Did you remove Default.aspx? That needs to be in place to render the root properly. This can also happen if you're trying to use Dependency Injection and your container isn't setup properly - meaning there is no ControllerFactory that asks the DI Container for the instance.

  • Nope, it's there. I found what the cause is, but not the solution yet. Please refer to my original post. – Boris Callens Dec 01 '08 at 19:54
  • 1
    That was it for me, I copied over code from the WPF app I was testing and I had removed the IControllerFactory controllerFactory = new UnityControllerFactory(_container); ControllerBuilder.Current.SetControllerFactory(controllerFactory); – rball Apr 05 '10 at 22:21
0

The root of my problem was also SelectList.

I had this:

<%: Html.DropDownListFor(m => Model.Destinations, Model.Destinations)%>

When I should have had this:

<%: Html.DropDownListFor(m => Model.Destination, Model.Destinations)%>

Destination is the user's selection, Destinations is the list of possible values. Using the plural SelectList twice caused the problem.

jbierling
  • 681
  • 6
  • 12