【发布时间】:2021-06-20 05:07:18
【问题描述】:
我尝试在应用程序中注册新用户时遇到问题。一旦我修改了我的 ApplicationUser Model 和 ApplicationDbContext 修改以将用户 ID 存储为 INT
一旦我运行应用程序并导航到Register,我会收到错误消息
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole`1[System.String]]' while attempting to activate 'CarPlatzz.Areas.Identity.Pages.Account.RegisterModel'.
我在 ApplicationUser 中所做的更改是
public class ApplicationUser : IdentityUser<int>
{
[Required]
[Display(Name = "Ime")]
public string Name { get; set; }
[Required]
[Display(Name = "Adresa")]
public string StreetAddress { get; set; }
[Required]
[Display(Name = "Grad")]
public string City { get; set; }
[Required]
[Display(Name = "Postanski broj")]
public string PostalCode { get; set; }
public int? ClientId { get; set; }
[ForeignKey("ClientId")]
public Client Client { get; set; }
[NotMapped]
public string Role { get; set; }
[NotMapped]
public IEnumerable<SelectListItem> RoleList { get; set; }
[NotMapped]
public IEnumerable<SelectListItem> ClientList { get; set; }
}
和Register.cs
namespace CarPlatzz.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class RegisterModel : PageModel
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;
private readonly RoleManager<IdentityRole<string>> _roleManager;
private readonly IUnitOfWork _unitOfwork;
public RegisterModel(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender,
RoleManager<IdentityRole<string>> roleManager,
IUnitOfWork unitOfWork)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
_roleManager = roleManager;
_unitOfwork = unitOfWork;
}
[BindProperty]
public InputModel Input { get; set; }
public string ReturnUrl { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }
public class InputModel
{
[Required]
[Display(Name = "Ime i prezime")]
[StringLength(100, ErrorMessage = "Polje Ime je obavezno! Molimo vas unesite Vaše Ime i prezime")]
public string Name { get; set; }
[Required]
[Display(Name = "Adresa")]
public string StreetAddress { get; set; }
[Required]
[Display(Name = "Grad")]
public string City { get; set; }
[Required]
[Display(Name = "Postanski broj")]
public string PostalCode { get; set; }
[Required]
[Display(Name = "Broj telefona")]
[StringLength(100, ErrorMessage = "Broj telefona je obavezan! Molimo vas unesite Vaše broj telefona ! ")]
public string PhoneNumber { get; set; }
public int? ClientId { get; set; }
public string Role { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "Password {0} mora sadrzati {2} najmanje {1} karakter.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Potvrdi password")]
[Compare("Password", ErrorMessage = "Password i Potvrdi password nisu isti. Molimo vas unesite isti password")]
public string ConfirmPassword { get; set; }
public IEnumerable<SelectListItem> ClientList { get; set; }
public IEnumerable<SelectListItem> RoleList { get; set; }
}
public async Task OnGetAsync(string returnUrl = null)
{
ReturnUrl = returnUrl;
Input = new InputModel()
{
ClientList = _unitOfwork.Client.GetAll().Select(i => new SelectListItem
{
Text = i.Name,
Value = i.Id.ToString()
}),
RoleList = _roleManager.Roles.Select(x => x.Name).Select(i => new SelectListItem
{
Text = i,
Value = i
}),
};
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
ApplicationUser user = new()
{
UserName = Input.Email,
Email = Input.Email,
ClientId = Input.ClientId,
StreetAddress = Input.StreetAddress,
City = Input.City,
PostalCode = Input.PostalCode,
Name = Input.Name,
PhoneNumber = Input.PhoneNumber,
Role = Input.Role
};
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
if (!await _roleManager.RoleExistsAsync(SD.Role_Admin))
{
await _roleManager.CreateAsync(new IdentityRole(SD.Role_Admin));
}
if (!await _roleManager.RoleExistsAsync(SD.Role_Manager))
{
await _roleManager.CreateAsync(new IdentityRole(SD.Role_Manager));
}
// u slucaju da se izbrise admin potrebno je samo obrisati tabelu AspNetUsers i odkomentarisati
// ovu liniju
//await _userManager.AddToRoleAsync(user, SD.Role_Admin);
// takodjer potrebno je i ovo zakomentarisati
if (user.Role == null)
{
await _userManager.AddToRoleAsync(user, SD.Role_Manager);
}
else
{
await _userManager.AddToRoleAsync(user, user.Role);
}
//var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
//code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
//var callbackUrl = Url.Page(
// "/Account/ConfirmEmail",
// pageHandler: null,
// values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
// protocol: Request.Scheme);
//await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
// $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl });
}
else
{
if (user.Role == null)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
else
{
// admin registering new user
return RedirectToAction("Index", "User", new { Area = "Admin" });
}
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
}
}
我更改了我的 Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddIdentity<ApplicationUser, IdentityRole<int>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddSignInManager<SignInManager<ApplicationUser>>()
.AddDefaultTokenProviders();
services.AddSingleton<IEmailSender, EmailSender>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddControllersWithViews().AddRazorRuntimeCompilation();
services.AddRazorPages();
services.AddMvc(o =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
o.Filters.Add(new AuthorizeFilter(policy));
});
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
}
我尝试将IdentityUser 更改为从ApplicationUser 继承,但仍然存在同样的问题。
我尝试从IdentityUser 更改为IdentityUser<int> 之类的东西,但仍然存在同样的问题。
由于这是RoleManager 的问题,我也尝试更改RoleManager<IdentityRole<string>> roleManager, 但仍然存在同样的问题。我真的不明白我在哪里做错了,我做错了什么?
【问题讨论】:
标签: c# asp.net-core claims-based-identity