【问题标题】:Ninject OWIN extensions break CreatePerOwinContext for Web APINinject OWIN 扩展破坏了 Web API 的 CreatePerOwinContext
【发布时间】:2014-12-06 00:47:44
【问题描述】:
在尝试将 Ninject 与使用 ASP.NET Identity 的新 Web API 2 项目一起使用时,我遇到了一些奇怪的行为。我无法将回调传递给 CreatePerOwinContext() 以触发对 Web API 控制器的请求。对于 MVC 控制器,它们可以正常工作。
重建步骤:
- 文件 -> 新建 VS 2013 ASP.NET Web 应用程序
- 检查 MVC 和 WebAPI
- 在身份验证下选择个人
- 为 Ninject、Ninject.Web.Common.OwinHost、Ninject.Web.WebApi.OwinHost 和依赖包添加 nuget 包
- 关注 guidance 为启用 Owin 的应用配置 ninject
- 在 ApplicationUserManager.Create() 中放置断点,然后 F5 调试
- 见证对 Home 控制器的请求工作正常 - 断点已命中。向 API 控制器发出提琴手请求 - 例如,api/Account/Register 并且根本不会调用回调
我不是 ninject 爱好者,所以我不确定这是我做错了什么还是 Ninject OWIN 扩展中的错误。我倾向于留下 OwinContext 并简单地使用 Ninject perHttpRequest 范围,但我不确定 ASP.NET 身份系统是否会中断。我听说如果我不将内容保存在 OWIN 上下文中,可能会对 OwinContext.Get() 进行内部调用。
非常感谢任何人的想法。
【问题讨论】:
标签:
asp.net-web-api
ninject
owin
asp.net-identity-2
【解决方案1】:
我最终通过使用 Ninject 进行所有生命周期管理来解决这个问题。显然 .CreatePerOwinContext() 是一个 stop gap solution,如果使用完整的 DI 工具,则不需要它。
我看到的唯一需要注意的是,对于基于 cookie 的身份验证,ASP.NET Identity 将在 OwinContext 中查找其 UserManager。我正在使用基于令牌的身份验证,但我看到有些人继续将 UserManager 填充到 OwinContext 中。
我的 Ninject 绑定:
private static readonly Lazy<IKernel> _lazyKernel = new Lazy<IKernel>(CreateKernel);
// Access the singleton kernel via this property
public static IKernel Kernel { get { return _lazyKernel.Value; } }
private void ConfigureNinject(IAppBuilder app)
{
app.UseNinjectMiddleware(() => Kernel);
Kernel.Bind<IAppBuilder>().ToConstant(app);
}
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<AuthDbContext>().ToSelf().InRequestScope().WithConstructorArgument("connectionString", "MyConnectionString");
kernel.Bind<IUserStore<MyApplicationUser, int>>().To<MyUserStore>().InRequestScope();
kernel.Bind<IRoleStore<MyRole, int>>().To<MyRoleStore>().InRequestScope();
kernel.Bind<MyUserManager>().ToSelf().InRequestScope();
kernel.Bind<ISecureDataFormat<AuthenticationTicket>>().To<SecureDataFormat<AuthenticationTicket>>();
kernel.Bind<IDataSerializer<AuthenticationTicket>>().To<TicketSerializer>();
kernel.Bind<IDataProtector>().ToMethod(x => x.Kernel.Get<IAppBuilder>().GetDataProtectionProvider().Create("ASP.NET Identity"));
kernel.Bind<ITextEncoder>().To<Base64UrlTextEncoder>();
}