MVC 4的Web API控制器没有默认构造函数? [英] MVC 4 Web Api Controller does not have a default constructor?

查看:2035
本文介绍了MVC 4的Web API控制器没有默认构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是跟踪:

<Error>
   <Message>An error has occurred.</Message>

   <ExceptionMessage>
      Type 'ProjectName.Web.Api.Controllers.ContinentsController' does not have a default constructor
   </ExceptionMessage>

   <ExceptionType>System.ArgumentException</ExceptionType>

   <StackTrace>
      at System.Linq.Expressions.Expression.New(Type type)

      at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)

      at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)

      at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
   </StackTrace>
</Error>

我觉得这是不可思议的公共类UsersController:ApiController {...} 工作就好了。我比较了2个控制器,所有的设置和结构是相似的。

I find this weird as public class UsersController : ApiController { ... } is working just fine. I have compared the 2 controllers, all the settings and structures are similar.

我使用 Ninject 和我有我类似杰米·库尔茨 <系统设置href=\"http://www.amazon.ca/gp/product/1430249773/ref=s9_simh_gw_p14_d11_i1?pf_rd_m=A3DWYIK6Y9EEQB&pf_rd_s=center-4&pf_rd_r=18BS0P23TZH1Q8KWS8JK&pf_rd_t=101&pf_rd_p=1375923642&pf_rd_i=915398\">Asp.Net MVC 4和Web API:从开始建立一个REST服务来完成

I am using Ninject and i have my system setup similar to Jamie Kurtz Asp.Net Mvc 4 and the Web Api: Building a REST Service from Start to Finish.

从堆栈跟踪,是任何人都能够发现的问题,以及如何解决呢?谢谢!

From the stack trace, is anyone able to spot the problem and how to solve it? Thanks!

的要求。

As Requested.

ContinentsController

[LoggingNHibernateSession]
public class ContinentsController : ApiController
{
    private readonly ISession _session;
    private readonly IContinentMapper _continentMapper;
    private readonly IHttpContinentFetcher _httpContinentFetcher;
    private readonly IDateTime _dateTime;

    public ContinentsController(ISession session, IContinentMapper continentMapper, IHttpContinentFetcher continentFetcher, IDateTime dateTime)
    {
        _session = session;
        _continentMapper = continentMapper;
        _httpContinentFetcher = continentFetcher;
        _dateTime = dateTime;
    }

    public IEnumerable<Continent> Get()
    {
        var continents = _session
            .Query<Data.Model.Continent>()
            .Select(_continentMapper.CreateContinent)
            .ToList();

        return continents;
    }

    public Continent Get(long id)
    {
        var modelContinent = _httpContinentFetcher.GetContinent(id);
        var continent = _continentMapper.CreateContinent(modelContinent);

            return continent;
        }
  }

UsersController :工作得很好。

    public class UsersController : ApiController
    {
        private readonly ISession _session;
        private readonly IUserManager _userManager;
        private readonly IUserMapper _userMapper;
        private readonly IHttpUserFetcher _userFetcher;

        public UsersController(
            IUserManager userManager,
            IUserMapper userMapper,
            IHttpUserFetcher userFetcher,
            ISession session)
        {
            _userManager = userManager;
            _userMapper = userMapper;
            _userFetcher = userFetcher;
            _session = session;
        }

        [Queryable]
        public IQueryable<Data.Model.User> Get()
        {
            return _session.Query<Data.Model.User>();
        }

        [LoggingNHibernateSession]
        public User Get(Guid id)
        {
            var user = _userFetcher.GetUser(id);
            return _userMapper.CreateUser(user);
        }
    }

我使用 NinjectWebCommon.cs ,并在其中,我有这个和其他一些默认方式:

I am using NinjectWebCommon.cs and in it, i have this and a few other default methods.:

        private static void RegisterServices(IKernel kernel)
        {
            var containerConfigurator = new NinjectConfigurator();
            containerConfigurator.Configure(kernel);

            GlobalConfiguration.Configuration.MessageHandlers.Add(kernel.Get<BasicAuthenticationMessageHandler>());
        }

然后,我有 NinjectConfigurator.cs

