Here's my situation: I have a very simple MVC4 application. One view, one controller, limited responsibility. It functions as a landing page for a vendor application, and is responsible for:
I'm having trouble with #3, but only since I have added Ninject to the project (dependency injection was needed to allow Unit Tests to be written). Since then, I get "No parameterless constructor defined for this object" for the HTTP Post controller action, and only the post . GET on this controller works just fine. There is only one constructor for this controller, and it is called successfully for either GET or POST - adding a breakpoint I can step through the calling of the constructor, and only after passing the last brace do I get the "No parameterless construtor" error.
I've tried the solutions in these StackOverflow answers: https://stackoverflow.com/a/14027722/1139007
https://stackoverflow.com/a/17909609/1139007
https://stackoverflow.com/a/21010851/1139007
I have ensured that all my bindings are properly set in NinjectWebCommon.cs (they are). I have verified (per this answer ) that the Web.Config has the correct configuration. I have uninstalled and reinstalled Ninject.MVC3 (and all dependencies). I am pulling my hair out.
Here's the default constructor:
public HomeController(IAlerts alertRepository, IStore storeRepository, IMemberRecord memberRepository, IHTTPUserRequest userRequest, IActiveDirectory ad)
{
_alertRepository = alertRepository;
_storeRepository = storeRepository;
_memberRepository = memberRepository;
_userRequest = userRequest;
_ad = ad;
}
Here's the HttpPost controller action:
[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.");
}
}
The repositories each have a constructor which accepts an instance of IDataAccess as a parameter:
public StoreRepository(IDataAccess db)
{
_db = db;
stores = db.getStores();
}
The DataAccess class which is bound to IDataAccess has only a parameterless constructor, and utilizes web.config for its connection string:
public DataAccess()
{
this.connectionString = ConfigurationManager.ConnectionStrings["DEV_ConnectionString"].ToString();
}
The bindings in 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>();
}
Any suggestions or guidance as to what I should be looking at here? If this goes on too much longer, I may just refactor the whole project to rip out Ninject (and lose many of the unit tests, unfortunately).
EDIT: Complete error was requested in the comments, so I will include here.
[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.WrappedAsyncResult1.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
You need to ensure that all your bound concrete classes have a constructor. In this case it looks as though the culprit(s) will be ActiveDirectory
and/or HTTPUserRequest
.
Just add a parameterless constructor to each and the error should be resolved. ie:
public class ActiveDirectory : IActiveDirectory
{
public ActiveDirectory() {}
....
}
Most (if not all) DI engines will throw this exception when there is no constructor for a concrete class, so this is not uncommon.
Update
Ninject is not the issue in this case, @ascary's comments below highlight AVMemberRecord
as the culprit class, which is used as a paramater on the Post
action. The exception is being thrown in this case because the Model Binder cannot find a paramaterless constructor to instantiate the type.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.