自托管Owin集成Autofac后,带依赖的WebApi控制器全返回404
解决Owin自托管WebAPI换Autofac后跨程序集控制器404问题
核心问题分析
从Ninject切换到Autofac后,本地自托管Owin的Mock控制器(自带默认构造函数)正常,但生产程序集里的依赖注入控制器返回404。本质是WebAPI默认控制器激活器无法实例化无默认构造函数的控制器,且Autofac的依赖解析器未正确接管,同时大概率存在程序集未加载导致控制器未被注册的问题。
针对性解决步骤
1. 修复程序集加载问题(最可能的根因)
AppDomain.CurrentDomain.GetAssemblies()仅返回已加载到内存的程序集,生产WebAPI程序集可能因延迟加载未被包含,导致RegisterApiControllers没注册到目标控制器。
替换Startup中的程序集获取逻辑,手动加载目标程序集:
// 替换原有的assemblies获取代码 var sepsisAssemblies = new List<Assembly>(); // 直接加载生产WebAPI程序集(替换为你的实际程序集名称) sepsisAssemblies.Add(Assembly.Load("Sepsis.WebApi")); // 加载控制器依赖的服务程序集(如果需要) sepsisAssemblies.Add(Assembly.Load("Sepsis.Services")); // 注册控制器 containerBuilder.RegisterApiControllers(sepsisAssemblies.ToArray()).InstancePerRequest();
2. 确认Autofac依赖解析器已生效
在设置config.DependencyResolver后,添加日志验证控制器激活器是否被Autofac接管:
var webApiResolver = new AutofacWebApiDependencyResolver(container); config.DependencyResolver = webApiResolver; // 新增验证代码 var activator = config.Services.GetService(typeof(IHttpControllerActivator)); logger.Info($"当前控制器激活器类型: {activator?.GetType().FullName ?? "未设置"}");
如果输出不是Autofac.Integration.WebApi.AutofacHttpControllerActivator,说明解析器未正确生效,需检查:
- 是否引用了正确版本的
Autofac.WebApi.Owin包 - 是否在
UseWebApi之前设置了config.DependencyResolver
3. 调整Owin中间件顺序
确保中间件顺序符合Autofac集成规范:Autofac中间件在前,WebAPI中间件在后,调整后的顺序:
// 先设置Autofac中间件,再处理WebAPI app.UseAutofacMiddleware(container) .UseAutofacWebApi(config) .UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll) // 把Cors移到WebAPI之前 .UseWebApi(config) .Use<RedirectMiddleware>(); // 自定义中间件放在最后
4. 验证控制器注册状态
除现有日志外,添加代码验证控制器的具体注册细节:
var controllerRegistration = container.ComponentRegistry.Registrations .FirstOrDefault(r => r.Activator.LimitType == typeof(ProvidersController)); logger.Info($"ProvidersController注册详情: {controllerRegistration?.ToString() ?? "未注册"}");
如果显示未注册,说明程序集加载逻辑仍有问题,可直接指定控制器类型注册:
containerBuilder.RegisterType<ProvidersController>().InstancePerRequest();
5. 排除路由与基类问题
- 确认请求URL与
ProvidersController的Route完全匹配(如http://localhost:8888/sites/1/providers) - 验证
BaseControllerWithSessionContext是否直接/间接继承自ApiController,WebAPI仅识别继承自ApiController的类为控制器
额外排查点
- 暂时注释
RedirectMiddleware和全局异常处理中间件,排查是否存在中间件冲突 - 检查
ProvidersController的构造函数参数是否都已在Autofac容器中注册(可通过container.Resolve<ProvidersController>()测试,若抛出异常则说明依赖缺失)
内容的提问来源于stack exchange,提问作者DanCaveman
相关产品推荐
相关产品推荐

