IServiceCollection does not contain a definition for AddDefaultIdentity
Asked Answered
G

3

29

Any idea why am I getting this error?   Error Message --> "IServiceCollection does not contain a definition for AddDefaultIdentity"

public class Program
{
    public async static void Main(string[] args)
    {
        await Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder => {
           webBuilder.UseContentRoot(Directory.GetCurrentDirectory());
           webBuilder.UseKestrel();
           webBuilder.UseAzureAppServices();
           webBuilder.UseStartup<Startup>();
       })
      .Build()
      .RunAsync();
   }
}

public class Startup
{
    public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment)
    {
        Configuration = configuration;
        HostEnvironment = hostEnvironment;
    }

    public IConfiguration Configuration { get; }
    protected IApplicationBuilder ApplicationBuilder { get; private set; }
    public IHostEnvironment HostEnvironment { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        //           services.AddRazorPages();

        services.AddDefaultIdentity<ApplicationUser>()  // "ApplicationUser" is named incorrectly, it should be "IdentityUser" instead, as per Microsoft documentation.
            .AddRoles<IdentityRole<Guid>>()
            .AddEntityFrameworkStores<ApplicationContext, Guid>()  // FYI - AddEntityFrameworkStores() deal with role that derives from IdentityRole, as per documentation.
            //.AddDefaultUI()
            .AddDefaultTokenProviders();

        // [ Old version #1 - replacement ]
        services.ConfigureApplicationCookie(options =>
        {
            options.LoginPath = new PathString("/Home/Index");
            options.SlidingExpiration = true;
            options.ExpireTimeSpan = TimeSpan.FromMinutes(this.Configuration.GetValue<int?>("Authentication:SlidingExpirationTime").Value);
            options.AccessDeniedPath = new PathString("/Home/AccessDenied");
        });

        // [ Old version #2 - replacement ]
        services.Configure<IdentityOptions>(options =>
        {
            options.Password.RequireUppercase = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireDigit = false;
            options.Password.RequiredLength = 7;
        });

        services.AddMvc();
        services.AddSession();

        //services.Configure<AuthorizationOptions>(options =>
        //{
        //});
    }

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });

        // Config Exception.
        if (env.IsDevelopment())
            app.UseDeveloperExceptionPage();
        else
            app.UseExceptionHandler("/Home/ErrorPage.html");
        
        app.UseStaticFiles(); // Note, we are not authenticating for static files if this is before them
        app.UseSession();
        app.UseAuthentication();

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

public class ApplicationUser : IdentityUser<Guid>, IUser
{
}

public interface IUser
{
}

