VS2015发布多层.NET Framework解决方案后生产环境遇Error 500
解决ASP.NET Web API依赖注入导致的控制器实例化失败问题
问题背景
多层.NET Framework解决方案结构:
- BusinessEntity层:包含DTO子层(如BeMonitorRequest.cs)
- Web层:包含Controllers子层(如MonitorController.cs)
使用VS2015发布功能部署到生产环境后,访问api/monitor/getMonitorCasesByFilter接口出现500错误,本地运行正常。错误核心:无法创建MonitorController实例,提示该类型无默认构造函数。
相关代码片段
1. MonitorController.cs
[RoutePrefix("api/monitor")] public class MonitorController : BaseController { private readonly ISelector iSelector; private readonly IMonitorCase iMonitorCase; private readonly ITimeConverter iTimeConverter; public MonitorController(IMonitorCase iMonitorCase, ISelector iSelector, ITimeConverter iTimeConverter) { this.iMonitorCase = iMonitorCase; this.iSelector = iSelector; this.iTimeConverter = iTimeConverter; } [HttpGet] [Route("getMonitorCasesByFilter")] public IHttpActionResult CasesByFilter([FromUri] BeMonitorRequest request) { request.ProjectId = this.GetProject(); request.UserName = this.GetUserName(); List<BeMonitorCase> cases = this.iMonitorCase.GetMonitorCasesMainByFilter(request); return Ok(cases); } }
2. BeMonitorRequest.cs
using MyProject.BusinessEntity.DTO; namespace MyProject.BusinessEntity.DTO { public class BeMonitorRequest { public int ProjectId { get; set; } public string ProjectDB { get; set; } public string From { get; set; } public string To { get; set; } public string RadNumber { get; set; } public string UserName { get; set; } public string FullName { get; set; } public int ProcessId { get; set; } public string ProcessName { get; set; } public int TaskId { get; set; } public string NotificationType { get; set; } public int StepTypeId { get; set; } public int WiClosed { get; set; } public int WinClosed { get; set; } } }
3. Startup.cs
using Microsoft.Owin; using Owin; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Web; [assembly: OwinStartup(typeof(MyProject.Web.Startup))] namespace MyProject.Web { public partial class Startup { public void Configuration(IAppBuilder app) { ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; Middleware.Configuration(app); } } }
4. Middleware.cs
using Owin; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MyProject.Web { public class Middleware { public static void Configuration(IAppBuilder app) { var container = Dependency.DependencyConfig.Configure(); WebApiConfig.ConfigureWebApi(app, container); } } }
5. DependencyConfig.cs
using MyProject.Bl; using MyProject.Bl.Interfaces; using MyProject.Dal; using MyProject.Dal.Interfaces; using MyProject.Utils; using MyProject.Utils.Interfaces; using MyProject.Utils.Proxies; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Web; using Unity; namespace MyProject.Web.Dependency { internal static class DependencyConfig { internal static IUnityContainer Configure() { IUnityContainer container = new UnityContainer(); var host = ConfigurationManager.AppSettings["Host"]; var connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; container.RegisterType<ICacheService, MemoryCacheService>(); container.RegisterInstance<IConfigProxyService>(new ConfigProxyService(host)); container.RegisterType<IConfigurationCacheService, ConfigurationCacheService>(); container.RegisterInstance<IDalConnection>(new DalConnection(connectionString, true)); //... container.RegisterType<IDalMonitorCase, DalMonitorCase>(); container.RegisterType<IMonitorCase, MonitorCase>(); //... return container; } } }
6. WebApiUnityResolver.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http.Dependencies; using Unity; namespace MyProject.Web.Dependency { public class WebApiUnityResolver : IDependencyResolver { protected IUnityContainer container; public WebApiUnityResolver(IUnityContainer container) { if (container == null) { throw new NotImplementedException("container"); } this.container = container; } public IDependencyScope BeginScope() { var child = container.CreateChildContainer(); return new WebApiUnityResolver(child); } public void Dispose() { container.Dispose(); } public object GetService(Type serviceType) { try { return container.Resolve(serviceType); } catch (ResolutionFailedException e) { return null; } } public IEnumerable<object> GetServices(Type serviceType) { try { return container.ResolveAll(serviceType); } catch (ResolutionFailedException) { return new List<object>(); } } } }
错误详情
{ "message" : "An error has occurred.", "exceptionMessage": "An error occurred when trying to create a controller of type 'MonitorController'. Make sure that the controller has a parameterless public constructor.", "exceptionType" : "System.InvalidOperationException", "stackTrace" : " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()", "innerException": { "message" : "An error has occurred.", "exceptionMessage": "Type 'MyProject.Web.Controllers.MonitorController' does not have a default constructor", "exceptionType" : "System.ArgumentException", "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)" } }
环境信息
- 本地OS:Windows 10 Enterprise 22H2(19045.4412)
- 服务器OS:Windows Server 2022 Datacenter 21H2(20348.1906)
- 服务器IIS:10.0.20348.1
- VS2015版本:14.0.25431.01 Update 3
- 目标框架:.NET Framework 4.5.2
已尝试方案
- 逐个项目清理重建
- 整个解决方案清理重建
解决方案
核心问题分析
错误说明Web API默认控制器激活器无法找到MonitorController的默认构造函数,本质是Unity依赖注入解析器未正确注册到Web API管道。虽已创建Unity容器和解析器,但需确认WebApiConfig.ConfigureWebApi方法是否完成解析器的注册。
修复步骤
- 完善
WebApiConfig.ConfigureWebApi方法,确保将Unity解析器绑定到Web API:
using System.Web.Http; using Unity; namespace MyProject.Web { public static class WebApiConfig { public static void ConfigureWebApi(IAppBuilder app, IUnityContainer container) { HttpConfiguration config = new HttpConfiguration(); // 启用属性路由 config.MapHttpAttributeRoutes(); // 设置Web API依赖解析器为Unity实现 config.DependencyResolver = new Web.Dependency.WebApiUnityResolver(container); app.UseWebApi(config); } } }
- 补全依赖项注册:
当前DependencyConfig中仅注册了IMonitorCase,需补充控制器构造函数中另外两个接口的实现注册:
// 在DependencyConfig.Configure方法中添加 container.RegisterType<ISelector, SelectorImpl>(); // 替换为实际实现类 container.RegisterType<ITimeConverter, TimeConverterImpl>(); // 替换为实际实现类
- 验证生产环境部署包:
- 确认
Unity.dll、Unity.AspNet.WebApi.dll等相关依赖已部署到服务器bin目录 - 检查发布配置是否未勾选“排除未使用的依赖项”,避免Unity组件被误删
内容的提问来源于stack exchange,提问作者momiavive
相关产品推荐
相关产品推荐

