ASP.Net MVC4 使用 Ninject、HttpPost returns 'No parameterless constructor'
ASP.Net MVC4 using Ninject, HttpPost returns 'No parameterless constructor'
这是我的情况:
我有一个非常简单的 MVC4 应用程序。一个视图,一个控制器,有限责任。它用作供应商应用程序的登录页面,并负责:
- 正在读取用户的 ActiveDirectory 属性
- 正在从供应商应用程序的数据库中读取该用户的成员资格
- 如果用户的成员资格不存在,通过用户确认添加成员资格条目,然后重定向到供应商应用程序
- 如果会员资格确实存在,则显示链接以允许用户点击进入供应商应用程序
我在 #3 上遇到了问题,但只是因为我已经将 Ninject 添加到项目中(需要依赖注入才能编写单元测试)。从那时起,对于 HTTP Post 控制器操作,我得到 "No parameterless constructor defined for this object",而 只有 post。 GET 在这个控制器上工作得很好。这个控制器只有一个构造函数,它被 GET 或 POST 成功调用 - 添加一个断点我可以逐步调用构造函数,只有在传递最后一个大括号后我才能得到 "No parameterless construtor" 错误。
我已经尝试了这些 Whosebug 答案中的解决方案:
我已确保在 NinjectWebCommon.cs 中正确设置了我的所有绑定(它们是)。我已验证(根据 this answer)Web.Config 具有正确的配置。我已经卸载并重新安装 Ninject.MVC3(以及所有依赖项)。我正在拔头发。
这是默认构造函数:
public HomeController(IAlerts alertRepository, IStore storeRepository, IMemberRecord memberRepository, IHTTPUserRequest userRequest, IActiveDirectory ad)
{
_alertRepository = alertRepository;
_storeRepository = storeRepository;
_memberRepository = memberRepository;
_userRequest = userRequest;
_ad = ad;
}
这是 HttpPost 控制器操作:
[HttpPost]
public HttpStatusCodeResult InsertMember(AVMemberRecord profile)
{
bool validStore = _storeRepository.isValidStore(profile.defaultStoreBU);
if (validStore)
{
bool success = _memberRepository.insertMemberRecord(profile);
if (success)
{
return new HttpStatusCodeResult(200);
}
else
{
return new HttpStatusCodeResult(500, "Error inserting Member record. Please open a ticket to request access.");
}
}
else
{
return new HttpStatusCodeResult(500, "Invalid store association for user. Please open a ticket to request access.");
}
}
每个存储库都有一个接受 IDataAccess 实例作为参数的构造函数:
public StoreRepository(IDataAccess db)
{
_db = db;
stores = db.getStores();
}
绑定到 IDataAccess 的 DataAccess class 只有一个无参数构造函数,并利用 web.config 作为其连接字符串:
public DataAccess()
{
this.connectionString = ConfigurationManager.ConnectionStrings["DEV_ConnectionString"].ToString();
}
NinjectWebCommon.cs中的绑定:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IDataAccess>().To<DataAccess>();
kernel.Bind<IActiveDirectory>().To<ActiveDirectory>();
kernel.Bind<IStore>().To<StoreRepository>();
kernel.Bind<IMemberRecord>().To<MemberRepository>();
kernel.Bind<IAlerts>().To<AlertRepository>();
kernel.Bind<IHTTPUserRequest>().To<HTTPUserRequest>();
}
关于我应该在这里查看的内容有什么建议或指导吗?如果这种情况持续的时间太长,我可能会重构整个项目以删除 Ninject(不幸的是,丢失了许多单元测试)。
编辑: 评论中要求出现完整错误,因此我将在此处包含。
<pre></p>
<p>[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, StackCrawlMark& stackMark) +113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +66
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +183
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +564
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +416
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +317
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +117
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +446
System.Web.Mvc.Async.WrappedAsyncResult<code>1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +30
System.Web.Mvc.Async.WrappedAsyncResult
1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +381
System.Web.Mvc.Async.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +71
System.Web.Mvc.Async.WrappedAsyncResult
1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +49
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
您需要确保所有绑定的具体 classes 都有一个构造函数。
在这种情况下,罪魁祸首似乎是 ActiveDirectory
and/or HTTPUserRequest
.
只需为每个添加一个无参数构造函数,即可解决错误。即:
public class ActiveDirectory : IActiveDirectory
{
public ActiveDirectory() {}
....
}
大多数(如果不是全部)DI 引擎在没有具体 class 的构造函数时会抛出此异常,因此这并不少见。
更新
Ninject 在这种情况下不是问题,@ascary 下面的评论突出显示 AVMemberRecord
作为罪魁祸首 class,它用作 Post
上的参数行动。在这种情况下抛出异常是因为模型绑定器找不到无参数构造函数来实例化类型。
这是我的情况: 我有一个非常简单的 MVC4 应用程序。一个视图,一个控制器,有限责任。它用作供应商应用程序的登录页面,并负责:
- 正在读取用户的 ActiveDirectory 属性
- 正在从供应商应用程序的数据库中读取该用户的成员资格
- 如果用户的成员资格不存在,通过用户确认添加成员资格条目,然后重定向到供应商应用程序
- 如果会员资格确实存在,则显示链接以允许用户点击进入供应商应用程序
我在 #3 上遇到了问题,但只是因为我已经将 Ninject 添加到项目中(需要依赖注入才能编写单元测试)。从那时起,对于 HTTP Post 控制器操作,我得到 "No parameterless constructor defined for this object",而 只有 post。 GET 在这个控制器上工作得很好。这个控制器只有一个构造函数,它被 GET 或 POST 成功调用 - 添加一个断点我可以逐步调用构造函数,只有在传递最后一个大括号后我才能得到 "No parameterless construtor" 错误。
我已经尝试了这些 Whosebug 答案中的解决方案:
我已确保在 NinjectWebCommon.cs 中正确设置了我的所有绑定(它们是)。我已验证(根据 this answer)Web.Config 具有正确的配置。我已经卸载并重新安装 Ninject.MVC3(以及所有依赖项)。我正在拔头发。
这是默认构造函数:
public HomeController(IAlerts alertRepository, IStore storeRepository, IMemberRecord memberRepository, IHTTPUserRequest userRequest, IActiveDirectory ad)
{
_alertRepository = alertRepository;
_storeRepository = storeRepository;
_memberRepository = memberRepository;
_userRequest = userRequest;
_ad = ad;
}
这是 HttpPost 控制器操作:
[HttpPost]
public HttpStatusCodeResult InsertMember(AVMemberRecord profile)
{
bool validStore = _storeRepository.isValidStore(profile.defaultStoreBU);
if (validStore)
{
bool success = _memberRepository.insertMemberRecord(profile);
if (success)
{
return new HttpStatusCodeResult(200);
}
else
{
return new HttpStatusCodeResult(500, "Error inserting Member record. Please open a ticket to request access.");
}
}
else
{
return new HttpStatusCodeResult(500, "Invalid store association for user. Please open a ticket to request access.");
}
}
每个存储库都有一个接受 IDataAccess 实例作为参数的构造函数:
public StoreRepository(IDataAccess db)
{
_db = db;
stores = db.getStores();
}
绑定到 IDataAccess 的 DataAccess class 只有一个无参数构造函数,并利用 web.config 作为其连接字符串:
public DataAccess()
{
this.connectionString = ConfigurationManager.ConnectionStrings["DEV_ConnectionString"].ToString();
}
NinjectWebCommon.cs中的绑定:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IDataAccess>().To<DataAccess>();
kernel.Bind<IActiveDirectory>().To<ActiveDirectory>();
kernel.Bind<IStore>().To<StoreRepository>();
kernel.Bind<IMemberRecord>().To<MemberRepository>();
kernel.Bind<IAlerts>().To<AlertRepository>();
kernel.Bind<IHTTPUserRequest>().To<HTTPUserRequest>();
}
关于我应该在这里查看的内容有什么建议或指导吗?如果这种情况持续的时间太长,我可能会重构整个项目以删除 Ninject(不幸的是,丢失了许多单元测试)。
编辑: 评论中要求出现完整错误,因此我将在此处包含。
<pre></p>
<p>[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, StackCrawlMark& stackMark) +113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +66
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +183
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +564
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +416
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +317
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +117
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +446
System.Web.Mvc.Async.WrappedAsyncResult<code>1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +30
System.Web.Mvc.Async.WrappedAsyncResult
1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +381
System.Web.Mvc.Async.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +71
System.Web.Mvc.Async.WrappedAsyncResult
1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +49
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
您需要确保所有绑定的具体 classes 都有一个构造函数。
在这种情况下,罪魁祸首似乎是 ActiveDirectory
and/or HTTPUserRequest
.
只需为每个添加一个无参数构造函数,即可解决错误。即:
public class ActiveDirectory : IActiveDirectory
{
public ActiveDirectory() {}
....
}
大多数(如果不是全部)DI 引擎在没有具体 class 的构造函数时会抛出此异常,因此这并不少见。
更新
Ninject 在这种情况下不是问题,@ascary 下面的评论突出显示 AVMemberRecord
作为罪魁祸首 class,它用作 Post
上的参数行动。在这种情况下抛出异常是因为模型绑定器找不到无参数构造函数来实例化类型。