3 votes

Obtenir l'instance de UserManager en dehors de l'application web ASP.NET ?

J'ai une application web ASP.NET MVC 5 avec ASP.NET Identity (Individual Accounts). Mais j'ai besoin de pouvoir enregistrer de nouveaux utilisateurs à partir d'une application console.

Je transfère donc certaines des classes ASP.NET Identity de l'application Web dans une bibliothèque de classes qui sera partagée entre l'application Web et l'interface de programmation.

J'ai réussi à déplacer les éléments suivants :

public class PortalDbContext : IdentityDbContext<PortalUser>
{
    public PortalDbContext(string connectionString)
        : base(connectionString, throwIfV1Schema: false)
    {
    }

    public static PortalDbContext Create(string connectionString)
    {
        return new PortalDbContext(connectionString);
    }
}

public class PortalUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<PortalUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

        // Add custom user claims here
        return userIdentity;
    }
}

public class PortalUserManager : UserManager<PortalUser>
{
    public PortalUserManager(IUserStore<PortalUser> store) : base(store)
    {
    }

    public async Task<IdentityResult> RegisterUser(string email, string password)
    {
        PortalUser user = new PortalUser { UserName = email, Email = email };

        return await this.CreateAsync(user, password);
    }
}

Mais je n'ai aucune idée de l'endroit où obtenir le IUserStore<PortalUser> el PortalUserManager besoins de.

Dans l'application web, ce gestionnaire est récupéré à partir de HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>() que je ne peux manifestement pas utiliser dans une bibliothèque de classes.

1voto

John H Points 4556

Jetez un coup d'œil à la OwinRequestScopeContext paquet nuget. Il vous permet d'utiliser un contexte sans dépendre de System.Web . J'ajouterai l'exemple du readme actuel pour éviter d'avoir une réponse uniquement basée sur des liens :

# Usage 

// using Owin; you can use UseRequestScopeContext extension method.

// enabled timing is according to Pipeline.
// so I recommend enable as far in advance as possible.
app.UseRequestScopeContext();

app.UseErrorPage();
app.Run(async _ =>
{
    // get global context like HttpContext.Current.
    var context = OwinRequestScopeContext.Current;

    // Environment is raw Owin Environment as IDictionary<string, object>.
    var __ = context.Environment;

    // optional:If you want to change Microsoft.Owin.OwinContext, you can wrap.
    new Microsoft.Owin.OwinContext(context.Environment);

    // Timestamp is request started(correctly called RequestScopeContextMiddleware timing).
    var ___ = context.Timestamp;

    // Items is IDictionary<string, object> like HttpContext.Items.
    // Items is threadsafe(as ConcurrentDictionary) by default.
    var ____ = context.Items;

    // DisposeOnPipelineCompleted can register dispose when request completed(correctly RequestScopeContextMiddleware underling Middlewares finished)
    // return value is cancelToken. If call token.Dispose() then canceled register.
    var cancelToken = context.DisposeOnPipelineCompleted(new TraceDisposable());

    // OwinRequestScopeContext over async/await also ConfigureAwait(false)
    context.Items["test"] = "foo";
    await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
    var _____ = OwinRequestScopeContext.Current.Items["test"]; // foo

    await Task.Run(() =>
    {
        // OwinRequestScopeContext over new thread/threadpool.
        var ______ = OwinRequestScopeContext.Current.Items["test"]; // foo
    });

    _.Response.ContentType = "text/plain";
    await _.Response.WriteAsync("Hello OwinRequestScopeContext! => ");
    await _.Response.WriteAsync(OwinRequestScopeContext.Current.Items["test"] as string); // render foo
});

0voto

emzero Points 1152

J'ai fini par ajouter une méthode statique Create(string connectionString) a PortalUserManager qui créera le UserStore y DbContext et renvoie une nouvelle instance du gestionnaire.

public class PortalDbContext : IdentityDbContext<PortalUser>
{
    public PortalDbContext(string connectionString)
        : base(connectionString, throwIfV1Schema: false)
    {
    }

    public static PortalDbContext Create(string connectionString)
    {
        return new PortalDbContext(connectionString);
    }
}

public class PortalUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<PortalUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

        // Add custom user claims here
        return userIdentity;
    }
}

public class PortalUserManager : UserManager<PortalUser>
{
    public PortalUserManager(IUserStore<PortalUser> store) : base(store)
    {
    }

    public static PortalUserManager Create(string connectionString)
    {
        UserStore<PortalUser> userStore = new UserStore<PortalUser>(PortalDbContext.Create(connectionString));

        PortalUserManager manager = new PortalUserManager(userStore);

        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<PortalUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = true,
            RequireUniqueEmail = true                
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

        return manager;
    }

    public async Task<IdentityResult> RegisterUser(string email, string password)
    {
        PortalUser user = new PortalUser { UserName = email, Email = email };

        return await this.CreateAsync(user, password);
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X