ASP.NET WebAPI标识2 - 用户注册/注册方法上的GetOwinContext错误

时间:2014-12-18 13:35:47

标签: asp.net asp.net-web-api asp.net-identity owin asp.net-identity-2

我有一个WebAPI 2.1应用程序,我遇到了用户注册问题。我在Register方法的第一行放置了一个断点,但是没有到达。相反,它在以下区域失败:

    public ApplicationUserManager UserManager
    {
        get
        {
            var a = Request; // this is null !!
            return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

    [AllowAnonymous]
    [Route("Register")]
    [ValidateModel]
    public async Task<IHttpActionResult> Register(RegisterBindingModel model)
    {

        var user = new ApplicationUser() { // <<<<< Debug breakpoint here never reached
            Email = model.Email, 
            FirstName = model.FirstName, 
            LastName = model.LastName,
            OrganizationId = 1,
            OrganizationIds = "1",
            RoleId = (int)ERole.Student,
            SubjectId = 1,
            SubjectIds = "1",
            UserName = model.UserName
        };




System.ArgumentNullException was unhandled by user code
  HResult=-2147467261
  Message=Value cannot be null.
Parameter name: request
  Source=System.Web.Http.Owin
  ParamName=request
  StackTrace:
       at System.Net.Http.OwinHttpRequestMessageExtensions.GetOwinContext(HttpRequestMessage request)
       at WebRole.Controllers.AccountController.get_UserManager() in c:\G\abr\WebRole\Controllers\Web API - Data\AccountController.cs:line 50
       at WebRole.Controllers.AccountController.Dispose(Boolean disposing) in c:\G\ab\WebRole\Controllers\Web API - Data\AccountController.cs:line 376
       at System.Web.Http.ApiController.Dispose()
       at System.Web.Http.Cors.AttributeBasedPolicyProviderFactory.SelectAction(HttpRequestMessage request, IHttpRouteData routeData, HttpConfiguration config)
       at System.Web.Http.Cors.AttributeBasedPolicyProviderFactory.GetCorsPolicyProvider(HttpRequestMessage request)
  InnerException: 

如果有人能给我任何关于我可以帮助解决这个问题的建议,我将非常感激。

特别是可以向我解释在此配置中如何处理请求的流程。我觉得它很混乱,我想知道WebAPI和Owin是如何结合在一起的。不知道这让我很难理解这个问题。

感谢。

这里的参考是我的WebAPI启动课程:

public partial class Startup
{
    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

    public static string PublicClientId { get; private set; }

    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {

        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // Configure the application for OAuth based flow
        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);

    }
}

更新1 - 在Darin的评论之后问题正确。问题不在构造函数中。

更新2 - 处理方法:

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            UserManager.Dispose();
        }

        base.Dispose(disposing);
    }

更新3 - 添加/ Register方法以显示我有断点(从未到达)的位置

2 个答案:

答案 0 :(得分:3)

在dispose方法中没有检查null _userManager,但是支持字段仍然可以为null。您也可以访问UserManager属性,而不是直接使用支持字段。因此,每次_userManager为null并且AccountController被释放时,UserManager将尝试创建一个新的OwinContext。这将失败。

将您的处置方法更改为:

protected override void Dispose(bool disposing)
{
    if (disposing && _userManager != null)
    {
        _userManager.Dispose();
        _userManager = null
    }

    base.Dispose(disposing);
}

答案 1 :(得分:2)

  

我遇到的问题是在帐户构造函数

HTTP上下文在控制器构造函数中不可用,这是设计使然。执行中可以访问它的最早点是 Initialize方法之后

protected override void Initialize(HttpControllerContext controllerContext)
{
    base.Initialize(controllerContext);

    // This is the earliest stage where you can access the HTTP context (request, response, ...).
}