无法从apicontroller中的OwinContext获取UserManager

Mar*_*arc 68 c# asp.net-web-api owin asp.net-identity

我正在关注Microsoft示例以使用Identity 2.0.0实现电子邮件验证

我被困在这一部分

public ApplicationUserManager UserManager
{
   get
   {
      return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
   }
   private set
   {
      _userManager = value;
   }
}
Run Code Online (Sandbox Code Playgroud)

这适用于controllerHttpContext不包含ApiController中的任何GetOwinContext方法.

所以我试过HttpContext.Current.GetOwinContext()但方法GetUserManager不存在.

我无法找到一种方法来获得UserManager我在Startup.Auth.cs中的构建

// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
    //Configure the db context, user manager and role manager to use a single instance per request
    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
    ...
}
Run Code Online (Sandbox Code Playgroud)

这条线

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
Run Code Online (Sandbox Code Playgroud)

调用以下函数来配置 UserManager

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
     var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
     //Configure validation logic for usernames
     manager.UserValidator = new UserValidator<ApplicationUser>(manager)
     {
         AllowOnlyAlphanumericUserNames = false,
         RequireUniqueEmail = true
     };

     // Configure user lockout defaults
     manager.UserLockoutEnabledByDefault = true;
     manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
     manager.MaxFailedAccessAttemptsBeforeLockout = 5;

     manager.EmailService = new EmailService();

     var dataProtectionProvider = options.DataProtectionProvider;
     if (dataProtectionProvider != null)
     {
         manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
     }
     return manager;
}
Run Code Online (Sandbox Code Playgroud)

我如何可以访问此UserManagerApiController

Rik*_*ard 87

我之前真的误解了你的问题.我想你只是缺少一些使用陈述.

GetOwinContext().GetUserManager<ApplicationUserManager>()Microsoft.AspNet.Identity.Owin.

所以尝试添加此部分:

using Microsoft.AspNet.Identity.Owin;
using Microsoft.AspNet.Identity; // Maybe this one too

var manager = HttpContext.Current.GetOwinContext().GetUserManager<UserManager<User>>();
Run Code Online (Sandbox Code Playgroud)

  • 使用时会更安全吗:System.Web.HttpContext.Current.Request.GetOwinContext().GetUserManager .... (7认同)

小智 27

如果要对控制器进行单元测试,此扩展方法可能是更好的解决方案.

using System;
using System.Net.Http;
using System.Web;
using Microsoft.Owin;

public static IOwinContext GetOwinContext(this HttpRequestMessage request)
{
    var context = request.Properties["MS_HttpContext"] as HttpContextWrapper;
    if (context != null)
    {
        return HttpContextBaseExtensions.GetOwinContext(context.Request);
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

用法:

public ApplicationUserManager UserManager
{
   get
   {
      return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
   }
   private set
   {
      _userManager = value;
   }
}
Run Code Online (Sandbox Code Playgroud)

  • BTW ...`Request.GetOwinContext()`在Microsoft.AspNet.WebApi.Owin nuget包中定义 (5认同)
  • 我完全同意,`HttpContext.Current`引入了对`System.Web`的依赖,这在自托管方案中是不可用的.注入`Request.GetOwinContext()`,因此允许测试能力.后者既不是. (3认同)

mub*_*her 5

这段代码节省了我的时间...

       var manager = 
       new ApplicationUserManager(new UserStore<ApplicationUser>(new ApplicationDbContext()));
Run Code Online (Sandbox Code Playgroud)

您可以在控制器操作中使用它来获取UserManager的实例。