ASP.NET MVC WebApi: No parameterless constructor defined for this object
Asked Answered
D

2

8

I have an ASP.NET MVC 4 Application that I want to implement Unit of Work Pattern.

In my Web Project I have:

IocConfig.cs

using System.Web.Http;
using NinjectMVC.Data;
using NinjectMVC.Data.Contracts;
using Ninject;


namespace NinjectMVC
{
    public class IocConfig
    {
        public static void RegisterIoc(HttpConfiguration config)
        {
            var kernel = new StandardKernel(); // Ninject IoC

            // These registrations are "per instance request".
            // See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/

            kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()
                .InSingletonScope();

            kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();
            kernel.Bind<INinjectMVCUow>().To<NinjectMVCUow>();

            // Tell WebApi how to use our Ninject IoC
            config.DependencyResolver = new NinjectDependencyResolver(kernel);
        }
    }
}

Global.asax

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace NinjectMVC
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            // Tell WebApi to use our custom Ioc (Ninject)
            IocConfig.RegisterIoc(GlobalConfiguration.Configuration);   

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
        }
    }
}

PersonsController.cs

using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using NinjectMVC.Data.Contracts;
using NinjectMVC.Model;

namespace NinjectMVC.Controllers
{
    public class PersonsController : ApiControllerBase
    {
        public PersonsController(INinjectMVCUow uow)
        {
            Uow = uow;
        }

        #region OData Future: IQueryable<T>
        //[Queryable]
        // public IQueryable<Person> Get()
        #endregion

        // GET /api/persons
        public IEnumerable<Person> Get()
        {
            return Uow.Persons.GetAll()
                .OrderBy(p => p.FirstName);
        }

        // GET /api/persons/5
        public Person Get(int id)
        {
            var person = Uow.Persons.GetById(id);
            if (person != null) return person;
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
        }

        // OData: GET /api/persons/?firstname=\'Hans\''
        // With OData query syntax we would not need such methods
        // /api/persons/getbyfirstname?value=Joe1
        [ActionName("getbyfirstname")]
        public Person GetByFirstName(string value)
        {
            var person = Uow.Persons.GetAll()
                .FirstOrDefault(p => p.FirstName.StartsWith(value));

            if (person != null) return person;
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
        }

        // Update an existing person
        // PUT /api/persons/
        public HttpResponseMessage Put(Person person)
        {
            Uow.Persons.Update(person);
            Uow.Commit();
            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }

    }
}

When I try to surf: http://www.domain.com/Persons/Get Im getting:

No parameterless constructor defined for this object.

Is there any stuff I have missed? I would appreciate any help.

Here is the zip file of the project for better references:

http://filebin.ca/E6aoOkaUpbQ/NinjectMVC.zip

Dentilingual answered 31/8, 2012 at 14:40 Comment(0)
A
8

Wep.API uses a different IDependencyResolver than the MVC framework.

When you use theHttpConfiguration.DependencyResolver it only works for ApiControllers. But your ApiControllerBase derives from Controller...

So your ApiControllerBase should inherit from ApiController.

Change it in your ApiBaseController.cs:

public abstract class ApiControllerBase : ApiController
{
}

If you want to inject dependencies to regular Controller derived classes you need to use ( in your IocConfig):

System.Web.Mvc.DependencyResolver.SetResolver(new NinjectMvcDependencyResolver(container));

Note that in this case you cannot use your NinjectDependencyResolver because it's for ApiControllers.

So you need a different NinjectMvcDependencyResolver which should implement System.Web.Mvc.IDependencyResolver.

public class NinjectMvcDependencyResolver: NinjectDependencyScope,
                                           System.Web.Mvc.IDependencyResolver
{
    private IKernel kernel;

    public NinjectDependencyResolver(IKernel kernel)
        : base(kernel)
    {
        this.kernel = kernel;
    }
}
Anthrax answered 31/8, 2012 at 14:56 Comment(3)
Thanks, actually I want to use them for normal Controller. Do you know what should I use instead of HttpConfiguration.DependencyResolver? Thanks a lotDentilingual
Thanks just added that line but I get the following error: The type NinjectMVC.NinjectDependencyResolver does not appear to implement Microsoft.Practices.ServiceLocation.IServiceLocator. Any clue?Dentilingual
This took me a long time to find. Thanks for this!!Gaddy
D
1

I know this is an old thread, but this might be useful for someone. :) In my case, it was missing the DependencyResolver on NinjectWebCommon.cs. I followed this article and everything worked fine.

RegisterServices(kernel);
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
Denunciate answered 12/2, 2018 at 14:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.