简体   繁体   中英

ASP.Net MVC4 using Ninject, HttpPost returns 'No parameterless constructor'

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:

  1. Reading ActiveDirectory properties of the user
  2. Reading membership of that user from the vendor application's db
  3. If membership for the user does not exist, adding membership entry via user confirmation, then redirecting to the vendor application
  4. If membership does exist, displaying links to permit user to click through to the vendor application

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.&lt;&gt;c__DisplayClass1d.&lt;BeginExecuteCore&gt;b__17(AsyncCallback asyncCallback, Object asyncState) +30 System.Web.Mvc.Async.WrappedAsyncResult1.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.&lt;&gt;c__DisplayClass8.&lt;BeginProcessRequest&gt;b__2(AsyncCallback asyncCallback, Object asyncState) +71 System.Web.Mvc.Async.WrappedAsyncResult1.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM