ASP.NET MVC:没有为此对象定义无参数构造函数


172
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:         }

我一直在关注Steven Sanderson的“ Pro ASP.NET MVC框架 ”书。在第132页上,根据作者的建议,我下载了ASP.NET MVC Futures程序集,并将其添加到我的MVC项目中。[注意:这可能是鲱鱼。]

此后,我将无法再加载项目。上面的错误使我感冒。

我的问题不是,“您能帮我修复代码吗?”

相反,我想更广泛地了解:

  • 我应该如何解决此问题?
  • 我应该找什么?
  • 根本原因可能是什么?

似乎我应该比现在更深入地了解路由和控制器。

Answers:


226

我只是有一个类似的问题。当a Model没有无参数构造函数时,会发生相同的异常。

调用堆栈正在确定一种负责创建模型新实例的方法。

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


这是一个示例:

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
    {
    }
}

16
将JSON数据发布到我的操作时,我遇到了类似的错误。事实证明,我要绑定的模型没有无参数构造函数!
蒂姆(Tim)

1
注意:如果我定义构造函数而不是无参数构造函数,则在序列化期间我只会遇到此问题(无参数bla bla ...)。我的意思是,在此示例中,如果删除定义的构造函数(public MyModel(IHelper helper){}),问题就会消失...因此,每次创建构造函数时,都必须创建一个无参数的构造函数...我可以理解就像这样:一旦开始定义构造函数,系统就不会冒创建“默认对象”的风险,因为它不知道这是否有意义……类似的东西。
H_He

1
元组...也许对其他来这里的人来说:如果您的类中只有元组(例如Tuple <string,string> data;),则可以进行序列化(因为我在JSON序列化期间遇到了这个问题)...但是,如果您使用类似List <Tuple <string,string >>的数据;您将开始出现“无参数构造函数”错误。因为.Net无法/不创建元组(我对此没有引用,但Tuple <string,string> data = new Tuple <string,string>();不会编译...而Tuple <string,字符串>数据=新的元组<字符串,字符串>( “”, “”);就可以了。
H_He

3
是的,但是如何将无参数构造函数添加到具有依赖项的类中,并想将其注入到构造函数中呢?那是我不明白的问题的一部分...
EluciusFTW

2
@ToaoG您的依赖项注入库应该为您提供一种选择“注入构造函数”的方法。顺便说一句,在视图模型中进行依赖注入看起来很奇怪。
SandRock

89

如果您的模型使用的是SelectList,也可能导致这种情况因为它没有无参数的构造函数

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

如果这是原因,则需要重构模型以其他方式进行。因此,请使用IEnumerable<Contact>并编写一个扩展方法,以使用不同的属性定义创建下拉列表:

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

或者,您可以使用@Mark和@krilovich方法,只需将SelectList替换为IEnumerable,它也可以与MultiSelectList一起使用。

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

1
我在此上浪费了很多时间...,不得不将正在返回SelectList的帮助器函数转换为一个将返回List <SelectListItem> .... blarg的函数
标记为

您可以使用IEnumerable <SelectListItem>并将其在构造函​​数中实例化为新的List <SelectListItem>()
krilovich 2014年

谢谢3.5年后!
tonyapolis

谢谢您,这对我们非常有帮助!
凯文·库尔森

在5年后仍然有效。谢谢!
尼尔,2016年

23

您需要与控制器对应的动作没有参数。

看起来像您拥有的控制器/动作组合:

public ActionResult Action(int parameter)
{

}

但是你需要

public ActionResult Action()
{

}

另外,请查看Phil Haack的Route Debugger对路由进行故障排除。


6
异常与构造函数有关,与动作方法无关。
詹森·威克

4
@Logrythmik。报告的异常是针对构造函数的,但问题出在action方法中。我有一个正在工作的类和操作方法,然后向该操作方法添加了一个参数,并收到此错误。一种替代解决方案是为参数提供一个值。或使参数可选-当控制器在C#中,但它并没有为我与F#这应该工作
史蒂芬·霍斯金

另外,如果您正在执行类似@ Html.Action(“ SomeAction”,new {myParameter =“ 42”})的操作,请确保Html.Action调用中的参数名称与在中定义的参数名称匹配您的行动方法!
JT泰勒

20

默认情况下,MVC控制器需要不带参数的默认构造函数。最简单的方法是创建一个默认构造函数,该构造函数使用参数调用该构造函数:

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

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

但是,您可以滚动自己的来覆盖此功能ControllerFactory。这样,您可以告诉MVC在创建MyController给它的实例时Helper

这使您可以将Dependency Injection框架与MVC一起使用,并真正使一切脱钩。一个很好的例子已经在StructureMap网站上结束。整个快速入门都不错,他在“自动接线”的底部专门介绍了MVC。


6
我认为这不是正确的答案,@ swilliams。这里的关键是部分:为此对象定义。这是一个废话错误消息,实际上提示无法传递传入的输入模型。因此,如果您的输入模型没有无参数构造函数,则会出现此错误。很容易想到它与CONTROLLER构造函数有关。但事实并非如此。
Pure.Krome 2012年

1
这是一则废话,如果您不希望收到此类答复,那将使您大跌眼镜。多亏了这个答案和上面的回答,我才能够解决问题。我想这是不完全了解活页夹在幕后所做的事情。我认为它只会设置每个属性,但由于某种原因,它在发布时也会在设置之前调用get。因此,因为我超载了构造函数,并且不得不用较少的参数来补偿构造函数,所以我不得不考虑一些属性获得的空值,这也是意外的。
eaglei22

18

使用IDependencyResolver时也会发生此错误(例如,使用IoC容器时),并且依赖项解析器返回null。在这种情况下,ASP.NET MVC 3默认使用DefaultControllerActivator创建对象。如果要创建的对象没有公共的无参数构造函数,则在提供的依赖项解析器返回null的任何时间都会引发异常。

这是一个这样的堆栈跟踪:

[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

2
这引起了我的问题:我的依赖解析器由于异常而无法构造我的控制器。它被解析器吞没,返回null,并且MVC框架切换到默认控制器激活器,从而导致所描述的错误。
贝里兹(Beriz)

@ jmona789检查是否已在Global.asax中设置所有注入的依赖项。
aloisdg移至codidact.com,

13

您可以在MVC框架的许多不同位置获得此异常(例如,它无法创建控制器,或者无法创建模型来提供该控制器)。

我发现诊断此问题的唯一简便方法是使用您自己的代码在尽可能接近异常的情况下覆盖MVC。然后,当发生此异常时,您的代码将在Visual Studio中中断,并且您可以从堆栈跟踪中读取导致问题的Type。

这似乎是解决此问题的一种可怕方法,但它非常快速且非常一致。

例如,如果此错误发生在MVC DefaultModelBinder内部(您可以通过检查堆栈跟踪来了解),则用以下代码替换DefaultModelBinder:

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);
    }
}

