1

I'm trying to build a registration system with roles to view data with limitations in my Asp.Net core project using Identity so I got this error and I'll appreciate it if someone guides me to solutions ............................

InvalidOperationException: Role ADMIN does not exist.
Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore<TUser, TRole, TContext, TKey, TUserClaim, TUserRole, TUserLogin, TUserToken, TRoleClaim>.AddToRoleAsync(TUser user, string normalizedRoleName, CancellationToken cancellationToken)
Microsoft.AspNetCore.Identity.UserManager<TUser>.AddToRoleAsync(TUser user, string role)
Relog.Controllers.AccountController.Register(AppUser model) in AccountController.cs
-
                    Email = model.Email
                };
                var result = await _userManager.CreateAsync(user, model.Password );
                if(result.Succeeded)
                {
                    await _userManager.AddToRoleAsync(user, "Admin");
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {

this is Program.cs

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Relog.Data;
using Relog.Models;
//using System.Configuration;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<AppUserDbContext>(options =>
    options.UseSqlServer(connectionString));
//builder.Services.AddDbContext<StockDbContext>(options =>
//    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<AppUserDbContext>();
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddDbContext<AppUserDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//builder.Services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

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

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{


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

});

app.Run();

this is AccountController

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Relog.Models;
using System.Linq;
using System.Threading.Tasks;

namespace Relog.Controllers
{
    public class AccountController : Controller
    {
        private readonly UserManager<IdentityUser> _userManager;
        private readonly SignInManager<IdentityUser> _signInManager;

        public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
        {
            _userManager = userManager;
            _signInManager = signInManager;

        }



        public IActionResult Register()
        {
            return View();
        }

        [HttpPost]
        public async Task  <IActionResult> Register(AppUser model)
        {
            if(ModelState.IsValid)
            {
                var user = new IdentityUser
                {
                    UserName = model.FirstName + model.LastName,
                    Email = model.Email
                };

                var result = await _userManager.CreateAsync(user, model.Password );
                if(result.Succeeded)
                {
                    await _userManager.AddToRoleAsync(user, "Admin");
                    return RedirectToAction("Index", "Home");

                }
            }
            else
            {
                ModelState.AddModelError("", "Invalid Register!");
                return View(model);
            }

            return View("Register", model);

        }
    }
}

this is my Dbcontext file

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Relog.Models;


namespace Relog.Data
{
    public class AppUserDbContext : IdentityDbContext
    {
        public AppUserDbContext(DbContextOptions<AppUserDbContext> options) : base(options)
        {

        }


        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            builder.Entity<IdentityUser>();
        }


        public DbSet<Relog.Models.AppUser> AppUsers { get; set; }

    }
}

my model :

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Relog.Models
{
    public class AppUser
    {

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }

        [Required]
        [Column(TypeName = "varchar(150)")]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }


        [Required]
        [Column(TypeName = "varchar(150)")]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }



        [Required(ErrorMessage = "Email is required")]
        [EmailAddress]
        public string Email { get; set; }



        [Required(ErrorMessage = "Password is required")]
        [DataType(DataType.Password)]
        public string Password { get; set; }



        [DataType(DataType.Password)]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }

    }
}
ha33
  • 162
  • 1
  • 5
  • 16
  • 1
    Did you insert the role "Admin" into the database? Check the `AspNetRoles` table. – klekmek Jan 02 '22 at 20:46
  • 1
    Does this answer your question? [Add New Role in AspNetRoles Table Identity](https://stackoverflow.com/questions/63730538/add-new-role-in-aspnetroles-table-identity) – Korfu Jan 02 '22 at 20:58

2 Answers2

1

According to the issue description, it's missing "admin" role in the role table.

before the line-code await _userManager.AddToRoleAsync(user, "Admin"); you need to add business logic, like what @klekmek commented, write code to check if there's Admin role in the table, code snippet from this high vote answer.

var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var roleExist = await RoleManager.RoleExistsAsync("Admin");
if (!roleExist)
{
    roleResult = await RoleManager.CreateAsync(new IdentityRole("Admin"));
}
await _userManager.AddToRoleAsync(user, "Admin");
Tiny Wang
  • 10,423
  • 1
  • 11
  • 29
1

Okay! I found a solution by the help of Tiny Wang answer, the issue's solution is To add the NormalizedName in the Roles table (UpperCase letters) instead of NULL! You can do that manually or using the above piece of code of Tiny Wang