No parameterless constructor object defined

2019-05-14 23:56发布

问题:

I know that this is a duplicate question but i can't find answer to my error. I'm trying to show a list of my rooms saved in database but i get next error:

 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:

    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

    Stack Trace:

   [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 'HotelProjectFinal.Controllers.RoomController'. 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() +8969412
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

But i have a constructor withou a parameter:

 namespace HotelProjectFinal.Controllers
 {
     public class RoomController : Controller
     {
         private IRoomRepository repository;

         public RoomController(IRoomRepository roomRepository) 
         {
             repository = roomRepository;
         }

         public ViewResult List()
         {
             return View(repository.Rooms);
         }
     }
}

My view is :

  @model IEnumerable<HotelProjectFinal.Models.Room>

   @{
   ViewBag.Title = "List";
    }

    @foreach (var p in Model)
    {
       <div class="item">
        <h3>@p.Room_number</h3>
       @p.Room_Type
       <h4>@p.Room_Type.Price.ToString("c")</h4>
      </div>
      }

I am using ninject:

               public class NinjectControllerFactory : DefaultControllerFactory
            {
    private IKernel ninjectKernel;
    public NinjectControllerFactory()
    {
        ninjectKernel = new StandardKernel();
        AddBindings();
    }
    protected override IController GetControllerInstance(RequestContext requestContext,
    Type controllerType)
    {
        return controllerType == null
        ? null
        : (IController)ninjectKernel.Get(controllerType);
    }
    private void AddBindings()
    {
        ninjectKernel.Bind<IRoomRepository>().To<EFRoomRepository>();
    }
          }
            }

回答1:

You've got a controller factory, but the fact that the stacktrace says nothing about Ninject suggests you have forgotten to tell MVC about it.

You could fix that by adding a line to tell it that.

However the recommended practice is to hook Ninject in by adding a NuGet reference to Ninject.MVC3. There are docs about it on the associated Ninject MVC3 wiki.



回答2:

Please try changing your constructors to the following:

public RoomController() { } // You were missing this parameterless constructor

[Inject] 
public RoomController(IRoomRepository roomRepository) 
{
    repository = roomRepository;
}

Ninject is looking for a parameterless constructor because you haven't specified [Inject] above constructor that you wish to use for dependency injection. This has confused "Ninject" and caused an exception to be thrown.

The primary DI pattern is Constructor Injection. When activating an instance of a type Ninject will choose one of the type’s constructors to use by applying the following rules in order:-

  • If a constructor has an [Inject] attribute, it is used (but if you apply the attribute to more than one, Ninject will throw a NotSupportedException at runtime upon detection).
  • If no constructors have an [Inject] attribute, Ninject will select the one with the most parameters that Ninject understands how to resolve.
  • If no constructors are defined, Ninject will select the default parameterless constructor (assuming there is one).

More information can be found here:

https://github.com/ninject/ninject/wiki/Injection-Patterns

As pointed out by Ruben, [Inject] attribute pollutes the controller with external concerns.

This ties your code to a specific container. (Although Ninject does permits the customization of the specific attribute to look for, the point remains – you’re polluting an interface with external concerns.)

Your actual problem probably relies in a missing reference to Ninject.MVC3



回答3:

Even though IRoomRepository could be null, that doesn't make it a parameterless constructor. At first glace, it looks like your IoC isn't wired up correctly for IRoomRepository. With no IoC, or misconfigured IoC, the controller activator looks for a parameterless constructor for your controllers.

 // This is a parameterless constructor.
 public RoomController() 
 { }

 // This is not a parameterless constructor.
 public RoomController(IRoomRepository roomRepository) 
 {
     repository = roomRepository;
 }

Edit, Are you using Ninject.Mvc and your base MvcHttpApplication is implementing NinjectHttpApplication?