“No IUserTokenProvider is registered” when using structuremap dependency injection

拈花ヽ惹草 提交于 2019-12-30 09:47:29

问题


I have an MVC 5 project that has been modified to use int as the primary key for identity as shown in this guide

I then enabled email confirmation as described in this guide

Everything worked fine as expected. Then I installed structuremap.mvc5 for dependency injection and added modified DefaultRegistry.cs to

public DefaultRegistry() {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
                scan.AssemblyContainingType(typeof(MyProject.Data.MyDbContext));
                scan.With(new ControllerConvention());
            });
        //For<IExample>().Use<Example>();
        For<IUserStore<ApplicationUser, int>>().Use<MyUserStore>().LifecycleIs<HttpContextLifecycle>();
        For<IAuthenticationManager>().Use(() => HttpContext.Current.GetOwinContext().Authentication);

    }

The project builds fine but when trying to register a new user on the site, the send email confirmation now throws an exception System.NotSupportedException: No IUserTokenProvider is registered when calling UserManager.GenerateEmailConfirmationTokenAsync(userID).

private async Task<string> SendEmailConfirmationTokenAsync(int userID, string subject)
    {
        string code = await UserManager.GenerateEmailConfirmationTokenAsync(userID);
        var callbackUrl = Url.Action("ConfirmEmail", "Account",
           new { userId = userID, code = code }, protocol: Request.Url.Scheme);
        await UserManager.SendEmailAsync(userID, subject,
           "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");

        return callbackUrl;
    }

I am new to dependency injection and pretty sure I am doing something wrong. I'll appreciate your thoughts and insights.


回答1:


IUserTokenProvider by default is inserted by OWIN, but when you resolve UserManager from your DI container, component that provides IUserTokenProvider is not available and this component is not initialised.

You'll have to assign token provider to a global static variable when it is available and then re-use it in UserManager constructor:

public class AuthConfig
{
    public static IDataProtectionProvider DataProtectionProvider { get; set; }

    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        DataProtectionProvider = app.GetDataProtectionProvider();

        // do other configuration 
    }
}

And in then re-assign it in constructor of UserManager constructor:

public UserManager(/*your dependecies*/)
{
    var dataProtectorProvider = AuthConfig.DataProtectionProvider;
    var dataProtector = dataProtectorProvider.Create("My Asp.Net Identity");
    this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, Guid>(dataProtector)
    {
        TokenLifespan = TimeSpan.FromHours(24),
    };
    // other stuff
}


来源:https://stackoverflow.com/questions/27471363/no-iusertokenprovider-is-registered-when-using-structuremap-dependency-injecti

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!