并更新您的Global.asax.cs:

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

现在,下次您遇到该异常时,Visual Studio将停止在MyDefaultModelBinder类内部,并且您可以检查“ modelType”属性以查看引起问题的类型。

上面的示例仅适用于在模型绑定期间获得“为此对象定义无参数构造函数”异常的情况。但是可以为MVC中的其他扩展点编写类似的代码(例如,控制器构造)。


这就是我想为自己的问题做的事情。
道格·张伯伦

希望我能对此再投票。为我节省了超过几分钟的时间。
基思2015年

8

我遇到了同样的错误,在我的案例中,罪魁祸首是既不是public也不是private的构造函数。

没有为此对象定义无参数构造函数。

异常详细信息:System.MissingMethodException:没有为此对象定义无参数构造函数。

复制代码:确保构造函数之前已公开。

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

    public string name
    {
        get;
        set;
    }
}

4
请注意,在构造函数中缺少访问修饰符的情况在编译器中默认为“内部”。
lsuarez 2015年

1
放置“私有”修饰符将无法解决问题。
krzyski


6

在以下情况下,我遇到了相同的错误:

使用自定义ModelView,两个操作(GET和POST)都传递了包含两个对象的ModelView:

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

POST也接受相同的模型视图:

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

问题在于View收到了ModelView(同时需要产品和类别信息列表),但是在提交后仅返回Product对象,但是由于POST Add期望一个ProductModelView它传递了NULL,但是只有ProductModelView的构造函数需要两个参数(产品(RootCategories),然后尝试为此NULL情况找到另一个不带参数的构造函数,然后失败,并显示“ no parameterles ...”。

因此,按以下方法修复POST Add可以解决此问题:

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

希望这可以对某人有所帮助(我花了将近半天的时间才能找到答案!)。


内斯特,这很有启发性,似乎是正确的。但是,为什么视图返回的对象不同于接收的对象,即产品对象而不是ProductViewModel?
GilShalit

哦,这是我的具体情况,因为我只需要保留Products的数据,RootCategories仅传递给视图以打印出来,因此没有进行任何输入,因此它们的值(RootCategories)未保留在<input中>或其他任何地方。我是否需要保持相同的ViewModel,我将使用<input>形式,视图数据或其他形式持久保存。
Nestor

GilShalit,今天我找到了一个答案(对不起,我很慢!),看着呈现的HTML,我看到输入名称为[ObjectName]。[Property],但是没有原始ViewModel的痕迹,因此您只能检索每个人对象放在ViewModel中,而不是完整的ViewModel本身。例如:如果您的ProductViewModel虚拟机具有内部对象Product p和Category c,则GET控制器将一个模型虚拟机发送到View,则POST控制器只能接受类似参数(Product p,Category c),但不能接受虚拟机。 ..如果我错了,将不胜感激。
Nestor

5

我也一样。之所以出现我的问题,是因为我忘记了我的基本模型类已经具有在视图中定义的名称的属性

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  { ... }

...和控制器处理模型:

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

没什么特别的吧?但是然后我定义了视图...

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

...导致POST请求出现“无参数构造函数”错误。

希望有帮助。


5

我有一个类似的问题,基本上,要点是动作方法中的某些参数不是模型绑定过程提供的(换句话说,这些字段不是由提交页面提交的)。

即使提供了除一个参数以外的所有参数,即使缺少的参数是可为空的类型,也会出现此问题。

该问题也可能是拼写错误的结果,其中参数的名称和表单字段的名称将不相同。

解决方案是:1)验证名称是否匹配2)为参数提供默认值3)或提供不带该参数的其他操作方法。


