20
votes

I'm using Identity and I have a problem that I make a new example project and with individual authentication and scaffold identity InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UI.Services.IEmailSender' while attempting to activate 'MASQ.Areas.Identity.Pages.Account.RegisterModel'.

5

5 Answers

40
votes

I am using ASP.NET Core 3.0 and had similar issue. I added the following .AddDefaultUI() to my Startup.cs & it worked.

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddIdentity<IdentityUser, IdentityRole>()
                .AddDefaultTokenProviders()
                .AddDefaultUI()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddControllersWithViews();
            services.AddRazorPages().AddRazorRuntimeCompilation();
        }
15
votes

There're two ways to do that :

  1. remove the services.AddDefaultTokenProviders() in the ConfigurureServices() to disable two-factor authentication (2FA) :
    // file: `Startup.cs` :
    services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
        ///.AddDefaultTokenProviders(); /// remove this line
    
  2. Add your own IEmailSender and ISmsSender implementation to DI contianer if you would like to enable 2FA

    // file: `Startup.cs`
    
    services.AddTransient<IEmailSender,YourEmailSender>();
    services.AddTransient<IEmailSender,YourSmsSender>();
    

Edit:

Both should work.

Both should work for ASP.NET Core 2.1. However, as of ASP.NET Core 3.0, the first approach doesn't work any more.

3
votes

Add Default UI in the configuration service:

services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders()
    .AddDefaultUI();
1
votes

For ASP.NET Core 5.0 you can use the following code, instead of calling AddIdentity

services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<AppDbContext>()
            .AddDefaultTokenProviders();
0
votes
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });
        services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddIdentity<ApplicationUser, ApplicationRole>(
           option => {
               option.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
               option.Lockout.MaxFailedAccessAttempts = 5;
               option.Lockout.AllowedForNewUsers = false;
           })
          .AddEntityFrameworkStores<ApplicationDbContext>()
          .AddDefaultTokenProviders();

        //services.AddDbContext<ApplicationDbContext>(options =>
        //    options.UseSqlServer(
        //        Configuration.GetConnectionString("DefaultConnection")));
        //services.AddIdentity<ApplicationUser, IdentityRole>()
        //    .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();

        services.AddTransient<Areas.Identity.Services.IEmailSender, AuthMessageSender>();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}