在 IIS 上将 Ninject 与 WebAPI 一起使用时出现无参数构造函数错误,在本地调试时运行正常
Parameterless constructor error when using Ninject with WebAPI on IIS, runs fine when debugging locally
当我 运行 来自 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);
}
}
}
当我使用 NuGet 将 EntityFramework 安装到我的 WebAPI 项目时,一切都开始工作了。这毫无意义,完全违背了 DI/Ninject 和我的数据访问层的目的,但我会在 "good design" 不起作用的情况下采用糟糕的设计。
当我 运行 来自 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);
}
}
}
当我使用 NuGet 将 EntityFramework 安装到我的 WebAPI 项目时,一切都开始工作了。这毫无意义,完全违背了 DI/Ninject 和我的数据访问层的目的,但我会在 "good design" 不起作用的情况下采用糟糕的设计。