public class NinjectConfigurator
{
    ......
    private void AddBindings(IKernel container)
        {
            .....
            container.Bind<IDateTime>().To<DateTimeAdapter>();
            container.Bind<IDatabaseValueParser>().To<DatabaseValueParser>();

            //HttpFetchers
            container.Bind<IHttpUserFetcher>().To<HttpUserFetcher>();
            container.Bind<IHttpContinentFetcher>().To<HttpContinentFetcher>();                                

            //TypeMappers
            container.Bind<IUserManager>().To<UserManager>();
            container.Bind<IMembershipInfoProvider>().To<MembershipAdapter>();
            container.Bind<IUserMapper>().To<UserMapper>();
            container.Bind<IContinentMapper>().To<ContinentMapper>();    
            .........
        }
     .......
}

两者 NinjectWebCommon.cs NinjectConfigurator.cs 位于 App_Start 文件夹中。

container.Bind&LT; ISession的方式&gt;()ToMethod(了createSession); NHibernate的。它是在 NinjectConfigurator.cs 私人无效ConfigureNHibernate(容器的iKernel){...}

推荐答案

此错误是一个已知的错误,当你没有设置在您的应用程序依赖解析器。控制器工厂找不到参数的构造函数来创建控制器和执行动作的方法(或动词的方法?)。所以,你必须创建一个依赖解析器类并将它放在你的web应用程序的初始化。这将解决您的控制器的依赖关系。

This error is a known error when you do not set the dependency resolver in your application. The Controller Factory could not find a parameterless constructor to create the controller and execute the action method (or verb method?). So, you have to create a dependency resolver class and set it on the initialization of your web app. It will resolve dependencies of your controllers.

使用 ninject ,你可以尝试这样的事:

Using ninject, you could try something like this:

using Ninject; 
using Ninject.Syntax; 
using System; 
using System.Collections.Generic; 
using System.Diagnostics.Contracts; 
using System.Web.Http.Dependencies; 

namespace MyApplication.App_Start 
{     
    public class NinjectDependencyScope : IDependencyScope     
    {         
        private IResolutionRoot resolver;         

        internal NinjectDependencyScope(IResolutionRoot resolver)         
        {             
            Contract.Assert(resolver != null);             
            this.resolver = resolver;         
        }         

        public void Dispose()         
        {             
            IDisposable disposable = resolver as IDisposable;             
            if (disposable != null)                 
                disposable.Dispose();             
            resolver = null;         
        }         

        public object GetService(Type serviceType)         
        {             
            if (resolver == null)                 
                throw new ObjectDisposedException("this", "This scope has already been disposed");             

            return resolver.TryGet(serviceType);         
        }   

        public IEnumerable GetServices(Type serviceType)         
        {             
            if (resolver == null)                 
                throw new ObjectDisposedException("this", "This scope has already been disposed");             

            return resolver.GetAll(serviceType);         
        }     
    }     

    public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver     
    {         
        private IKernel kernel;         
        public NinjectDependencyResolver(IKernel kernel)             
            : base(kernel)         
        {             
            this.kernel = kernel;         
        }         

        public IDependencyScope BeginScope()         
        {             
            return new NinjectDependencyScope(kernel.BeginBlock());         
        }     
    } 
}

NinjectDependencyResolver 类需要一个 Ninject StandardKernel 对象作为构造函数的参数,并使用该参考每​​当一个依赖范围是流水线。
为了使这一切工作,在 NinjectDependencyResolver 类被分配给应用程序的全局配置:

The NinjectDependencyResolver class takes a Ninject StandardKernel object as a constructor argument and this reference is used whenever a dependency scope is pipelined. To make this all work, the NinjectDependencyResolver class is assigned to the application's global configuration:

private static IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
    kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

    // register all your dependencies on the kernel container
    RegisterServices(kernel);

    // register the dependency resolver passing the kernel container
    GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);

    return kernel;
}

在在Application_Start事件后,你的的Global.asax.cs 文件,调用这个 CreateKernel 方法。

On your Global.asax.cs file in the end of Application_Start event, call this CreateKernel method.

这篇关于MVC 4的Web API控制器没有默认构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