谢谢@yo hal,您的答案竟然是解决我对此错误的特定实例的答案。在这种情况下,框架发出的错误消息恰好是最没有用的错误消息
斯科特·劳伦斯

4

我也遇到了这个问题,并认为我会分享,因为在上面找不到我的问题。

这是我的代码

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

调用此ActionResult:

public ActionResult Overview(int id)

我以为足够聪明,可以确定我传递的值是Overview的id参数,但事实并非如此。这修复了它:

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


4

由于没有无参数的公共构造函数,因此我遇到了同样的异常

代码是这样的:

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

变成

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

问题解决了我。


在基类中使用受保护的构造函数时,我遇到了同样的问题-现在看来是一个显而易见的解决方案!
keithl8041 2015年

4

所有答案都表明,要创建一个参数较少的构造函数,如果您不希望任何其他开发人员仅使用模型绑定程序,则这是不理想的。

[Obsolete("For model binding only", true)]如果另一个开发人员尝试使用此属性,则公共构造函数上方的属性将引发编译器错误。我花了很长时间才找到这个,希望它能对某人有所帮助。


完美-添加此属性可允许MVC模型绑定在运行时工作,并将属性的布尔参数设置为true可以防止(在编译时)实例化无参数构造函数的任何尝试。最好的答案在这里。
格雷格·特里维利克

3

我得到这个错误。我在构造函数中使用接口,而我的依赖解析器无法解析,当我注册它时错误就消失了。


如果您有新问题,请原样发布。这应该是注释或新问题,因为它不会尝试回答问题。
Nahuel Ianni'8

2

我有同样的问题...

如果您使用接口将连接与DbContext断开连接(如我),则可以使用structuremap.mvc (3或4-轻推包)在控制器类中使用结构。这将为您提供一个DependencyResolution文件夹。只需使用For <InterfaceClass>()并将注释行更改为Use <DbContextClass>()。


2

虽然这对于某些人可能是显而易见的,但对我来说,此错误的原因是我的MVC方法绑定到包含type属性的模型Tuple<>Tuple<>没有无参数的构造函数。


1

我遇到了同样的问题,但后来发现添加任何新接口,相应的类要求将其注册在Initializable Module下进行依赖项注入。就我而言,它是内部代码,如下所示:

[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)
    {
    }
}

}


1

就我而言,我的班级有 [Serializable]属性。

如果您的类是,则需要具有不带参数的构造函数 [Serializable]


0

当我添加了实例化类的新方法时,此错误开始了。

例:

    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;
         }
     }

当我进行此更改并添加无参数构造函数时,该错误已解决。我相信编译器默认会创建一个无参数的构造函数,但是如果添加自己的构造函数,则必须显式创建它。

    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;
         }
     }

0

我在DropDownList表单中添加了一个,但是在我的情况下,它不是(也不打算)与表单一起提交的,因为它在<form></form>标记之外:

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

由于模型仅包含用于显示的字段,因此这也导致了No parameterless constructor defined for this object错误,因为该字段根本没有提交。

在这种情况下,我通过添加排除绑定对其进行了修复:

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

0

这发生在我身上,并且此页面上的结果是一个很好的资源,使我朝着多个方向发展,但我想添加另一种可能性:

如其他答复所述,使用参数创建构造函数会删除隐式的无参数构造函数,因此您必须显式键入它。

我的问题是带有默认参数的构造函数也触发了此异常。

给出错误:

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

作品:

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

0

很可能您的控制器中可能已经有参数化的构造函数,并且所使用的任何依赖项解析器都无法正确解析该依赖项。您需要在编写依赖项解析器方法的地方放置断点,并且会在内部异常中获得确切的错误。



0

我在DOMAIN文件夹中的模型中添加了一个无参数的构造函数,此问题已解决。

在此处输入图片说明

 public User()
        {

        }

-3

因此,在进行ajax调用时,我也已经获得了该消息。因此,基本要求的是由contoller调用的该模型类中的构造函数,没有任何参数。

这是一个例子

public class MyClass{

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

 }

我从模型中删除了默认构造函数,这对我有用。
Musakkhir说
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.