【问题标题】:Parameterless constructor error when using Ninject with WebAPI on IIS, runs fine when debugging locally在 IIS 上使用 Ninject 和 WebAPI 时出现无参数构造函数错误,在本地调试时运行良好
【发布时间】:2015-12-12 08:15:08
【问题描述】:

当我从 Visual Studio 运行我的 WebAPI 项目时,它运行良好。但是当我发布到文件系统并将文件复制到我的 IIS 文件夹并运行它时,它失败并出现错误:An error occurred when trying to create a controller of type 'DepartmentsController'. Make sure that the controller has a parameterless public constructor.

关于 SO 的其他一些答案如下:MVC5, Web API 2 and and Ninject 说需要安装Ninject.Web.WebApi.WebHost,我已经安装好了。

我所有的绑定都设置好了,一切都在 NinjectWebCommon 中初始化。当我在本地调试时,正在调用 NinjectWebCommon.Start()。我不知道它叫什么,因为我在应用程序的任何地方都找不到对 NinjectWebCommon.Start() 的引用。为什么这在本地调试中有效,但在 IIS 中失败?

using System.Web.Http;
using MyApp.WebAPI.Infrastructure;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(MyApp.WebAPI.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(MyApp.WebAPI.App_Start.NinjectWebCommon), "Stop")]

namespace MyApp.WebAPI.App_Start {
    using System;
    using System.Web;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;

    public static class NinjectWebCommon {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        public static void Start() {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            IKernel container = null;

            bootstrapper.Initialize(() => {
                container = CreateKernel();
                return container;
            });

            NinjectDependencyResolver resolver = new NinjectDependencyResolver(container);
            GlobalConfiguration.Configuration.DependencyResolver = resolver;
        }

        public static void Stop() {
            bootstrapper.ShutDown();
        }

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

                RegisterServices(kernel);
                return kernel;
            }
            catch {
                kernel.Dispose();
                throw;
            }
        }

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

这是我的绑定所在:

using MyApp.DataAccess.Entities;
using MyApp.Domain.Abstract;
using MyApp.DataAccess.Repositories.Concrete;
using Ninject;
using Ninject.Web.Common;

namespace MyApp.WebAPI.App_Start {
    public class NinjectConfigurator {
        public void Configure(IKernel container) {
            AddBindings(container);
        }

        private void AddBindings(IKernel container) {
            container.Bind<MyAppContext>().ToSelf().InRequestScope();
            container.Bind<IUnitOfWork<MyAppContext>>().To<UnitOfWork<MyAppContext>>();
            container.Bind<IUserRepository>().To<UserRepository>();
            container.Bind<ITeamRepository>().To<TeamRepository>();
            container.Bind<IDepartmentRepository>().To<DepartmentRepository>();
            container.Bind<IDivisionRepository>().To<DivisionRepository>();
        }
    }
}

这是控制器:

using System;
using System.Collections.Generic;
using System.Web.Http;
using MyApp.DataAccess.Entities;
using MyApp.Domain.Abstract;
using Department = MyApp.Domain.Models.Department;

namespace MyApp.WebAPI.Controllers
{
    public class DepartmentsController : ApiController {
        private IUnitOfWork<MyAppContext> _unitOfWork;

        public DepartmentsController(IUnitOfWork<MyAppContext> unitOfWork) {
            _unitOfWork = unitOfWork;
        }

        [HttpGet]
        public IHttpActionResult Get() {
            IEnumerable<Department> deptsList = _unitOfWork.Departments.GetAll();
            return Ok(deptsList);
        }

        [HttpGet]
        public IHttpActionResult Get(int id) {
            Department dept = _unitOfWork.Departments.Get(id);
            return Ok(dept);
        }

        [HttpGet]
        [Route("api/departments/division/{divisionId:int}")]
        public IHttpActionResult GetDepartmentsByDivision(int divisionId) {
            IEnumerable<Department> departmentsInDivision = _unitOfWork.Departments.GetDepartmentsByDivisionId(divisionId);
            return Ok(departmentsInDivision);
        }

        [HttpPost]
        public IHttpActionResult Post(Department department) {
            _unitOfWork.Departments.Add(department);

            //Make sure departmentId is updated from DB before passing back
            return Created("api/departments/" + department.DepartmentId, department);
        }

        [HttpPut]
        public IHttpActionResult Put(Department department) {
            _unitOfWork.Departments.Update(department);
            return Ok(department);
        }
    }
}

【问题讨论】:

  • 更新为包含控制器

标签: c# ninject asp.net-web-api2


【解决方案1】:

当我使用 NuGet 将 EntityFramework 安装到我的 WebAPI 项目时,一切都开始工作了。这是没有意义的,并且完全违背了 DI/Ninject 的目的和我的数据访问层,但我会采用一个有效的糟糕设计,而不是一个不起作用的“好设计”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 2016-03-21
    相关资源
    最近更新 更多