【问题标题】:IOwinContext.Get<DbContext>() returns nullIOwinContext.Get<DbContext>() 返回 null
【发布时间】:2016-08-20 22:19:45
【问题描述】:

我正在尝试添加身份验证以向我从一个空项目开始的现有 MVC 5 应用程序添加身份验证。我使用个人用户帐户启动了一个新的 WebAPI 项目,以便查看它是如何配置的。我复制了与身份验证有关的代码,并重构了命名空间和类名。在下面的代码中,第一行 var identityContext = context.Get&lt;IdentityDbContext&gt;() 返回 null 并导致第二行 var userStore = new UserStore&lt;AdminAppUser&gt;(identityContext) 由于 null 参数而引发错误。

我可能没有包含足够的代码,因为我对 MVC 身份验证非常陌生,并且对所有部分如何组合在一起知之甚少。如果我需要包含更多代码,请告诉我哪些部分有用。谢谢!

public static AdminAppUserManager Create(IdentityFactoryOptions<AdminAppUserManager> options, IOwinContext context)
    {

        var identityContext = context.Get<IdentityDbContext>();
        var userStore = new UserStore<AdminAppUser>(identityContext);

        var manager = new AdminAppUserManager(userStore);
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<AdminAppUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<AdminAppUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }

编辑:

startup.auth.cs

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(AdminAppIdentityDbContext.Create);
        app.CreatePerOwinContext<AdminAppUserManager>(AdminAppUserManager.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),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

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

        // Uncomment the following lines to enable logging in with third party login providers
        //app.UseMicrosoftAccountAuthentication(
        //    clientId: "",
        //    clientSecret: "");

        //app.UseTwitterAuthentication(
        //    consumerKey: "",
        //    consumerSecret: "");

        //app.UseFacebookAuthentication(
        //    appId: "",
        //    appSecret: "");

        //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
        //{
        //    ClientId = "",
        //    ClientSecret = ""
        //});
    }
}

startup.cs:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }
}

编辑 2:

public class AdminAppIdentityDbContext : IdentityDbContext<AdminAppUser>
{
    public AdminAppIdentityDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static AdminAppIdentityDbContext Create()
    {
        return new AdminAppIdentityDbContext();
    }
}

【问题讨论】:

    标签: c# asp.net-mvc entity-framework asp.net-web-api owin


    【解决方案1】:

    应该有某种在启动时调用的 ConfigureAuth 方法来确定每个 Owin 上下文有一个 IdentityDbContext。该调用将如下所示:

    app.CreatePerOwinContext(IdentityDbContext.Create);
    

    该调用应该在 VS 自动为您生成的样板文件中。

    【讨论】:

    • 我在编辑中添加了我的启动类代码。那个电话已经存在了。
    • AdminAppIdentityDbContext.Create 返回什么类型?
    • 它返回new AdminAppIdentityDbContext();
    • 问题在于返回 null 的调用 (context.Get()) 正在寻找一种获取 IdentityDbContext 类型的方法。您拥有的 app.CreatePerOwnContext 调用正在注册一种返回 AdminAppIdentityDbContext 类型的方法。如果您的代码需要调用 context.Get(),那么您的启动代码需要调用 app.CreatePerOwnContext(IdentityDbContext.Create) 或类似方法。换句话说,类型需要匹配。
    【解决方案2】:

    你也可以只替换 var identityContext = context.Get&lt;IdentityDbContext&gt; 与 var identityContext = new AdminAppIdentityDbContext();, 没关系。它可能会节省您的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多