我的工作环境:
macOS14 AppleSilicon
我的开发环境:
我正在开发一个具有身份验证和授权的简单项目。最初,它使用 SQL Server 作为数据库,但我想将其迁移到 SQLite。我在YouTube上找到了迁移教程并按照它进行操作,但随后遇到了无法分配权限的问题。我使用脚手架来设置与身份相关的页面。程序的其他CRUD功能运行正常,但是注册新用户时VS提示错误:
InvalidOperationException:角色 CLIENT 不存在
148号线:
await _userManager.AddToRoleAsync(user, "client");
是的,它说这个角色名不存在......我检查了数据库,发现
AspNetRoles
表如下截图所示:
三个角色确实都在里面了。并且在
AspNetUsers
表中,我填写的注册用户的信息也正常记录了。
我觉得可能和迁移注册操作时的代码有关,所以我把代码贴在这里:
AppDbContext.cs
文件:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Sqlite;
using RazorPagesToys.Models;
namespace RazorPagesToys.Data
{
IdentityDbContext<ApplicationUser>
public class AppDbContext : IdentityDbContext<ApplicationUser>
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
var admin = new IdentityRole("admin");
admin.NormalizedName = "admin";
var client = new IdentityRole("client");
client.NormalizedName = "client";
var seller = new IdentityRole("seller");
seller.NormalizedName = "seller";
builder.Entity<IdentityRole>().HasData(admin, client, seller);
}
}
}
ApplicationUser.cs
文件:
using Microsoft.AspNetCore.Identity;
namespace RazorPagesToys.Models
{
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; } = "";
public string LastName { get; set; } = "";
public string Address { get; set; } = "";
public DateTime CreatedAt { get; set; }
}
}
Register.cshtml.cs
文件(在 /Areas/Identity/Pages/Account/
中):
/*Only Post Method*/
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new ApplicationUser()
{
FirstName = Input.FirstName,
LastName = Input.LastName,
UserName = Input.Email,
Email = Input.Email,
PhoneNumber = Input.PhoneNumber,
Address = Input.Address,
CreatedAt = DateTime.Now,
};
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
// set the user role
await _userManager.AddToRoleAsync(user, "client");
var userId = await _userManager.GetUserIdAsync(user);
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 = userId, 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 = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return Page();
}
问题:
我尝试在分配权限之前使用记录器检查是否获取了角色名称,答案是Null。为什么是空的?数据库里明明有啊……
我使用AI辅助来帮助我查看迁移后的上下文文件。 AI说好像没问题,我自己检查也没有发现什么问题。感觉很奇怪。
我不太确定哪个部分出了问题,所以我来这里寻求帮助。感谢每一位帮助我的专业人士!谢谢你!即使只是一个解决方案想法......谢谢。
无法在我这边重现问题。我在我这边检查了你的代码,在我这边一切正常。
我建议您在将用户添加到角色之前可以使用
RoleManager.RoleExistsAsync
方法检查角色是否存在。或者您可以使用 RoleMananger
将新角色添加到数据库中,然后检查数据库/AspNetRoles 表是否有任何差异?
另外,请检查你的连接字符串,数据库是否正确?也许是因为您连接到了不同的数据库。