public class ApplicationContext : IdentityDbContext<ApplicationUser, IdentityRole<Guid>, Guid>
{
    public ApplicationContext(DbContextOptions<ApplicationContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="3.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.DataProtection.AzureStorage" Version="1.0.2" />
    <PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Xml" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Session" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.3" />
    <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="3.1.3" />
    <PackgaeReference Include="Microsoft.Extensions.Hosting" Version="3.1.3" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.3" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
    <PackageReference Include="Microsoft.AspNetCore.AzureAppServicesIntegration" Version="1.0.2" />
  </ItemGroup>
</Project>

-- Edited - New Update Below. -------------------------------------------------------

Ok, that help by adding "Microsoft.AspNetCore.Identity.UI" NuGet package. Now I have run into another error. :-/ I can't make sense of this one.

services.AddDefaultIdentity<ApplicationUser>() 
.AddRoles<IdentityRole<Guid>>()
.AddEntityFrameworkStores<ApplicationContext, Guid>() 
.AddDefaultTokenProviders();

The error on the first line is gone now. But now new error on 3rd line here, "AddEntityFrameworkStore<ApplicationContext, Guid>()". The error message is --> "IdentityBuilder" does not contain a definition for "AddEntityFrameworkStores" & no accessible extension method "AddEntityFrameworkStores" accepting a first argument of type "IdentityBuilder" could be found (are you mising a using directive or an assembly reference?).

Not even sure what NuGet package does this "AddEntityFrameworkStores" come from & what have changed from version 1 to 3.1 either.

Gerfen answered 5/5, 2020 at 17:34 Comment(0)
D
39

You would need to add a reference to the Microsoft.AspNetCore.Identity.UI nuget package in order to use AddDefaultIdentity. But if you don't want to migrate to the Identity Razor Class Library I think you can still use .AddIdentity<ApplicationUser, IdentityRole>() in core 3.1. If you do want to migrate to the RCL, the Migration documentation for 2.0 to 2.1 might be a good starting place: https://learn.microsoft.com/en-us/aspnet/core/migration/20_21?view=aspnetcore-3.1#changes-to-authentication-code

--- Edited ---

I've migrated a few sites from 1.1 to 3.1 and the easiest way I have found to do it is this:

  1. Move your entire solution to a backup folder (make sure to leave your source control files where they are).
  2. Create a new application in your original location with the exact same name that targets 3.1. I use the "Web Application (Model-View-Controller)" template in VS 2019 and change the authentication to "Individual User Accounts".
  3. Commit that to source control so you can see what changes you make.
  4. Copy all of your pages, views controllers, and other code to the new application.
  5. Add back any missing nuget packages.
  6. You will probably need to make some changes to your copied code but you can use the changes in source control and the migration docs for a reference point.

It still takes a lot to get it working but otherwise you will need to go through every migration doc starting with the one for 1.x to 2.0 all the way through the doc for 3.0 to 3.1.

Dawes answered 5/5, 2020 at 19:39 Comment(6)
When I added that NuGet package, I get the .AddEntityFrameworkStore<ApplicationContext, Guid>() error saying "IdentityBuilder does not contain a definition for "AddEntityFrameworkStores and no accessible extension method AddEntityFrameworkStores accepting a first arguement of type IdentityBuilder could be found (are you missing a using directory or an assembly reference?)". So not sure how to fix that one too. This method is right after AddDefaultIdentity<>() error, just 2 lines down from it.Gerfen
In my applications I have it like this: .AddEntityFrameworkStores<ApplicationDbContext>(). I've also updated my answer with another suggestion for migrating.Dawes
I have added new project before in VS 2019 & everything is empty. So, I been looking for a sample solution/projects to download from that have just about everything in it. A kitchen sink sample would get me there faster.Gerfen
I use the "Web Application (Model-View-Controller)" template in VS 2019 and change the authentication to "Individual User Accounts"Dawes
Aw nice! I couldn't see the authentication option the first few times til now because the "change" link is hard to find. Ok, now I am figuring out the issue a bit better now. If I use .AddEntityFrameworkStores<ApplicationContext>(), it works but if I use Guid part, .AddEntityFrameworkStores<ApplicationContext, Guid>() it doesn't work. Ok, need to figure out why is that without breaking old code. :-/Gerfen
If you need to use .AddIdentity<ApplicationUser, IdentityRole>(), make sure that you are using Microsoft.AspNetCore.Identity.UI version 6, it is looks like in 7 it was depreciatedNewcastle
I
22

I don't know when this got put in, but in AspNetCore 5.0: services.AddIdentityCore<ApplicationUser>() works. Contains type requirement for TUser only.

Iconium answered 27/2, 2021 at 8:54 Comment(0)
A
2

This answer may not be helpful to the question owner. But some may have made my mistake.

I also had this problem, but my problem was because of my mistake in installing the packages. I installed Microsoft.AspNetCore.Identity.EntityFrameworkCore and using Microsoft.AspNetCore.Identity And this was not known. While I had to install the ‍‍‍Microsoft.AspNetCore.Identity package.

Of course, by using the first package, you should use AddIdentityCore instead of AddIdentity. But some of methods like AddDefaultTokenProviders are not available in the first package.

Allard answered 9/6, 2023 at 10:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.