Search code examples
razorasp.net-core-mvcasp.net-core-6.0

ASP.NET Core 6 MVC + views: exception when switching from AddDefaultIdentity to AddIdentity


I have opened a test project (.NET 6, VS2022) based on ASP.NET Core MVC and views template (not Razor pages), with activated individual user accounts.

Program.cs looks like this (from the template):

builder.Services.AddDefaultIdentity<IdentityUser>(options ...

builder.Services.AddControllersWithViews();

...
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();

So far so good.

Now I added some example code to seed the user database, which needs access to the RoleManager:

var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();`

However, that throws an exception

No service for type Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]'

which could be fixed (thanks Stackoverflow) by changing the AddDefaultIdentity() to AddIdentity() which introduces IdentityRole:

builder.Services.AddIdentity<IdentityUser, IdentityRole>(options ...

However, now I get an exception further down with

app.MapRazorPages();

System.InvalidOperationException: 'Unable to find the required services. Please add all the required services by calling 'IServiceCollection.AddRazorPages' inside the call to 'ConfigureServices(...)' in the application startup code.'

Which services need to be configured and how?

When I remove app.MapRazorPages();, the user management pages (login, user registration) do no longer work (404 error).

When I instead add builder.Service.AddRazorPages() above, the routing is also broken: a route to "/account/login" is missing, probably because Razor pages are somewhat differently organized than MVC controllers. Obviously, I do not want Razor pages, just Razor logic in a few views, and basically MVC architecture.

I am, honestly, a bit confused, since the official documentation does not help much.


Solution

  • Follow your document, I fount that what you did is adding an initialization to create data in the database. So I created a new .net 6 MVC app and integrate default authentication. Pick up Authentication type field with Individual User Accounts when creating the project, then run Update-Database command in Package Manager Console window. Now I have a empty .net 6 MVC project with default asp.net core authentication.

    Next, I followed the document and created a SeedData.cs file in the root folder:

    using Microsoft.AspNetCore.Identity;
    
    namespace WebAppDefIdentity
    {
        public static class SeedData
        {
            //public const string AdministratorRole = "Administrator";
    
            public static async Task InitializeAsync(IServiceProvider services) {
                var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
                await EnsureRolesAsync(roleManager);
            }
    
            private static async Task EnsureRolesAsync(RoleManager<IdentityRole> roleManager)
            {
                var alreadyExists = await roleManager.RoleExistsAsync("Administrator");
            }
    
        }
    }
    

    And the document is .net 5 oriented project, so need a little change. In the Program.cs file, adding following codes.

    using (var scope = app.Services.CreateScope())
    {
        var aa = scope.ServiceProvider;
        await SeedData.InitializeAsync(aa);
    }
    

    enter image description here

    Then I reproduce your first exception

    enter image description here

    To solve this exception, I changed in Program.cs with code .AddRoles<IdentityRole>()

    enter image description here

    Then no exception. enter image description here