You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:04:59