ASP.NET MVC:没有为此对象定义无参数构造函数
Posted
技术标签:
【中文标题】ASP.NET MVC:没有为此对象定义无参数构造函数【英文标题】:ASP.NET MVC: No parameterless constructor defined for this object 【发布时间】:2010-11-24 05:41:14 【问题描述】: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 Framework”一书。在第 132 页,按照作者的建议,我下载了 ASP.NET MVC Futures 程序集,并将其添加到我的 MVC 项目中。 [注意:这可能是一个红鲱鱼。]
在此之后,我无法再加载我的项目。上面的错误让我不寒而栗。
我的问题是不是,“你能帮我修复我的代码吗?”
相反,我想更一般地了解:
我应该如何解决这个问题? 我应该寻找什么? 根本原因可能是什么?看来我应该比现在更深入地了解路由和控制器。
【问题讨论】:
【参考方案1】:我刚刚遇到了类似的问题。当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 数据发布到我的操作时,我遇到了类似的错误。事实证明,我尝试绑定的模型没有无参数构造函数! 注意:如果我定义了一个构造函数,而不是一个无参数的构造函数,我只会在序列化过程中遇到这个问题(没有无参数 bla bla ...)。我的意思是,在这个例子中,如果你删除你定义的构造函数( public MyModel(IHelper helper) )问题就消失了......所以每次你创建一个构造函数时,你必须创建一个无参数的......我能理解就像:一旦你开始定义一个构造函数,系统就不会冒险创建“默认对象”,因为它不知道这是否有意义......类似的事情。 Tuples... 也许对于其他来这里的人来说:如果您的班级中只有元组(例如 Tuple如果您的模型使用 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;
【讨论】:
我在这上面浪费了很多时间......并且不得不将返回 SelectList 的辅助函数转换为返回 ListReadOnlyCollection
【参考方案3】:
你需要控制器对应的动作没有参数。
您拥有的控制器/动作组合看起来像:
public ActionResult Action(int parameter)
但你需要
public ActionResult Action()
另外,请查看 Phil Haack 的 Route Debugger 以解决路线问题。
【讨论】:
异常与构造函数有关,与动作方法无关。 @Logrythmik。报告的异常是针对构造函数的,但问题出在操作方法中。我有一个正在工作的类和操作方法,然后向操作方法添加了一个参数,并得到了这个错误。另一种解决方案是为参数提供一个值。或者使参数可选 - 当控制器在 C# 中时这应该可以工作,但它不适用于 F# 另外,如果您正在执行类似@Html.Action("SomeAction", new myParameter = "42" ) 的操作,请确保您的 Html.Action 调用中的参数名称与您的操作方法中定义的参数名称匹配!【参考方案4】:默认情况下,MVC 控制器需要一个不带参数的默认构造函数。最简单的方法是创建一个默认构造函数,调用带有参数的构造函数:
public MyController() : this(new Helper())
public MyController(IHelper helper)
this.helper = helper;
但是,您可以通过滚动自己的 ControllerFactory
来覆盖此功能。这样你就可以告诉 MVC,当你创建一个 MyController
时,给它一个 Helper
的实例。
这允许您将依赖注入框架与 MVC 一起使用,并真正解耦一切。 StructureMap website 就是一个很好的例子。整个快速入门很好,他在“自动布线”的底部专门针对 MVC。
【讨论】:
我认为这不是正确的答案,@swilliams。这里的关键是部分:为此对象定义。这是一条废话错误消息,实际上暗示无法创建传入的输入模型。因此,如果您有一个没有无参数构造函数的输入模型,那么您会收到此错误。很容易认为它与 CONTROLLER 构造函数有关。但事实并非如此。 这是一条废话,如果不是因为这样的回应,你会大发雷霆。多亏了这个答案和上面的回复,我才得以解决问题。我想这是一个不完全了解活页夹在幕后做什么的问题。我认为它只会设置每个属性,但由于某种原因,它在发布时也会在设置之前调用 get。所以因为我重载了我的构造函数并且不得不用一个无参数的构造函数来补偿我不得不考虑我的一些属性得到的空值,这也是出乎意料的。【参考方案5】:在使用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
【讨论】:
这导致了我的问题:我的依赖解析器由于异常而无法构造我的控制器。它被解析器吞下,返回 null 并且 MVC 框架切换到默认的控制器激活器,导致所描述的错误。 @jmona789 检查您是否在 Global.asax 中设置了所有注入的依赖项。 这是我的问题。在制作我的项目演示时,我仍然有依赖解析器,我需要为演示删除它!【参考方案6】:您可以在 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】:我遇到了同样的错误,在我的例子中,罪魁祸首是构造函数,它既不是公共的也不是私有的。
没有为此对象定义无参数构造函数。
异常详细信息:System.MissingMethodException:没有为此对象定义无参数构造函数。
复制代码:确保构造函数之前有 public。
public class Chuchi()
Chuchi() // The problem is this line. Public is missing
// initialization
name="Tom Hanks";
public string name
get;
set;
【讨论】:
作为注释,在构造函数中缺少访问修饰符默认为编译器中的“内部”。 把“private”修饰符放在那里并不能解决问题。【参考方案8】:http://tekpub.com/conferences/mvcconf 上的第一个视频
47:10 分钟显示错误并显示如何覆盖默认 ControllerFactory。 IE。创建结构映射控制器工厂。
基本上,您可能正在尝试实现依赖注入??
问题在于接口依赖。
【讨论】:
您可以从 MVC Storefront 项目中获取 StructureMapControllerFactory 类【参考方案9】:我遇到了同样的错误:
使用自定义 ModelView,两个 Action(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 只需要构造函数两个参数(Product,RootCategories),然后它试图为这个 NULL 情况找到另一个没有参数的构造函数,然后失败,“没有参数......”
因此,修复 POST Add 如下解决问题:
[HttpPost]
[ValidateInput(false)]
public ActionResult Add(Product product)
...
希望这可以帮助某人(我花了将近半天的时间才找到这个!)。
【讨论】:
Nestor,这很有启发性,似乎是正确的。但是为什么 View 返回一个不同的对象,而不是它正在接收的对象,即 Product 对象而不是 ProductViewModel? 哦,这是针对我的情况的,因为我只需要保留产品的数据,RootCategories 被传递给视图只是为了打印出来,没有对其进行任何输入,所以它们的值(RootCategories ) 没有保存在 或其他任何地方。我是否需要保持相同的 ViewModel,我会使用表单 、视图数据或其他东西来坚持。 GilShalit,今天我找到了答案(对不起,我很慢!),查看呈现的 HTML 我看到输入采用 [ObjectName].[Property] 的名称,但没有原始 ViewModel 的痕迹,因此您只能检索 ViewModel 中的每个单独对象,而不能检索完整的 ViewModel 本身。示例:如果您的 ProductViewModel vm 具有内部对象 Product p 和 Category c,那么您的 GET 控制器将一个模型 vm 发送到 View,那么您的 POST 控制器只能接受(产品 p,Category c)之类的参数,但不能接受 vm。 ..如果我错了,希望得到一些反馈。【参考方案10】:对我来说也一样。 我的问题出现了,因为我忘记了我的基础模型类已经具有在视图中定义的名称的属性。
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 请求出现“无参数构造函数”错误。
希望对您有所帮助。
【讨论】:
【参考方案11】:我也遇到过类似的问题,基本上问题是action方法中有一些参数不是模型绑定过程提供的,(换句话说,这些字段不是提交页面提交的)。
即使提供了除一个以外的所有参数,即使缺少的参数是可空类型,也会出现此问题。
问题也可能是由于输入错误导致的,其中参数的名称和表单字段的名称将不相同。
解决方案是 1) 验证名称是否匹配 2) 为参数提供默认值 3) 或提供不带此参数的其他操作方法。
【讨论】:
谢谢@yo hal,你的答案原来是解决我这个错误的特定实例的答案。在这种情况下,框架吐出的错误消息恰好是有史以来最没用的错误消息。【参考方案12】:我也遇到了这个问题,我想分享一下,因为我在上面找不到我的问题。
这是我的代码
return RedirectToAction("Overview", model.Id);
调用此 ActionResult:
public ActionResult Overview(int id)
我认为它足够聪明,可以弄清楚我传递给它的值是 Overview 的 id 参数,但事实并非如此。这修复了它:
return RedirectToAction("Overview", new id = model.Id);
【讨论】:
【参考方案13】:由于没有无参数的公共构造函数,我得到了同样的异常
代码是这样的:
public class HomeController : Controller
private HomeController()
_repo = new Repository();
改为
public class HomeController : Controller
public HomeController()
_repo = new Repository();
问题已解决。
【讨论】:
我在基类中使用受保护的构造函数时遇到了同样的问题 - 现在似乎是一个明显的解决方案!【参考方案14】:所有答案都说要创建一个无参数的构造函数,如果您不希望任何其他开发人员使用它而只使用模型绑定器,这并不理想。
如果另一个开发人员尝试使用它,公共构造函数上方的属性[Obsolete("For model binding only", true)]
将引发编译器错误。我花了很长时间才找到这个,希望它对某人有所帮助。
【讨论】:
完美 - 添加此属性允许 MVC 模型绑定在运行时工作,并将属性的布尔参数设置为 true 防止(在编译时)任何实例化无参数构造函数的尝试。最佳答案在这里。【参考方案15】:我收到了这个错误。我在构造函数中使用了接口,而我的依赖解析器无法解析,当我注册它时,错误就消失了。
【讨论】:
如果您有新问题,请照此发布。这应该是评论或新问题,因为它不会尝试回答问题。【参考方案16】:我遇到了同样的问题...
如果您使用接口将连接与 DbContext 解耦(像我一样),您可以使用 structuremap.mvc (3 or 4 - nudget package) 能够在控制器类中使用构造。这将为您提供一个 DependencyResolution 文件夹。只需将注释行更改为 For() 并使用()。
【讨论】:
【参考方案17】:虽然这对某些人来说可能很明显,但对我来说,这个错误的罪魁祸首是我的 MVC 方法绑定到了一个包含Tuple<>
类型属性的模型。 Tuple<>
没有无参数构造函数。
【讨论】:
【参考方案18】:由于缺少依赖注入器/解析器容器和/或缺少绑定,可能会出现此类型错误
-
使用 NugetPacketManager(Unity、Ninject 或任何您喜欢的)将依赖注入器添加到您的项目中
为类添加接口绑定和具体实现
UnityMConfig.cs
using System;
using Unity;
using <your_namespace for the interfaces and concrete classes>
namespace <your_namespace>
public static class UnityConfig
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
var container = new UnityContainer();
RegisterTypes(container);
return container;
);
public static IUnityContainer Container => container.Value;
public static void RegisterTypes(IUnityContainer container)
container.RegisterType <IInterfaceClassName, ConcreteImplementationOfInterface> ();
UnityMvcActivator.cs
using System.Linq;
using System.Web.Mvc;
using Unity.AspNet.Mvc;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(xxxx.UnityMvcActivator), nameof(xxxx.UnityMvcActivator.Start))]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(xxxx.UnityMvcActivator), nameof(xxxx.UnityMvcActivator.Shutdown))]
namespace <your_namespace>
public static class UnityMvcActivator
public static void Start()
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(UnityConfig.Container));
DependencyResolver.SetResolver(new UnityDependencyResolver(UnityConfig.Container));
public static void Shutdown()
UnityConfig.Container.Dispose();
【讨论】:
【参考方案19】:我遇到了同样的问题,但后来发现添加任何新接口和相应的类都需要在 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)
【讨论】:
【参考方案20】:就我而言,我的班级有[Serializable]
属性。
如果你的类是[Serializable]
,你需要有一个不带参数的构造函数
【讨论】:
【参考方案21】:我在DOMAIN Folder里面的模型中添加了一个无参构造函数,问题就解决了。
public User()
【讨论】:
【参考方案22】:当我添加了一种实例化类的新方法时,我开始出现此错误。
例子:
public class myClass
public string id get; set;
public List<string> myListget; 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> myListget; 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;
【讨论】:
【参考方案23】:我在表单中添加了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)
【讨论】:
【参考方案24】:这发生在我身上,这个页面上的结果是一个很好的资源,引导了我很多方向,但我想添加另一种可能性:
正如其他回复中所说,创建带参数的构造函数会删除隐式无参数构造函数,因此您必须显式键入它。
我的问题是带有默认参数的构造函数也触发了这个异常。
给出错误:
public CustomerWrapper(CustomerDto customer = null)...
作品:
public CustomerWrapper(CustomerDto customer)...
public CustomerWrapper():this(null)
【讨论】:
【参考方案25】:很可能您的控制器中有参数化构造函数,而您使用的任何依赖解析器都无法正确解析依赖。您需要在编写依赖解析器方法的地方放置断点,您将在内部异常中得到确切的错误。
【讨论】:
【参考方案26】:我遇到了同样的问题。
刚刚从 Post Action 方法参数中删除了 HttpFileCollectionBase files
并在方法主体中添加HttpFileCollectionBase files = Request.Files;
。
【讨论】:
【参考方案27】:所以我之前在进行 ajax 调用时也收到了该消息。所以它基本上要求的是由控制器调用的模型类中的构造函数,没有任何参数。
这是一个例子
public class MyClass
public MyClass() // so here would be your parameterless constructor
【讨论】:
我从模型中删除了默认构造函数,这对我有用。以上是关于ASP.NET MVC:没有为此对象定义无参数构造函数的主要内容,如果未能解决你的问题,请参考以下文章
ExpressMapper / EntityFramework - 没有为此对象定义无参数构造函数
用于 ASP.NET MVC 的没有 DI 容器的控制器的构造函数参数