ASP.NET Core RoleManager在Blazor Server中创建新角色失败
Blazor Server中RoleManager.CreateAsync提示角色名无效问题排查
我正在开发Blazor Server应用,实现角色创建功能时遇到问题:调用RoleManager.CreateAsync(newRole)时,即使传入硬编码的角色名(比如"Administrator"),仍会抛出角色名无效的错误,日志提示:
Microsoft.AspNetCore.Identity.RoleManager[0] Role (null) validation failed: InvalidRoleName. fail: TestWebsite.Pages.Admin.Users[0] Role name '' is invalid. fail: TestWebsite.Pages.Admin.Users[0] InvalidRoleName
已确认传入的ApplicationRole对象名称不为空,且ApplicationRole仅继承IdentityRole未做重写,猜测问题出在依赖注入或Identity服务实现上。
相关代码
Blazor页面注入与创建逻辑
@inject RoleManager<ApplicationRole> roleManager
@code { // 省略其他页面逻辑代码... // ===== NEW ROLE CREATION ===== private bool _creatingRole = false; private RoleModel roleModel = new(); private EditContext? editContext; protected override void OnInitialized() { editContext = new(roleModel); editContext.EnableDataAnnotationsValidation(); } private async Task HandleValidSubmit() { if (editContext != null && editContext.Validate()) { Logger.LogInformation(roleModel.Name); ArgumentNullException.ThrowIfNull(roleModel.Name); // 硬编码角色名仍报错 var result = await roleManager.CreateAsync(new ApplicationRole("Administrator")); if (result.Succeeded) { _creatingRole = false; _loadingRoles = true; LoadAllRoles(); } else { foreach (var error in result.Errors) { Logger.LogError(error.Description); Logger.LogError(error.Code); } } } } public class RoleModel { [Required(ErrorMessage = "Role name is required")] [StringLength(256, MinimumLength = 3, ErrorMessage = "Role name must be 3 to 256 characters long")] public string? Name { get; set; } } }
Program.cs配置
using TestWebsite.Data.Identity; using TestWebsite.Models; using Microsoft.AspNetCore.Identity; using System.Data; using System.Data.SqlClient; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); builder.Services.AddScoped<IDapperUserStore, DapperUserStore>(); builder.Services.AddScoped<IDapperRoleStore, DapperRoleStore>(); builder.Services .AddIdentity<ApplicationUser, ApplicationRole>() .AddUserStore<DapperUserStore>() .AddRoleStore<DapperRoleStore>() .AddDefaultTokenProviders(); builder.Services.AddTransient<IDbConnection>( sp => new SqlConnection(builder.Configuration.GetConnectionString("KristeraLocal")) ); var app = builder.Build(); // 省略中间件配置... app.Run();
问题根源与解决方法
问题出在你自定义的DapperRoleStore实现上。RoleManager.CreateAsync执行时,会先通过IRoleStore<TRole>的GetRoleNameAsync方法获取角色名称,再进行验证。如果你的DapperRoleStore中GetRoleNameAsync方法没有正确返回角色的Name属性,就会导致验证时认为角色名为空。
检查并修正DapperRoleStore的以下核心方法:
- GetRoleNameAsync:确保正确返回角色对象的
Name属性public Task<string> GetRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); return Task.FromResult(role.Name); } - SetRoleNameAsync:确保正确为角色对象赋值名称
public Task SetRoleNameAsync(ApplicationRole role, string roleName, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); role.Name = roleName; return Task.CompletedTask; } - 规范化名称处理:确保
GetNormalizedRoleNameAsync和SetNormalizedRoleNameAsync正确处理规范化名称(通常转大写),避免后续其他验证或存储问题public Task<string> GetNormalizedRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); return Task.FromResult(role.NormalizedName); } public Task SetNormalizedRoleNameAsync(ApplicationRole role, string normalizedName, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); role.NormalizedName = normalizedName; return Task.CompletedTask; }
同时确认DapperRoleStore的CreateAsync方法中,正确将角色的Name和NormalizedName写入数据库,规范化名称建议通过RoleManager的NormalizeKey方法生成(或手动转大写)。
内容的提问来源于stack exchange,提问作者Kristers
相关产品推荐
相关产品推荐

