【发布时间】:2016-05-12 17:24:31
【问题描述】:
我正在尝试通过 OWIN 设置一个同时使用 MVC 和 Web API 的项目,但我无法让 Autofac 生效。
这是我初始化 Web API 的方式:
public partial class Startup
{
public static void ConfigureWebApi(IAppBuilder app)
{
var config = BuildHttpConfiguration();
var container = AutoFacConfig.BuildContainer();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
app.UseWebApi(config);
}
private static HttpConfiguration BuildHttpConfiguration()
{
var config = new HttpConfiguration();
// Response formatter config
config.Formatters.Remove(
GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
// Setup Web API error reporting
var customErrors = (CustomErrorsSection)ConfigurationManager.GetSection("system.web/customErrors");
IncludeErrorDetailPolicy errorDetailPolicy;
switch (customErrors.Mode)
{
case CustomErrorsMode.RemoteOnly:
errorDetailPolicy
= IncludeErrorDetailPolicy.LocalOnly;
break;
case CustomErrorsMode.On:
errorDetailPolicy
= IncludeErrorDetailPolicy.Never;
break;
case CustomErrorsMode.Off:
errorDetailPolicy
= IncludeErrorDetailPolicy.Always;
break;
default:
throw new ArgumentOutOfRangeException();
}
config.IncludeErrorDetailPolicy = errorDetailPolicy;
config.MapHttpAttributeRoutes();
SwaggerConfig.ConfigureSwagger(config);
return config;
}
}
BuildContainer() 方法如下所示。此方法用于为 MVC 和 Web API 构建容器:
public static IContainer BuildContainer()
{
var builder = new ContainerBuilder();
// Register your MVC controllers.
builder.RegisterControllers(typeof(MvcApplication).Assembly)
.PropertiesAutowired();
builder.RegisterApiControllers(typeof(MvcApplication).Assembly);
// OPTIONAL: Register model binders that require DI.
builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
builder.RegisterModelBinderProvider();
// OPTIONAL: Register web abstractions like HttpContextBase.
builder.RegisterModule<AutofacWebTypesModule>();
// OPTIONAL: Enable property injection in view pages.
builder.RegisterSource(new ViewRegistrationSource());
// OPTIONAL: Enable property injection into action filters.
builder.RegisterFilterProvider();
// Bind the core types
Core.Infrastructure.AutoFacConfig.BuildContainer(builder);
builder.RegisterType<Postal.EmailService>().As<Postal.IEmailService>();
// Effectively auto-wires the anything with an interface within Web assembly infrastructure folder
builder.RegisterAssemblyTypes(typeof(IJwtHelper).Assembly)
.Where(t => t.Namespace != null && t.Namespace.StartsWith("MyApp.Web.Infrastructure") && t.GetInterfaces().Any())
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
// Set the dependency resolver to be Autofac.
return builder.Build();
}
我在某个区域设置了 Web API 控制器,并且所有东西都可以使用标准 MVC 控制器。我想在合适的地方使用 Web API 控制器,但每次我尝试基于 ApiController 请求控制器时,我都会收到错误消息:
An error occurred when trying to create a controller of type 'XxxController'. Make sure that the controller has a parameterless public constructor.
-- 编辑--
API 区域配置如下所示。 (旁注:我知道这不是配置 Web API 的“正确”方式。我包括 {action} 因为我觉得控制器文件太多。)
public class ApiAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "Api"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.Routes.MapHttpRoute(
"Api_default",
"Api/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
身份验证控制器如下所示:
public class AuthenticationController : MyAppApiJwtController
{
private readonly IUserRepository _userRepository;
private readonly IAppSettingsHelper _appSettingsHelper;
private readonly IJwtHelper _jwtHelper;
private readonly IDeviceRepository _deviceRepository;
private readonly IINLDataService _inlDataService;
public AuthenticationController(IUserRepository userRepository, IAppSettingsHelper appSettingsHelper, IJwtHelper jwtHelper, IDeviceRepository deviceRepository, IINLDataService inlDataService)
{
_userRepository = userRepository;
_appSettingsHelper = appSettingsHelper;
_jwtHelper = jwtHelper;
_deviceRepository = deviceRepository;
_inlDataService = inlDataService;
}
[HttpPost]
[AllowAnonymous]
public LoginResponseModel Login(LoginModel model)
{
...
}
}
MyAppApiJwtController 看起来像这样:
public class MyAppApiJwtController : ApiController
{
internal IAuthenticationManager AuthenticationManager
{
get { return Request.GetOwinContext().Authentication; }
}
private JwtUserIdentity _currentJwtUser;
public JwtUserIdentity CurrentJwtUser
{
get
{
if (_currentJwtUser != null)
return _currentJwtUser;
if (User == null)
return null;
_currentJwtUser = new JwtUserIdentity((ClaimsIdentity)User.Identity);
return _currentJwtUser;
}
}
}
-- 编辑2--
我尝试使用的 URL 是 http://localhost:20630/api/authentication/login
-- 编辑 3--
MVC 配置如下所示。这是在 Web API 配置之前调用的:
public partial class Startup
{
public static void ConfigureMvc()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
MvcConfig.RegisterRoutes(RouteTable.Routes);
MvcConfig.ValueConfig();
BundleConfig.RegisterBundles(BundleTable.Bundles);
AutomapperConfig.Configure();
JsonConfig.Configure();
AutoFacConfig.ConfigureContainer();
}
}
【问题讨论】:
-
什么版本的MVC?因为 OWIN 和 MVC 相处得不好。适用于 Web API,但已知会导致路由问题
-
虽然 MVC 方面似乎工作得很好
-
好的。凉爽的。太好了。
-
显示控制器和路由配置。我看到您在设置中使用了属性路由。什么路径给出了错误
-
你去。我正在覆盖
ApiController类,尽管我怀疑这是问题所在。我在 MVC 方面做类似的事情没有问题
标签: asp.net-mvc asp.net-web-api2 owin autofac