当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《ASP.NETMVC:没有为此对象定义的无参数构造函数》经验,为你挑选了11个好方法。

我刚遇到类似的问题.当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
    {
    }
}

将JSON数据发布到我的操作时,我收到了类似的错误.事实证明,我试图绑定的模型没有无参数构造函数! (15认同)

是的,但是如何将一个无参数构造函数添加到具有依赖项的类中,并且您希望将它们注入构造函数中?这是我没有得到的问题的一部分...... (3认同)

@ToaoG你的依赖注入库应该为你提供一种选择"注入构造函数"的方法.顺便说一下,在视图模型中有依赖注入看起来很奇怪. (2认同)


Chris S.. 87

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

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

如果这是原因,你需要重构你的模型以不同的方式做.因此,使用IEnumerable和编写一个扩展方法,创建具有不同属性定义的下拉列表:

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

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

或者您可以使用@Mark和@krilovich方法,只需要将SelectList替换为IEnumerable,它也适用于MultiSelectList.

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


Martin.. 23

您需要与控制器对应的操作没有参数.

看起来你有控制器/动作组合:

public ActionResult Action(int parameter)
{

}

但你需要

public ActionResult Action()
{

}

另外,查看Phil Haack的Route Debugger来排除路线故障.



1> SandRock..:

我刚遇到类似的问题.当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
    {
    }
}


将JSON数据发布到我的操作时,我收到了类似的错误.事实证明,我试图绑定的模型没有无参数构造函数!
是的,但是如何将一个无参数构造函数添加到具有依赖项的类中,并且您希望将它们注入构造函数中?这是我没有得到的问题的一部分......
@ToaoG你的依赖注入库应该为你提供一种选择"注入构造函数"的方法.顺便说一下,在视图模型中有依赖注入看起来很奇怪.

2> Chris S..:

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

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

如果这是原因,你需要重构你的模型以不同的方式做.因此,使用IEnumerable和编写一个扩展方法,创建具有不同属性定义的下拉列表:

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

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

或者您可以使用@Mark和@krilovich方法,只需要将SelectList替换为IEnumerable,它也适用于MultiSelectList.

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



3> Martin..:

您需要与控制器对应的操作没有参数.

看起来你有控制器/动作组合:

public ActionResult Action(int parameter)
{

}

但你需要

public ActionResult Action()
{

}

另外,查看Phil Haack的Route Debugger来排除路线故障.


该异常与构造函数有关,而与操作方法无关.
@Logrythmik.报告的异常是针对构造函数的,但问题出在action方法中.我有一个正在运行的类和操作方法,然后在action方法中添加了一个参数,并得到了这个错误.另一种解决方案是为参数提供值.或者让参数可选 - 这应该在C#中的控制器时有效,但是对于我来说不适用于F#

4> swilliams..:

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

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

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

但是,您可以通过滚动自己来覆盖此功能ControllerFactory.通过这种方式,您可以告诉MVC在创建时MyController给它一个实例Helper.

这允许您将依赖注入框架与MVC一起使用,并真正解耦所有内容.一个很好的例子就是在StructureMap网站上.整个快速入门很好,他在"Auto Wiring"中将MVC特定于底部.


我不认为这是正确的答案,@ swilliams.这里的关键是部分:*为此对象定义*.这是一个废话错误消息,实际暗示传入的INPUT模型无法创建.因此,如果您的输入模型没有无参数构造函数,那么您会收到此错误.很容易认为它与CONTROLLER构造函数有关.但事实并非如此.

5> Kaleb Peders..:

使用IDependencyResolver时也会发生此错误,例如使用IoC容器时,依赖项解析程序返回null.在这种情况下,ASP.NET MVC 3默认使用DefaultControllerActivator来创建对象.如果正在创建的对象没有公共的no-args构造函数,则只要提供的依赖项解析程序返回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.b__2() +49
   System.Web.Mvc.<>c__DisplayClassb`1.b__a() +13
   System.Web.Mvc.SecurityUtil.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


这导致了我的问题:由于异常,我的依赖项解析器无法构造我的控制器.它被解析器吞没,返回null并且MVC框架切换到默认的控制器激活器,导致所描述的错误.

6> Josh Mouch..:

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

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

这似乎是解决这个问题的可怕方法,但它非常快,而且非常一致.

例如,如果在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中的其他扩展点编写类似的代码(例如,控制器构造).



7> Hammad Khan..:

我得到了同样的错误,我的案例中的罪魁祸首是构造函数既不公开也不私有.

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

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

Repro代码:确保构造函数在它之前已公开.

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

    public string name
    {
        get;
        set;
    }
}


正如注释一样,构造函数上缺少访问修饰符默认为编译器中的"内部".

8> Dan B..:

http://tekpub.com/conferences/mvcconf上的第一个视频

47:10分钟显示错误并显示如何覆盖默认的ControllerFactory.即创建结构图控制器工厂.

基本上,您可能正在尝试实现依赖注入?

问题是接口依赖性.



9> Nestor..:

我遇到同样的错误:

使用自定义ModelView,两个Actions(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)
{...}

希望这可以帮助别人(我花了差不多半天才发现这个!).



10> Anonymous..:

我也一样.我的问题出现了,因为我忘了我的基础模型类已经具有在视图中定义的名称的属性.

public class CTX : DbContext {  // context with domain models
    public DbSet 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) { ... }

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

<%=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")%>

...在POST请求中导致"无参数构造函数"错误.

希望有所帮助.



11> yoel halb..:

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

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

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

解决方案是1)验证名称是否匹配2)为参数提供默认值3)或提供不带此参数的另一个操作方法.

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有