ASP.NET MVC: No parameterless constructor defined

2019-01-01 09:06发布

问题:

Server Error in \'/\' Application.
--------------------------------------------------------------------------------

No parameterless constructor defined for this object. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

Source Error: 


Line 16:             HttpContext.Current.RewritePath(Request.ApplicationPath, false);
Line 17:             IHttpHandler httpHandler = new MvcHttpHandler();
Line 18:             httpHandler.ProcessRequest(HttpContext.Current);
Line 19:             HttpContext.Current.RewritePath(originalPath, false);
Line 20:         }

I was following Steven Sanderson\'s \'Pro ASP.NET MVC Framework\' book. On page 132, in accordance with the author\'s recommendation, I downloaded the ASP.NET MVC Futures assembly, and added it to my MVC project. [Note: This could be a red herring.]

After this, I could no longer load my project. The above error stopped me cold.

My question is not, \"Could you help me fix my code?\"

Instead, I\'d like to know more generally:

  • How should I troubleshoot this issue?
  • What should I be looking for?
  • What might the root cause be?

It seems like I should understand routing and controllers at a deeper level than I do now.

回答1:

I just had a similar problem. The same exception occurs when a Model has no parameterless constructor.

The call stack was figuring a method responsible for creating a new instance of a model.

System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)


Here is a sample:

public class MyController : Controller
{
    public ActionResult Action(MyModel model)
    {

    }
}

public class MyModel
{
    public MyModel(IHelper helper) // MVC cannot call that
    {
        // ...
    }

    public MyModel() // MVC can call that
    {
    }
}


回答2:

This can also be caused if your Model is using a SelectList, as this has no parameterless constructor:

public class MyViewModel
{
    public SelectList Contacts { get;set; }
}

You\'ll need to refactor your model to do it a different way if this is the cause. So using an IEnumerable<Contact> and writing an extension method that creates the drop down list with the different property definitions:

public class MyViewModel
{
    public Contact SelectedContact { get;set; }
    public IEnumerable<Contact> Contacts { get;set; }
}

public static MvcHtmlString DropDownListForContacts(this HtmlHelper helper, IEnumerable<Contact> contacts, string name, Contact selectedContact)
{
    // Create a List<SelectListItem>, populate it, return DropDownList(..)
}

Or you can use the @Mark and @krilovich approach, just need replace SelectList to IEnumerable, it\'s works with MultiSelectList too.

 public class MyViewModel
    {
        public Contact SelectedContact { get;set; }
        public IEnumerable<SelectListItem> Contacts { get;set; }
    }


回答3:

You need the action that corresponds to the controller to not have a parameter.

Looks like for the controller / action combination you have:

public ActionResult Action(int parameter)
{

}

but you need

public ActionResult Action()
{

}

Also, check out Phil Haack\'s Route Debugger to troubleshoot routes.



回答4:

By default, MVC Controllers require a default constructor with no parameters. The simplest would be to make a default constructor that calls the one with parameters:

public MyController() : this(new Helper()) {
}

public MyController(IHelper helper) {
  this.helper = helper;
}

However, you can override this functionality by rolling your own ControllerFactory. This way you can tell MVC that when you are creating a MyController give it an instance of Helper.

This allows you to use Dependency Injection frameworks with MVC, and really decouple everything. A good example of this is over at the StructureMap website. The whole quickstart is good, and he gets specific to MVC towards the bottom at \"Auto Wiring\".



回答5:

This error also occurs when using an IDependencyResolver, such as when using an IoC container, and the dependency resolver returns null. In this case ASP.NET MVC 3 defaults to using the DefaultControllerActivator to create the object. If the object being created does not have a public no-args constructor an exception will then be thrown any time the provided dependency resolver has returned null.

Here\'s one such stack trace:

[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) +98
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67

