asp.net-mvc 错误:确保控制器有一个无参数的公共构造函数 webapi
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28552726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
error: Make sure that the controller has a parameterless public constructor webapi
提问by steveareeno
I am using webapi, unity, and mvc. I am getting the error "Make sure that the controller has a parameterless public constructor". I have seen treads on similar problems but still can't get it to work. I have installed unity.webapi and seem to have all the necessary references:
我正在使用 webapi、unity 和 mvc。我收到错误“确保控制器具有无参数的公共构造函数”。我已经看到了类似问题的痕迹,但仍然无法让它发挥作用。我已经安装了 unity.webapi 并且似乎有所有必要的参考:
- Microsoft.Practices.Unity - runtime: v4.0.30319, version: 3.5.0.0
- Microsoft.Practices.Unity.Mvc - runtime: v4.0.30319, version: 3.5.0.0
- Unity.WebApi - runtime: v4.0.30319, version: 5.1.0.0
- System.Web.Http - runtime: v4.0.30319, version: 5.2.2.0
- System.Web.Mvc - runtime: v4.0.30319, version: 5.2.2.0
- Microsoft.Practices.Unity - 运行时:v4.0.30319,版本:3.5.0.0
- Microsoft.Practices.Unity.Mvc - 运行时:v4.0.30319,版本:3.5.0.0
- Unity.WebApi - 运行时:v4.0.30319,版本:5.1.0.0
- System.Web.Http - 运行时:v4.0.30319,版本:5.2.2.0
- System.Web.Mvc - 运行时:v4.0.30319,版本:5.2.2.0
I verified everything matches what is on this site:
我验证了所有内容都与本网站上的内容相符:
Here is what I have:
这是我所拥有的:
Bootstrapper:
引导程序:
public static class Bootstrapper
{
public static IUnityContainer Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
return container;
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
container.RegisterType<IDatabaseFactoryHouseDB, DatabaseFactoryHouseDB>(new HierarchicalLifetimeManager());
container.RegisterType<UnitOfWorkHouseDB>();
// repositories
container.RegisterType<IEmployeeRepository, EmployeeRepository>();
// services
container.RegisterType<IEmployeeService, EmployeeService>();
RegisterTypes(container);
return container;
}
public static void RegisterTypes(IUnityContainer container) { }
}
Global.asax:
全球.asax:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Database.SetInitializer<HouseDBContext>(null);
Bootstrapper.Initialise();
//required for setting routes in the attributes of a controller method
GlobalConfiguration.Configuration.EnsureInitialized();
}
}
Api controller:
api控制器:
public class EmployeeApiController : ApiController
{
private readonly IEmployeeService employeeService;
public EmployeeApiController(IEmployeeService employeeService)
{
this.employeeService = employeeService;
}
// rest of controller
}
WebApiConfig:
WebApiConfig:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// use json strings as the default return value for the app
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}
UnityConfig:
统一配置:
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
Not sure what I am missing.
不知道我错过了什么。
Edit:I noticed I had a UnityConfig class in my App_Start folder. After looking into the comment by Sarathy, I realized it wasn't be called. I commented out my bootstrapper initialization in the global.asax and added the line UnityConfig.RegisterComponents(), so now my global.asax looks like this:
编辑:我注意到我的 App_Start 文件夹中有一个 UnityConfig 类。在查看 Sarathy 的评论后,我意识到它没有被调用。我在 global.asax 中注释掉了我的引导程序初始化并添加了一行 UnityConfig.RegisterComponents(),所以现在我的 global.asax 看起来像这样:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
UnityConfig.RegisterComponents(); // <--- added
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Database.SetInitializer<HouseDBContext>(null);
//Bootstrapper.Initialise(); <-- not using bootstrapper anymore
//required for setting routes in the attributes of a controller method
GlobalConfiguration.Configuration.EnsureInitialized();
}
}
and my UnityConfig looks like this:
我的 UnityConfig 看起来像这样:
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
container.RegisterType<IDatabaseFactoryHouseDB, DatabaseFactoryHouseDB>(new HierarchicalLifetimeManager());
//container.RegisterType<IUnitOfWork>();
container.RegisterType<UnitOfWorkHouseDB>();
// repositories
container.RegisterType<IEmployeeRepository, EmployeeRepository>();
// services
container.RegisterType<IEmployeeService, EmployeeService>();
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
}
}
Yet I still get the parameterless constructor error. What is funny is even though I have added a parameterless constructor:
但是我仍然收到无参数构造函数错误。有趣的是,即使我添加了一个无参数构造函数:
public class EmployeeApiController : ApiController
{
private readonly IEmployeeService employeeService;
public EmployeeApiController()
: base()
{
}
public EmployeeApiController(IEmployeeService employeeService)
{
this.employeeService = employeeService;
}
}
I still get the error when using the unityconfig approach. With bootstrapper, I didn't get the error but my services were not initialized.
使用 unityconfig 方法时,我仍然收到错误消息。使用引导程序,我没有收到错误,但我的服务没有初始化。
I am totally confused. Somehow I feel I am mixing MVC and WebApi and things are not resolving correctly...
我完全糊涂了。不知何故,我觉得我正在混合 MVC 和 WebApi 并且事情没有正确解决......
EDIT 2:
编辑2:
I looked at the inner exception of my parameterless constructor error and noticed it is mentioning my IUnitOfWork class:
我查看了无参数构造函数错误的内部异常,并注意到它提到了我的 IUnitOfWork 类:
"Resolution of the dependency failed, type = \"AngularMVC.Controllers.EmployeeApiController\", name = \"(none)\".\r\nException occurred while: while resolving.\r\nException is: InvalidOperationException - The current type, AngularMVC.Models.Interfaces.IUnitOfWork, is an interface and cannot be constructed. Are you missing a type mapping?\r\n-----------------------------------------------\r\nAt the time of the exception, the container was:\r\n\r\n Resolving AngularMVC.Controllers.EmployeeApiController,(none)\r\n Resolving parameter \"employeeService\" of constructor AngularMVC.Controllers.EmployeeApiController(AngularMVC.Services.IEmployeeService employeeService)\r\n Resolving AngularMVC.Services.EmployeeService,(none) (mapped from AngularMVC.Services.IEmployeeService, (none))\r\n Resolving parameter \"unitOfWork\" of constructor AngularMVC.Services.EmployeeService(AngularMVC.Models.Repositories.IEmployeeRepository employeeRepository, AngularMVC.Models.Interfaces.IUnitOfWork unitOfWork)\r\n Resolving AngularMVC.Models.Interfaces.IUnitOfWork,(none)\r\n"
"依赖项的解析失败,类型 = \"AngularMVC.Controllers.EmployeeApiController\", name = \"(none)\"。\r\n发生异常时:解析时。\r\n异常是:InvalidOperationException -当前类型, AngularMVC.Models.Interfaces.IUnitOfWork, 是一个接口,不能被构造。你是否缺少类型映射?\r\n----------------------------------------- --\r\n发生异常时,容器为:\r\n\r\n Resolving AngularMVC.Controllers.EmployeeApiController,(none)\r\n Resolving parameter \"employeeService\" of constructor AngularMVC.Controllers .EmployeeApiController(AngularMVC.Services.IEmployeeService employeeService)\r\n 解析 AngularMVC.Services.EmployeeService,(none) (映射自 AngularMVC.Services.IEmployeeService, (none))\r\n 解析构造函数的参数 \"unitOfWork\" AngularMVC.Services.EmployeeService(AngularMVC.Models.Repositories.IEmployeeRepository employeeRepository, AngularMVC.Models.Interfaces.IUnitOfWork unitOfWork)\r\n 解析 AngularMVC.Models.Interfaces.IUnitOfWork,(none)\r\n"
which is only this:
仅此而已:
public interface IUnitOfWork
{
void Commit();
}
When I do the following in my UnityConfig:
当我在 UnityConfig 中执行以下操作时:
container.RegisterType<IUnitOfWork>();
IUnitOfWork sm = container.Resolve<IUnitOfWork>();
I get the same error stating "The current type, AngularMVC.Models.Interfaces.IUnitOfWork, is an interface and cannot be constructed. Are you missing a type mapping?"
我收到同样的错误,指出“当前类型 AngularMVC.Models.Interfaces.IUnitOfWork 是一个接口,无法构造。您是否缺少类型映射?”
回答by Jeff Chen
From your code, I can see you are using Unity as your IoC Container. IoC Container will handle the initialization of controller class.
从您的代码中,我可以看到您正在使用 Unity 作为您的 IoC 容器。IoC Container 将处理控制器类的初始化。
To make IoC container to create a instance of your controller, your controller class needs to have a parameterless public constructor(aka default constructor).
要使 IoC 容器创建控制器的实例,您的控制器类需要有一个无参数的公共构造函数(又名默认构造函数)。
public class EmployeeApiController : ApiController
{
private readonly IEmployeeService employeeService;
public EmployeeAPIController() : base()
{
}
public EmployeeApiController(IEmployeeService employeeService)
{
this.employeeService = employeeService;
}
}
UPDATE 1: 18 Feb 2015From your code I have not seen a implementation of IUnitOfWork interface. The unit of work is pattern that is widely used in domain central modeling. Normally, unit of work pattern is used with repository pattern together. The purpose of of unit of work, is to make multiple repository can working on a same database context.
更新 1:2015年2 月 18 日从您的代码中,我还没有看到 IUnitOfWork 接口的实现。工作单元是在领域中心建模中广泛使用的模式。通常,工作单元模式与存储库模式一起使用。工作单元的目的是使多个存储库可以在同一个数据库上下文中工作。
From your code, you register
从您的代码,您注册
//container.RegisterType<IUnitOfWork>();
container.RegisterType<UnitOfWorkHouseDB>();
However, I think you should have register code like this: (I assume UnitOfWorkHouseDB is the implementation of IUnitOfWork)
但是,我认为你应该有这样的注册代码:(我假设 UnitOfWorkHouseDB 是 IUnitOfWork 的实现)
container.RegisterType<IUnitOfWork, UnitOfWorkHouseDB>();
Which is similar as: (EmployeeRepository is the implementation of IEmployeeRepository)
类似于:(EmployeeRepository 是 IEmployeeRepository 的实现)
// repositories
container.RegisterType<IEmployeeRepository, EmployeeRepository>();
Normally, when I use unit of work and repository pattern, I will do following structure:
通常,当我使用工作单元和存储库模式时,我会做以下结构:
IUnitOfWork interface
IUnitOfWork 接口
public interface IUnitOfWork
{
void Commit();
}
IUnitOfWork implementation:
IUnitOfWork 实现:
public class UnitOfWork : IUnitOfWork
{
//DBContext could your own db context, or a interface, like IDatabaseFactoryHouseDB
private DBContext _ctx;
public UnitOfWork(DbContext ctx)
{
_ctx = ctx;
}
private IEmployeeRepository _EmployeeRepository;
public IEmployeeRepository EmployeeRepository
{
get { return _EmployeeRepository ?? (_EmployeeRepository = new EmployeeRepository(_ctx)); }
}
private ICustomerRepository _CustomerRepository;
public ICustomerRepository CustomerRepository
{
get { return _CustomerRepository ?? (_CustomerRepository = new CustomerRepository(_ctx)); }
}
public void Commit()
{
_ctx.SaveChange();
}
}

