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

如何在AspNetCore.Identity的IdentityErrorDescriber中添加新方法并解决调用报错

问题解决方法

一、解决编译错误(CS1061)

报错原因是UserManager.ErrorDescriber的类型是基类IdentityErrorDescriber,而你自定义的InvalidPhoneNumber方法仅存在于子类AuthErrorDescriber中,直接调用会触发编译失败。以下是两种可行的解决方式:

1. 显式转换为自定义错误描述器类型

因为你已经通过AddErrorDescriber<AuthErrorDescriber>()注册了自定义实现,ErrorDescriber的实际实例是AuthErrorDescriber,可以通过强制转换或as关键字获取子类实例:

if (string.IsNullOrEmpty(phoneNumber) || !PhoneNumberHelper.IsValid(phoneNumber))
{
    var authDescriber = userManager.ErrorDescriber as AuthErrorDescriber;
    if (authDescriber == null)
    {
        // 处理转换失败的边界情况
        var defaultError = new IdentityError 
        { 
            Code = "InvalidPhoneNumber", 
            Description = "Invalid phone number." 
        };
        return CreateValidationProblem(IdentityResult.Failed(defaultError));
    }
    return CreateValidationProblem(IdentityResult.Failed(authDescriber.InvalidPhoneNumber(phoneNumber)));
}

如果能确保注册的一定是AuthErrorDescriber,也可以直接强制转换:

return CreateValidationProblem(IdentityResult.Failed(((AuthErrorDescriber)userManager.ErrorDescriber).InvalidPhoneNumber(phoneNumber)));

2. 通过依赖注入直接获取自定义错误描述器

在控制器或服务的构造函数中直接注入AuthErrorDescriber,跳过从UserManager获取的步骤:

// 控制器构造函数
private readonly UserManager<User> _userManager;
private readonly AuthErrorDescriber _errorDescriber;

public AuthController(UserManager<User> userManager, AuthErrorDescriber errorDescriber)
{
    _userManager = userManager;
    _errorDescriber = errorDescriber;
}

// 调用处代码
if (string.IsNullOrEmpty(phoneNumber) || !PhoneNumberHelper.IsValid(phoneNumber))
{
    return CreateValidationProblem(IdentityResult.Failed(_errorDescriber.InvalidPhoneNumber(phoneNumber)));
}

二、其他添加新错误的方式

除了继承IdentityErrorDescriber,还有两种灵活的方式可以添加自定义错误:

1. 直接创建IdentityError实例

如果只是个别场景需要该错误,无需扩展错误描述器,直接实例化IdentityError即可:

if (string.IsNullOrEmpty(phoneNumber) || !PhoneNumberHelper.IsValid(phoneNumber))
{
    var error = new IdentityError
    {
        Code = "InvalidPhoneNumber",
        Description = $"PhoneNumber '{phoneNumber}' is invalid."
    };
    return CreateValidationProblem(IdentityResult.Failed(error));
}

2. 给IdentityErrorDescriber写扩展方法

通过扩展方法让所有IdentityErrorDescriber实例都能调用自定义错误方法,同时兼容自定义实现:

public static class IdentityErrorDescriberExtensions
{
    public static IdentityError InvalidPhoneNumber(this IdentityErrorDescriber describer, string? phoneNumber)
    {
        // 如果是自定义描述器实例,优先调用其方法
        if (describer is AuthErrorDescriber authDescriber)
        {
            return authDescriber.InvalidPhoneNumber(phoneNumber);
        }
        // 否则返回默认错误
        return new IdentityError
        {
            Code = nameof(InvalidPhoneNumber),
            Description = $"PhoneNumber '{phoneNumber}' is invalid."
        };
    }
}

之后就可以直接调用userManager.ErrorDescriber.InvalidPhoneNumber(phoneNumber),不会出现编译错误。

补充:解决资源文件无法使用的问题

如果想在自定义错误描述器中使用本地化资源,可以注入IStringLocalizer:

public class AuthErrorDescriber : IdentityErrorDescriber
{
    private readonly IStringLocalizer<AuthErrorDescriber> _localizer;

    public AuthErrorDescriber(IStringLocalizer<AuthErrorDescriber> localizer)
    {
        _localizer = localizer;
    }

    public virtual IdentityError InvalidPhoneNumber(string? phoneNumber)
    {
        return new IdentityError
        {
            Code = nameof(InvalidPhoneNumber),
            Description = _localizer["PhoneNumber '{0}' is invalid.", phoneNumber]
        };
    }
}

只需提前创建对应的资源文件(如AuthErrorDescriber.resx),即可实现错误信息的本地化。

内容的提问来源于stack exchange,提问作者bcExpt1123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:13:16