[InvalidOperationException: An error occurred when trying to create a controller of type \'My.Namespace.MyController\'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +232
   System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
   System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8963444
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184


回答6:

You can get this exception at many different places in the MVC framework (e.g. it can\'t create the controller, or it can\'t create a model to give that controller).

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).



回答7:

I got the same error, the culprit in my case was the constructor which was neither public nor private.

No parameterless constructor defined for this object.

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

Repro code: Make sure the constructor has public before it.

public class Chuchi()
{
     Chuchi()    // The problem is this line. Public is missing
     {
         // initialization
         name=\"Tom Hanks\";
     }

    public string name
    {
        get;
        set;
    }
}


回答8:

First video on http://tekpub.com/conferences/mvcconf

47:10 minutes in show the error and shows how to override the default ControllerFactory. I.e. to create structure map controller factory.

Basically, you are probably trying to implement dependency injection??

The problem is that is the interface dependency.



回答9:

I got the same error when:

Using a custom ModelView, both Actions (GET and POST) were passing the ModelView that contained two objects:

public ActionResult Add(int? categoryID)
{
    ...
    ProductViewModel productViewModel = new ProductViewModel(
            product,
            rootCategories
            );
    return View(productViewModel); 
}

And the POST also accepting the same model view:

[HttpPost]
[ValidateInput(false)]
public ActionResult Add(ProductModelView productModelView)
{...}

Problem was the View received the ModelView (needed both product and list of categories info), but after submitted was returning only the Product object, but as the POST Add expected a ProductModelView it passed a NULL but then the ProductModelView only constructor needed two parameters(Product, RootCategories), then it tried to find another constructor with no parameters for this NULL case then fails with \"no parameterles...\"

So, fixing the POST Add as follows correct the problem:

[HttpPost]
[ValidateInput(false)]
public ActionResult Add(Product product)
{...}

Hope this can help somebody (I spent almost half day to find this out!).



回答10:

The same for me. My problem appeared because i forgot that my base model class already has property with the name which was defined in the view.

public class CTX : DbContext {  // context with domain models
    public DbSet<Products> Products { get; set; }  // \"Products\" is the source property
    public CTX() : base(\"Entities\") {}
}

public class BaseModel : CTX { ... }
public class ProductModel : BaseModel { ... }
public class OrderIndexModel : OrderModel  { ... }

... and controller processing model :

[HttpPost]
[ValidateInput(false)]
public ActionResult Index(OrderIndexModel order) { ... }

Nothing special, right? But then i define the view ...

<div class=\"dataItem\">
    <%=Html.Label(\"Products\")%>
    <%=Html.Hidden(\"Products\", Model.index)%>   // I FORGOT THAT I ALREADY HAVE PROPERTY CALLED \"Products\"
    <%=Html.DropDownList(\"ProductList\", Model.products)%>
    <%=Html.ActionLink(\"Delete\", \"D\")%>
</div>

... which causes \"Parameterless constructor\" error on POST request.

Hope that helps.



回答11:

I had a similar problem, and basically the point is that there are some arguments in the action method that were not supplied by the Model Binding process, (and in other words these fields were not submitted by the submitting page).

This problem will come up even if all arguments but one are supplied, and even if the one missing is a nullable type.

The problem might also be a result of a typo, in which the name of the argument and name of the form field will not be identical.

The solution is to 1) verify that the names match up 2) provide a default value for the argument 3) or provide another action method without this argument.



回答12:

I had this problem as well and thought I\'d share since I can\'t find my problem above.

This was my code

return RedirectToAction(\"Overview\", model.Id);

Calling this ActionResult:

public ActionResult Overview(int id)

I assumed it would be smart enough to figure out that the value I pass it is the id paramter for Overview, but it\'s not. This fixed it:

return RedirectToAction(\"Overview\", new {id = model.Id});



回答13:

I got same exception due to there was no parameterless public contructor

Code was like this:

public class HomeController : Controller
{        
    private HomeController()
    {
        _repo = new Repository();
    }

changed to

 public class HomeController : Controller
{        
    public HomeController()
    {
        _repo = new Repository();
    }

problem resolved to me.



回答14:

I had the same problem...

If your using a interface to decouple your connection against your DbContext (like me) you can use structuremap.mvc (3 or 4 - nudget package) to be able to use a constructure in your controller class. This will give you a DependencyResolution folder. Just change the commented line with your For< InterfaceClass >() and to Use< DbContextClass >().



回答15:

While this may be obvious to some, the culprit of this error for me was my MVC method was binding to a model that contained a property of type Tuple<>. Tuple<> has no parameterless constructor.



回答16:

All of the answers say to create a parameters less constructor which isn\'t ideal if you don\'t want any other devs using it and only the model binder.

The attribute [Obsolete(\"For model binding only\", true)] above a public constructor will throw a compiler error if another dev tries to use this. Took me ages to find this, hope it helps someone.



回答17:

I got this error. I was using interfaces in my constructor and my dependency resolver wasn\'t able to resolve, when i registered it then the error went away.



回答18:

This error started for me when I added a new way to instantiate a class.

Example:

    public class myClass
    {
         public string id{ get; set; }
         public List<string> myList{get; set;}

         // error happened after I added this
         public myClass(string id, List<string> lst)
         {
             this.id= id;
             this.myList= lst;
         }
     }

The error was resolved when I added when I made this change, adding a parameterless constructor. I believe the compiler creates a parameterless constuctor by default but if you add your own then you must explicitly create it.

    public class myClass
    {
         public string id{ get; set; }
         public List<string> myList{get; set;}

         // error doesn\'t happen when I add this
         public myClass() { }

         // error happened after I added this, but no longer happens after adding above
         public myClass(string id, List<string> lst)
         {
             this.id= id;
             this.myList= lst;
         }
     }


回答19:

I\'d added a DropDownList to my form, however in my case it wasn\'t (and wasn\'t intended to be) submitted with the form as it was outside of the <form></form> tags:

@Html.DropDownList(\"myField\", Model.MyField)

As the Model contained the field for display only, this also caused the No parameterless constructor defined for this object error because the field wasn\'t submitted at all.

In this case I fixed it by adding an exclude binding:

public ActionResult Foo(int id, int? page, [Bind(Exclude = \"MyField\")]MyModel model)


回答20:

This happened to me, and the results on this page were a good resource that led me in many directions, but I would like to add another possibility:

As stated in other replies, creating a constructor with parameters removes the implicit parameterless constructor, so you have to explicitly type it.

What was my problem was that a constructor with default parameters also triggered this exception.

Gives errors:

public CustomerWrapper(CustomerDto customer = null){...}

Works:

public CustomerWrapper(CustomerDto customer){...}
public CustomerWrapper():this(null){}


回答21:

Most probably you might have parameterized constructor in your controller and whatever dependency resolver you are using is not able to resolve the dependency properly. You need to put break-point where the dependency resolver method is written and you will get the exact error in inner exception.



回答22:

I had same problem but later found adding any new interface and corresponding class requires it to be registered under Initializable Module for dependency injection. In my case it was inside code as follows:

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class DependencyResolverInitialization : IConfigurableModule
{

    public void ConfigureContainer(ServiceConfigurationContext context)
    {
        context.Container.Configure(ConfigureContainer);
        var structureMapDependencyResolver = new StructureMapDependencyResolver(context.Container);
        DependencyResolver.SetResolver(structureMapDependencyResolver);
        GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), structureMapDependencyResolver);
    }

    private void ConfigureContainer(ConfigurationExpression container)
    {
        container.For<IAppSettingService>().Use<AppSettingService>();
        container.For<ISiteSettingService>().Use<SiteSettingService>();
        container.For<IBreadcrumbBuilder>().Use<BreadcrumbBuilder>();
        container.For<IFilterContentService>().Use<FilterContentService>().Singleton();
        container.For<IDependecyFactoryResolver>().Use<DependecyFactoryResolver>();
        container.For<IUserService>().Use<UserService>();
        container.For<IGalleryVmFactory>().Use<GalleryVmFactory>();
        container.For<ILanguageService>().Use<LanguageService>();
        container.For<ILanguageBranchRepository>().Use<LanguageBranchRepository>();
        container.For<ICacheService>().Use<CacheService>(); 
        container.For<ISearchService>().Use<SearchService>();
        container.For<IReflectionService>().Use<ReflectionService>();
        container.For<ILocalizationService>().Use<LocalizationService>();
        container.For<IBookingFormService>().Use<BookingFormService>();
        container.For<IGeoService>().Use<GeoService>();
        container.For<ILocationService>().Use<LocationService>();
        RegisterEnterpriseAPIClient(container);
    }

   public void Initialize(InitializationEngine context)
    {
    }

    public void Uninitialize(InitializationEngine context)
    {
    }

    public void Preload(string[] parameters)
    {
    }
}

}



回答23:

I had the same problem.

Just Removed HttpFileCollectionBase files from Post Action method argument and added like HttpFileCollectionBase files = Request.Files; in method body.



回答24:

In my case, my class had the [Serializable] attribute.

You are required to have a constructor that takes no parameters if your class is [Serializable]



回答25:

So I have gotten that message before as well, when doing an ajax call. So what it\'s basically asking for is a constructor in that model class that is being called by the contoller, doesn\'t have any parameter.

Here is an example

public class MyClass{

     public MyClass(){} // so here would be your parameterless constructor

 }