【问题标题】:ASP.Net Core localizationASP.Net Core 本地化
【发布时间】:2017-01-06 15:41:18
【问题描述】:

ASP.Net 核心功能new support for localization.

在我的项目中,我只需要一种语言。对于大多数文本和注释,我可以用我的语言指定内容,但对于来自 ASP.Net Core 本身的文本,语言是英语。

例子:

  • 密码必须至少有一个大写字母 ('A'-'Z')。
  • 密码必须至少有一位数字 ('0'-'9')。
  • 用户名“x@x.com”已被占用。
  • E-post 字段不是有效的电子邮件地址。
  • 值 '' 无效。

我已尝试手动设置文化,但语言仍然是英语。

app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture("nb-NO"),
    SupportedCultures = new List<CultureInfo> { new CultureInfo("nb-NO") },
    SupportedUICultures = new List<CultureInfo> { new CultureInfo("nb-NO") }
});

如何更改 ASP.Net Core 的语言,或覆盖其默认文本?

【问题讨论】:

标签: asp.net-core asp.net-core-mvc asp.net-core-localization asp.net-core-identity


【解决方案1】:

列出的错误消息在 ASP.NET Core 标识中定义并由 IdentityErrorDescriber 提供。到目前为止我没有找到翻译的资源文件,我认为它们没有本地化。在我的系统(德语语言环境)上,尽管 CultureInfo 设置正确,但它们也没有被翻译。

您可以配置自定义 IdentityErrorDescriber 以返回您自己的消息及其翻译。它被描述为例如在 How to change default error messages of MVC Core ValidationSummary?

Startup.csConfigure 方法中,您可以连接从IdentityErrorDescriber 继承的错误描述器类

 services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddErrorDescriber<TranslatedIdentityErrorDescriber>();

对于其他默认模型错误消息(如无效号码),您可以在ModelBindingMessageProvider 中提供自己的访问器函数。此提供程序供 ASP.NET Core MVC 使用,也可以在 Startup.cs 中进行配置。

services.AddMvc(
            options => 
            options.ModelBindingMessageProvider.ValueIsInvalidAccessor = s => $"My not valid text for {s}");

【讨论】:

  • 谢谢。这解决了身份部分,但还有更多错误未翻译。例如,如果未填写数字字段,则会显示“值 '' 无效。”
  • @TeddHansen - 我做了一点研究,并将 ModelBindingMessageProvider 信息添加到答案中。
【解决方案2】:

让我对这个问题有一个全面的回答,并描述我在阅读.net核心源代码后是如何想出解决方案的。

在任何进一步的描述之前,首先使用 NuGet Microsoft.Extensions.Localization 安装这个包

你们可能还记得在 asp.net 完整框架中,文化之间的切换非常简单

System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

但在 .net 核心中,文化不再与当前线程相关联。 asp.net 核心引擎有一个管道,我们可以在这个管道中添加不同的中间件,所以 RequestLocalizationMiddleware 是用于处理本地化的中间件类,我们可能有多个提供程序,因此它将遍历所有文化提供程序,如 QueryStringRequestCultureProviderCookieRequestCultureProviderAcceptLanguageHeaderRequestCultureProvider,……

只要请求本地化中间件可以从第一个提供者那里获取当前语言环境,它就会忽略其他的并将请求传递给管道中的下一个中间件,因此列表中提供者的顺序非常重要。

我个人更喜欢将文化存储在浏览器cookie中,因此由于CookieRequestCultureProvider不是列表中的第一个文化提供者,我将其移至列表顶部,这部分的配置在Startup.cs中>配置服务如下

services.Configure<RequestLocalizationOptions>(options =>
             {
                 var supportedCultures = new[]
                 {
                    new CultureInfo("en-US"),
                    new CultureInfo("fa-IR"),
                    new CultureInfo("de-DE")
                };
                options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
                options.SupportedCultures = supportedCultures;
                options.SupportedUICultures = supportedCultures;

                var defaultCookieRequestProvider =
                    options.RequestCultureProviders.FirstOrDefault(rcp =>
                        rcp.GetType() == typeof(CookieRequestCultureProvider));
                if (defaultCookieRequestProvider != null)
                    options.RequestCultureProviders.Remove(defaultCookieRequestProvider);

                options.RequestCultureProviders.Insert(0,
                    new CookieRequestCultureProvider()
                    {
                        CookieName = ".AspNetCore.Culture",
                        Options = options
                    });
            });

让我描述一下上面的代码,我们的应用默认文化是en-US,我们只支持英语、波斯语、德国,所以如果浏览器有不同的语言环境或者你设置语言不是这 3 种语言,那么应用程序必须切换到默认文化。在上面的代码中,我只是从列表中删除 CookieCultureProvider 并将其添加为列表中的第一个提供者(* 我已经描述了它必须是第一个的原因*)。默认的 CookieName 对我有用,您可以根据需要更改它。

不要忘记在 Startup.cs 中的 Configure(IApplicationBuilder app, IHostingEnvironment env) 下方添加以下代码

   var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
   app.UseRequestLocalization(options.Value);

到目前为止一切顺利。要拥有资源文件,您必须指定资源的路径,我在 Web 项目根路径中分别指定了 Controller、Views、ViewModels 和 SharedResources 的资源,层次结构如下所示

|-Resoures
|---Controllers
|---Views
|---Models
|---SharedResource.resx
|---SharedResource.fa-IR.resx
|---SharedResource.de-DE.resx

请记住,对于 SharedResource,在 Web 项目根路径中创建一个同名的空类,我的意思是一个 SharedResource.cs,其中包含一个同名的类。

在 Startup.cs 中添加以下代码 sn-p 用于指定资源路径和其余部分。

services.AddLocalization(options => options.ResourcesPath = "Resources");

services.AddMvc()
    AddViewLocalization(
                LanguageViewLocationExpanderFormat.Suffix,
                opts => { opts.ResourcesPath = "Resources/Views"; }) // this line is not required, it is just for more clarification
            .AddDataAnnotationsLocalization();

使用此配置,例如当您在控制器中注入 IStringLocalizer 时,您必须在 Resources > Controllers 文件夹中拥有相应的资源文件(即 HomeController.resx、HomeController.fa-IR.resx、HomeController .de-DE.resx)我们也可以在文件名中用 .(比如点)分隔路径我的意思是 Resources/Controllers/HomeController.resx 可以是 Resources/Controllers.HomeController.resx 中的一个文件,您必须将 IViewLocalizer 注入视图以在视图中进行相应的本地化,您必须在 Resources/Views 文件夹中拥有 Views 的资源文件,对于 ViewModels,因为我们将文件夹命名为 Models,请将所有 ViewModels 放在预先创建的文件夹中名称为 Models 的 Web 项目根路径,如果文件夹有其他名称或者您更喜欢其他名称,请不要忘记重命名 Resource 文件夹下的 Models 文件夹。那么你只需要对模型进行注解,例如,用 [DisplayName("User Emailaddress")] 对 ViewModel 属性进行注解,然后在模型内部的相应资源文件中创建资源(文件名必须与模型类名匹配)使用相同的密钥(“用户电子邮件地址”)。

让我们从已经开始的地方结束,我的意思是 CookieRequestCultureProvider。正如我之前所说,我更喜欢将其存储在 cookie 中,但这有点棘手,因为 cookie parsing 与您的预期有些不同,只需在您想要更改文化的地方添加以下代码,只需将 preferedCulture 替换为你的文化偏好

var preferedCulture = "fa-IR"; // get the culture from user, i just mock it here in a variable
if (HttpContext.Response.Cookies.ContainsKey(".AspNetCore.Culture"))
{
    HttpContext.Response.Cookies.Delete(".AspNetCore.Culture");
}

HttpContext.Response.Cookies.Append(".AspNetCore.Culture",
    $"c={preferedCulture}|uic={preferedCulture}", new CookieOptions {Expires = DateTime.UtcNow.AddYears(1)});

我们开始了,我们的 sp.net 核心网络应用程序现已本地化 :)

【讨论】:

  • 只是给你一个UP。我发疯了两个小时,问自己为什么 asp net core 本地化 cookie 不工作,尽管它在浏览器中。您的帖子完美地解释了这一点。
  • 当心两个“陷阱”: 1) IStringLocalizer 不喜欢一些短文化名称。它只是不适用于lv,尽管当前线程文化和资源名称是lv。当我将它们全部重命名为 lv-LV 时,它开始起作用了。 2) 如果您将 SharedResource 文件放在 Resources 文件夹中,并将其命名空间设置为以 Resources 结尾,则不要设置 o.ResourcesPath = "Resources",因为那样它将开始在不存在的 Resources.Resources 文件夹中查找。所以,它要么是命名空间,要么是 ResourcesPath,但不是两者兼而有之。
【解决方案3】:

基于 rboe 和 Tedd Hansen 的出色回答,我写了一个基于 IdentityErrorDescriberIStringLocalizer 供我自己使用,我想在这里分享一下,以防有人需要多语言支持:)

基本思想是以通常的方式为您的默认语言和任何其他语言创建资源文件。 (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization)

位于(如果你保留我的班级名称):

/Resources/你的命名空间.LocalizedIdentityErrorDescriber.resx
/Resources/yournamespace.LocalizedIdentityErrorDescriber.fr.resx
等等……

在这些中,您将使用错误代码(例如:DefaultError、ConcurrencyError)作为键。

然后在下面添加类

LocalizedIdentityErrorDescriber.cs

public class LocalizedIdentityErrorDescriber : IdentityErrorDescriber
{
    /// <summary> 
    /// The <see cref="IStringLocalizer{LocalizedIdentityErrorDescriber}"/>
    /// used to localize the strings
    /// </summary>
    private readonly IStringLocalizer<LocalizedIdentityErrorDescriber> localizer;

    /// <summary>
    /// Initializes a new instance of the <see cref="LocalizedIdentityErrorDescriber"/> class.
    /// </summary>
    /// <param name="localizer">
    /// The <see cref="IStringLocalizer{LocalizedIdentityErrorDescriber}"/>
    /// that we will use to localize the strings
    /// </param>
    public LocalizedIdentityErrorDescriber(IStringLocalizer<LocalizedIdentityErrorDescriber> localizer)
    {
        this.localizer = localizer;
    }

    /// <summary>
    /// Returns the default <see cref="IdentityError" />.
    /// </summary>
    /// <returns>The default <see cref="IdentityError" /></returns>
    public override IdentityError DefaultError()
    {
        return this.GetErrorByCode("DefaultError");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a concurrency failure.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating a concurrency failure.</returns>
    public override IdentityError ConcurrencyFailure()
    {
        return this.GetErrorByCode("ConcurrencyFailure");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a password mismatch.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating a password mismatch.</returns>
    public override IdentityError PasswordMismatch()
    {
        return this.GetErrorByCode("PasswordMismatch");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating an invalid token.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating an invalid token.</returns>
    public override IdentityError InvalidToken()
    {
        return this.GetErrorByCode("InvalidToken");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating an external login is already associated with an account.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating an external login is already associated with an account.</returns>
    public override IdentityError LoginAlreadyAssociated()
    {
        return this.GetErrorByCode("LoginAlreadyAssociated");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating the specified user <paramref name="userName" /> is invalid.
    /// </summary>
    /// <param name="userName">The user name that is invalid.</param>
    /// <returns>An <see cref="IdentityError" /> indicating the specified user <paramref name="userName" /> is invalid.</returns>
    public override IdentityError InvalidUserName(string userName)
    {
        return this.FormatErrorByCode("InvalidUserName", (object)userName);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="email" /> is invalid.
    /// </summary>
    /// <param name="email">The email that is invalid.</param>
    /// <returns>An <see cref="IdentityError" /> indicating the specified <paramref name="email" /> is invalid.</returns>
    public override IdentityError InvalidEmail(string email)
    {
        return this.FormatErrorByCode("InvalidEmail", (object)email);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="userName" /> already exists.
    /// </summary>
    /// <param name="userName">The user name that already exists.</param>
    /// <returns>An <see cref="IdentityError" /> indicating the specified <paramref name="userName" /> already exists.</returns>
    public override IdentityError DuplicateUserName(string userName)
    {
        return this.FormatErrorByCode("DuplicateUserName", (object)userName);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="email" /> is already associated with an account.
    /// </summary>
    /// <param name="email">The email that is already associated with an account.</param>
    /// <returns>An <see cref="IdentityError" /> indicating the specified <paramref name="email" /> is already associated with an account.</returns>
    public override IdentityError DuplicateEmail(string email)
    {
        return this.FormatErrorByCode("DuplicateEmail", (object)email);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="role" /> name is invalid.
    /// </summary>
    /// <param name="role">The invalid role.</param>
    /// <returns>An <see cref="IdentityError" /> indicating the specific role <paramref name="role" /> name is invalid.</returns>
    public override IdentityError InvalidRoleName(string role)
    {
        return this.FormatErrorByCode("InvalidRoleName", (object)role);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="role" /> name already exists.
    /// </summary>
    /// <param name="role">The duplicate role.</param>
    /// <returns>An <see cref="IdentityError" /> indicating the specific role <paramref name="role" /> name already exists.</returns>
    public override IdentityError DuplicateRoleName(string role)
    {
        return this.FormatErrorByCode("DuplicateRoleName", (object)role);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a user already has a password.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating a user already has a password.</returns>
    public override IdentityError UserAlreadyHasPassword()
    {
        return this.GetErrorByCode("UserAlreadyHasPassword");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating user lockout is not enabled.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating user lockout is not enabled..</returns>
    public override IdentityError UserLockoutNotEnabled()
    {
        return this.GetErrorByCode("UserLockoutNotEnabled");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a user is already in the specified <paramref name="role" />.
    /// </summary>
    /// <param name="role">The duplicate role.</param>
    /// <returns>An <see cref="IdentityError" /> indicating a user is already in the specified <paramref name="role" />.</returns>
    public override IdentityError UserAlreadyInRole(string role)
    {
        return this.FormatErrorByCode("UserAlreadyInRole", (object)role);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a user is not in the specified <paramref name="role" />.
    /// </summary>
    /// <param name="role">The duplicate role.</param>
    /// <returns>An <see cref="IdentityError" /> indicating a user is not in the specified <paramref name="role" />.</returns>
    public override IdentityError UserNotInRole(string role)
    {
        return this.FormatErrorByCode("UserNotInRole", (object)role);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a password of the specified <paramref name="length" /> does not meet the minimum length requirements.
    /// </summary>
    /// <param name="length">The length that is not long enough.</param>
    /// <returns>An <see cref="IdentityError" /> indicating a password of the specified <paramref name="length" /> does not meet the minimum length requirements.</returns>
    public override IdentityError PasswordTooShort(int length)
    {
        return this.FormatErrorByCode("PasswordTooShort", (object)length);
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a password entered does not contain a non-alphanumeric character, which is required by the password policy.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating a password entered does not contain a non-alphanumeric character.</returns>
    public override IdentityError PasswordRequiresNonAlphanumeric()
    {
        return this.GetErrorByCode("PasswordRequiresNonAlphanumeric");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a password entered does not contain a numeric character, which is required by the password policy.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating a password entered does not contain a numeric character.</returns>
    public override IdentityError PasswordRequiresDigit()
    {
        return this.GetErrorByCode("PasswordRequiresDigit");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a password entered does not contain a lower case letter, which is required by the password policy.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating a password entered does not contain a lower case letter.</returns>
    public override IdentityError PasswordRequiresLower()
    {
        return this.GetErrorByCode("PasswordRequiresLower");
    }

    /// <summary>
    /// Returns an <see cref="IdentityError" /> indicating a password entered does not contain an upper case letter, which is required by the password policy.
    /// </summary>
    /// <returns>An <see cref="IdentityError" /> indicating a password entered does not contain an upper case letter.</returns>
    public override IdentityError PasswordRequiresUpper()
    {
        return this.GetErrorByCode("PasswordRequiresUpper");
    }

    /// <summary>Returns a localized <see cref="IdentityError"/> for the provided code.</summary>
    /// <param name="code">The error's code.</param>
    /// <returns>A localized <see cref="IdentityError"/>.</returns>
    private IdentityError GetErrorByCode(string code)
    {
        return new IdentityError()
        {
            Code = code,
            Description = this.localizer.GetString(code)
        };
    }

    /// <summary>Formats a localized <see cref="IdentityError"/> for the provided code.</summary>
    /// <param name="code">The error's code.</param>
    /// <param name="parameters">The parameters to format the string with.</param>
    /// <returns>A localized <see cref="IdentityError"/>.</returns>
    private IdentityError FormatErrorByCode(string code, params object[] parameters)
    {
        return new IdentityError
        {
            Code = code,
            Description = string.Format(this.localizer.GetString(code, parameters))
        };
    }
}

并初始化一切:

Startup.cs

    [...]

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddErrorDescriber<LocalizedIdentityErrorDescriber>();

        services.AddLocalization(options => options.ResourcesPath = "Resources");

        // Your service configuration code

        services.AddMvc()
            .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
            .AddDataAnnotationsLocalization();

        // Your service configuration code cont.
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // your configuration code

        app.UseRequestLocalization(
            new RequestLocalizationOptions()
                {
                    DefaultRequestCulture = new RequestCulture("fr"),
                    SupportedCultures = SupportedCultures,
                    SupportedUICultures = SupportedCultures
                });

        app.UseStaticFiles();

        app.UseIdentity();

        // your configuration code
    }

    [...]

【讨论】:

    【解决方案4】:

    还有俄语 IdentityErrorDescriber,以防有人需要。

    public class RussianIdentityErrorDescriber : IdentityErrorDescriber
    {
    
        public override IdentityError ConcurrencyFailure()
        {
            return new IdentityError
            {
                Code = "ConcurrencyFailure",
                Description = "Сбой в параллельных запросах. Возможно объект был изменен."
            };
        }
        public override IdentityError DefaultError()
        {
        return new IdentityError
            {
                Code = "DefaultError",
                Description = "Произошла неизвестная ошибка при авторизации."
            };
        }
        public override IdentityError DuplicateEmail(string email)
        {
            return new IdentityError
            {
                Code = "DuplicateEmail",
                Description = $"E-mail '{email}' уже используется."
            };
        }
        public override IdentityError DuplicateRoleName(string role)
        {
            return new IdentityError
            {
                Code = "DuplicateRoleName",
                Description = $"Роль с именем '{role}' уже существует."
            };
        }
        public override IdentityError DuplicateUserName(string userName)
        {
            return new IdentityError
            {
                Code = "DuplicateUserName",
                Description = $"Пользователь '{userName}' уже зарегистрирован."
            };
        }
        public override IdentityError InvalidEmail(string email)
        {
            return new IdentityError
            {
                Code = "InvalidEmail",
                Description = $"E-mail '{email}' содержит неверный формат."
            };
        }
        public override IdentityError InvalidRoleName(string role)
        {
            return new IdentityError
            {
                Code = "InvalidRoleName",
                Description = $"Имя роли '{role}' задано не верно (содержит не допустимые символы либо длину)."
            };
        }
        public override IdentityError InvalidToken()
        {
            return new IdentityError
            {
                Code = "InvalidToken",
                Description = "Неправильно указан код подтверждения (token)."
            };
        }
        public override IdentityError InvalidUserName(string userName)
        {
            return new IdentityError
            {
                Code = "InvalidUserName",
                Description = $"Имя пользователя '{userName}' указано не верно (содержит не допустимые символы либо длину)."
            };
        }
        public override IdentityError LoginAlreadyAssociated()
        {
            return new IdentityError
            {
                Code = "LoginAlreadyAssociated",
                Description = "Данный пользователь уже привязан к аккаунту."
            };
        }
        public override IdentityError PasswordMismatch()
        {
            return new IdentityError
            {
                Code = "PasswordMismatch",
                Description = "Пароли не совпадают."
            };
        }
        public override IdentityError PasswordRequiresDigit()
        {
            return new IdentityError
            {
                Code = "PasswordRequiresDigit",
                Description = "Пароль должен содержать минимум одну цифру."
            };
        }
        public override IdentityError PasswordRequiresLower()
        {
            return new IdentityError
            {
                Code = "PasswordRequiresLower",
                Description = "Пароль должен содержать минимум одну строчную букву."
            };
        }
        public override IdentityError PasswordRequiresNonAlphanumeric()
        {
            return new IdentityError
            {
                Code = "PasswordRequiresNonAlphanumeric",
                Description = "Пароль должен содержать минимум один специальный символ (не буквенно-цифровой)."
            };
        }
        public override IdentityError PasswordRequiresUniqueChars(int uniqueChars)
        {
            return new IdentityError
            {
                Code = "PasswordRequiresUniqueChars",
                Description = $"Пароль должен содержать минимум '{uniqueChars}' не повторяющихся символов."
            };
        }
        public override IdentityError PasswordRequiresUpper()
        {
            return new IdentityError
            {
                Code = "PasswordRequiresUpper",
                Description = "Пароль должен содержать минимум одну заглавную букву."
            };
        }
        public override IdentityError PasswordTooShort(int length)
        {
            return new IdentityError
            {
                Code = "PasswordTooShort",
                Description = $"Пароль слишком короткий. Минимальное количество символов: '{length}'."
            };
        }
        public override IdentityError RecoveryCodeRedemptionFailed()
        {
            return new IdentityError
            {
                Code = "RecoveryCodeRedemptionFailed",
                Description = "Не удалось использовать код восстановления."
            };
        }
        public override IdentityError UserAlreadyHasPassword()
        {
            return new IdentityError
            {
                Code = "UserAlreadyHasPassword",
                Description = "Пароль для пользователя уже задан."
            };
        }
        public override IdentityError UserAlreadyInRole(string role)
        {
            return new IdentityError
            {
                Code = "UserAlreadyInRole",
                Description = $"Роль '{role}' уже привязана к пользователю."
            };
        }
        public override IdentityError UserLockoutNotEnabled()
        {
            return new IdentityError
            {
                Code = "UserLockoutNotEnabled",
                Description = "Блокировка пользователя отключена."
            };
        }
        public override IdentityError UserNotInRole(string role)
        {
            return new IdentityError
            {
                Code = "UserNotInRole",
                Description = $"Пользователь должен иметь роль: '{role}'"
            };
        }
    }
    
    In `Startup.cs` set `RussianIdentityErrorDescriber `
    
    public void ConfigureServices(IServiceCollection services)
    {
    // ...   
        services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddErrorDescriber<RussianIdentityErrorDescriber>();
        // ...   
    }
    

    【讨论】:

    • 请编辑您的答案以消除语法错误。第一个错误出现在方法InvalidEmail:“содержить”->“содержит”中。方法InvalidToken中的下一个:"Не правильно" -> "Неправильно"
    • 已修复。感谢您的评论。我显然急于出版! (((
    【解决方案5】:

    如果您正在寻找波兰语,这里是:

    公共类 PolishLocalizedIdentityErrorDescriber : IdentityErrorDescriber { 公共覆盖 IdentityError DefaultError() { 返回新的身份错误 { 代码 = nameof(DefaultError), Description = "Wystąpił nieznany błąd." }; } 公共覆盖 IdentityError ConcurrencyFailure() { 返回新的身份错误 { 代码 = nameof(ConcurrencyFailure), Description = "Błąd współbieżności, obiekt został już zmodyfikowany." }; } 公共覆盖 IdentityError PasswordMismatch() { 返回新的身份错误 { 代码 = nameof(密码不匹配), Description = "Niepoprawne hasło." }; } 公共覆盖 IdentityError InvalidToken() { 返回新的身份错误 { 代码 = nameof(InvalidToken), Description = "Nieprawidłowy 令牌。" }; } 公共覆盖 IdentityError RecoveryCodeRedemptionFailed() { 返回新的身份错误 { 代码 = nameof(RecoveryCodeRedemptionFailed), 描述 = "Pobranie kodu odzyskiwania nie powiodło się." }; } 公共覆盖 IdentityError LoginAlreadyAssociated() { 返回新的身份错误 { 代码 = nameof(LoginAlreadyAssociated), Description = "Użytkownik o tym loginie już istnieje." }; } 公共覆盖 IdentityError InvalidUserName(string userName) { 返回新的身份错误 { 代码 = nameof(InvalidUserName), 说明 = $“Nazwa użytkownika '{userName}' jest nieprawidłowa, może zawierać tylko litery lub cyfry。” }; } 公共覆盖 IdentityError InvalidEmail(字符串电子邮件) { 返回新的身份错误 { 代码 = nameof(InvalidEmail), Description = $"地址电子邮件 '{email}' 开玩笑 nieprawidłowy。" }; } 公共覆盖 IdentityError DuplicateUserName(string userName) { 返回新的身份错误 { 代码 = nameof(DuplicateUserName), 描述 = $"Nazwa '{userName}' jest już zajęta." }; } 公共覆盖 IdentityError DuplicateEmail(字符串电子邮件) { 返回新的身份错误 { 代码 = nameof(DuplicateEmail), 描述 = $"地址电子邮件 '{email}' jest już zajęty." }; } 公共覆盖 IdentityError InvalidRoleName(字符串角色) { 返回新的身份错误 { 代码 = nameof(InvalidRoleName), 描述 = $"Nazwa roli '{role}' już niepoprawna." }; } 公共覆盖 IdentityError DuplicateRoleName(字符串角色) { 返回新的身份错误 { 代码 = nameof(DuplicateRoleName), 描述 = $"Rola '{role}' już istnieje." }; } 公共覆盖 IdentityError UserAlreadyHasPassword() { 返回新的身份错误 { 代码 = nameof(UserAlreadyHasPassword), Description = "Użytkownik ma już ustawione hasło。" }; } 公共覆盖 IdentityError UserLockoutNotEnabled() { 返回新的身份错误 { 代码 = nameof(UserLockoutNotEnabled), Description = "Blokada konta nie jest włączona dla tego użytkownika." }; } 公共覆盖 IdentityError UserAlreadyInRole(字符串角色) { 返回新的身份错误 { 代码 = nameof(UserAlreadyInRole), 描述 = $"Użytkownik korzysta już z roli '{role}'。" }; } 公共覆盖 IdentityError UserNotInRole(字符串角色) { 返回新的身份错误 { 代码 = nameof(UserNotInRole), 描述 = $"Użytkownika nie ma w roli '{role}'。" }; } 公共覆盖 IdentityError PasswordTooShort(int length) { 返回新的身份错误 { 代码 = nameof(PasswordTooShort), 描述 = $"Hasło musi składać się z co najmniej {length} znaków." }; } 公共覆盖 IdentityError PasswordRequiresUniqueChars(int uniqueChars) { 返回新的身份错误 { 代码 = nameof(PasswordRequiresUniqueChars), 描述 = $"Hasło musi składać się z co najmniej {uniqueChars} unikalnych znaków。" }; } 公共覆盖 IdentityError PasswordRequiresNonAlphanumeric() { 返回新的身份错误 { 代码 = nameof(PasswordRequiresNonAlphanumeric), 描述 = “Hasło musi zawierać co najmniej jeden znak niebędący literą lub cyfrą。” }; } 公共覆盖 IdentityError PasswordRequiresDigit() { 返回新的身份错误 { 代码 = nameof(PasswordRequiresDigit), 描述 = “Hasło musi zawierać co najmniej jedną cyfrę (0-9)。” }; } 公共覆盖 IdentityError PasswordRequiresLower() { 返回新的身份错误 { 代码 = nameof(PasswordRequiresLower), 描述 = “Hasło musi zawierać co najmniej jedną małą literę (a-z)。” }; } 公共覆盖 IdentityError PasswordRequiresUpper() { 返回新的身份错误 { 代码 = nameof(PasswordRequiresUpper), 描述 = “Hasło musi zawierać co najmniej jedną wielką literę (A-Z)。” }; } }

    【讨论】:

      【解决方案6】:

      对于那些想知道是否可以针对当前选择的文化本地化消息的人,是的,这是可能的。在 asp.net core 2.2 中,您可以创建一个类 LocalizedIdentityErrorDescriber 其中 IdentityResources 是您的虚拟类的名称(此处描述:@987654321 @):

      public class LocalizedIdentityErrorDescriber : IdentityErrorDescriber
      {
          /// <summary> 
          /// The <see cref="IStringLocalizer{LocalizedIdentityErrorDescriber}"/>
          /// used to localize the strings
          /// </summary>
          private readonly IStringLocalizer<IdentityResources> localizer;
      
          /// <summary>
          /// Initializes a new instance of the <see cref="LocalizedIdentityErrorDescriber"/> class.
          /// </summary>
          /// <param name="localizer">
          /// The <see cref="IStringLocalizer{LocalizedIdentityErrorDescriber}"/>
          /// that we will use to localize the strings
          /// </param>
          public LocalizedIdentityErrorDescriber(IStringLocalizer<IdentityResources> localizer)
          {
              this.localizer = localizer;
          }
      
          /// <summary>
          /// Returns the default <see cref="IdentityError" />.
          /// </summary>
          /// <returns>The default <see cref="IdentityError" /></returns>
          public override IdentityError DefaultError()
          {
              return this.GetErrorByCode(nameof(DefaultError));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a concurrency failure.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating a concurrency failure.</returns>
          public override IdentityError ConcurrencyFailure()
          {
              return this.GetErrorByCode(nameof(ConcurrencyFailure));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a password mismatch.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating a password mismatch.</returns>
          public override IdentityError PasswordMismatch()
          {
              return this.GetErrorByCode(nameof(PasswordMismatch));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating an invalid token.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating an invalid token.</returns>
          public override IdentityError InvalidToken()
          {
              return this.GetErrorByCode(nameof(InvalidToken));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating an external login is already associated with an account.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating an external login is already associated with an account.</returns>
          public override IdentityError LoginAlreadyAssociated()
          {
              return this.GetErrorByCode(nameof(LoginAlreadyAssociated));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating the specified user <paramref name="userName" /> is invalid.
          /// </summary>
          /// <param name="userName">The user name that is invalid.</param>
          /// <returns>An <see cref="IdentityError" /> indicating the specified user <paramref name="userName" /> is invalid.</returns>
          public override IdentityError InvalidUserName(string userName)
          {
              return this.FormatErrorByCode(nameof(InvalidUserName), (object)userName);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="email" /> is invalid.
          /// </summary>
          /// <param name="email">The email that is invalid.</param>
          /// <returns>An <see cref="IdentityError" /> indicating the specified <paramref name="email" /> is invalid.</returns>
          public override IdentityError InvalidEmail(string email)
          {
              return this.FormatErrorByCode(nameof(InvalidEmail), (object)email);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="userName" /> already exists.
          /// </summary>
          /// <param name="userName">The user name that already exists.</param>
          /// <returns>An <see cref="IdentityError" /> indicating the specified <paramref name="userName" /> already exists.</returns>
          public override IdentityError DuplicateUserName(string userName)
          {
              return this.FormatErrorByCode(nameof(DuplicateUserName), (object)userName);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="email" /> is already associated with an account.
          /// </summary>
          /// <param name="email">The email that is already associated with an account.</param>
          /// <returns>An <see cref="IdentityError" /> indicating the specified <paramref name="email" /> is already associated with an account.</returns>
          public override IdentityError DuplicateEmail(string email)
          {
              return this.FormatErrorByCode(nameof(DuplicateEmail), (object)email);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="role" /> name is invalid.
          /// </summary>
          /// <param name="role">The invalid role.</param>
          /// <returns>An <see cref="IdentityError" /> indicating the specific role <paramref name="role" /> name is invalid.</returns>
          public override IdentityError InvalidRoleName(string role)
          {
              return this.FormatErrorByCode(nameof(InvalidRoleName), (object)role);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating the specified <paramref name="role" /> name already exists.
          /// </summary>
          /// <param name="role">The duplicate role.</param>
          /// <returns>An <see cref="IdentityError" /> indicating the specific role <paramref name="role" /> name already exists.</returns>
          public override IdentityError DuplicateRoleName(string role)
          {
              return this.FormatErrorByCode(nameof(DuplicateRoleName), (object)role);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a user already has a password.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating a user already has a password.</returns>
          public override IdentityError UserAlreadyHasPassword()
          {
              return this.GetErrorByCode(nameof(UserAlreadyHasPassword));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating user lockout is not enabled.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating user lockout is not enabled..</returns>
          public override IdentityError UserLockoutNotEnabled()
          {
              return this.GetErrorByCode(nameof(UserLockoutNotEnabled));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a user is already in the specified <paramref name="role" />.
          /// </summary>
          /// <param name="role">The duplicate role.</param>
          /// <returns>An <see cref="IdentityError" /> indicating a user is already in the specified <paramref name="role" />.</returns>
          public override IdentityError UserAlreadyInRole(string role)
          {
              return this.FormatErrorByCode(nameof(UserAlreadyInRole), (object)role);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a user is not in the specified <paramref name="role" />.
          /// </summary>
          /// <param name="role">The duplicate role.</param>
          /// <returns>An <see cref="IdentityError" /> indicating a user is not in the specified <paramref name="role" />.</returns>
          public override IdentityError UserNotInRole(string role)
          {
              return this.FormatErrorByCode(nameof(UserNotInRole), (object)role);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a password of the specified <paramref name="length" /> does not meet the minimum length requirements.
          /// </summary>
          /// <param name="length">The length that is not long enough.</param>
          /// <returns>An <see cref="IdentityError" /> indicating a password of the specified <paramref name="length" /> does not meet the minimum length requirements.</returns>
          public override IdentityError PasswordTooShort(int length)
          {
              return this.FormatErrorByCode(nameof(PasswordTooShort), (object)length);
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a password entered does not contain a non-alphanumeric character, which is required by the password policy.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating a password entered does not contain a non-alphanumeric character.</returns>
          public override IdentityError PasswordRequiresNonAlphanumeric()
          {
              return this.GetErrorByCode(nameof(PasswordRequiresNonAlphanumeric));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a password entered does not contain a numeric character, which is required by the password policy.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating a password entered does not contain a numeric character.</returns>
          public override IdentityError PasswordRequiresDigit()
          {
              return this.GetErrorByCode(nameof(PasswordRequiresDigit));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a password entered does not contain a lower case letter, which is required by the password policy.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating a password entered does not contain a lower case letter.</returns>
          public override IdentityError PasswordRequiresLower()
          {
              return this.GetErrorByCode(nameof(PasswordRequiresLower));
          }
      
          /// <summary>
          /// Returns an <see cref="IdentityError" /> indicating a password entered does not contain an upper case letter, which is required by the password policy.
          /// </summary>
          /// <returns>An <see cref="IdentityError" /> indicating a password entered does not contain an upper case letter.</returns>
          public override IdentityError PasswordRequiresUpper()
          {
              return this.GetErrorByCode(nameof(PasswordRequiresUpper));
          }
      
          public override IdentityError PasswordRequiresUniqueChars(int uniqueChars)
          {
              return this.FormatErrorByCode(nameof(PasswordRequiresUniqueChars), (object)uniqueChars);
          }
      
          public override IdentityError RecoveryCodeRedemptionFailed()
          {
              return this.GetErrorByCode(nameof(RecoveryCodeRedemptionFailed));
          }
      
          /// <summary>Returns a localized <see cref="IdentityError"/> for the provided code.</summary>
          /// <param name="code">The error's code.</param>
          /// <returns>A localized <see cref="IdentityError"/>.</returns>
          private IdentityError GetErrorByCode(string code)
          {
              return new IdentityError()
              {
                  Code = code,
                  Description = this.localizer.GetString(code)
              };
          }
      
          /// <summary>Formats a localized <see cref="IdentityError"/> for the provided code.</summary>
          /// <param name="code">The error's code.</param>
          /// <param name="parameters">The parameters to format the string with.</param>
          /// <returns>A localized <see cref="IdentityError"/>.</returns>
          private IdentityError FormatErrorByCode(string code, params object[] parameters)
          {
              return new IdentityError
              {
                  Code = code,
                  Description = string.Format(this.localizer.GetString(code, parameters))
              };
          }
      }
      

      然后为您的语言创建资源文件,如下所示:Resources\(上述虚拟类的名称)(.culture).resx。对于您的默认语言文化,应留空。并且不要忘记“。”如果不是默认值,则在文化名称之前。您的 IdentityResources 文件应如下所示:

      在 Startup.cs 添加以下行:

       public void ConfigureServices(IServiceCollection services)
       {
            services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });
            services.AddIdentity<IdentityUser, IdentityRole>()
                 .AddEntityFrameworkStores<nameofyourdbcontext>()
                 .AddDefaultTokenProviders()
                 .AddErrorDescriber<LocalizedIdentityErrorDescriber>(); // this line is important
             services.Configure<RequestLocalizationOptions>(options =>
             {
                  var supportedCultures = new[]
                  {
                      new CultureInfo("en"), // english
                      new CultureInfo("tr"), // turkish
                      new CultureInfo("ru")  // russian
                  };
      
                  options.DefaultRequestCulture = new RequestCulture(culture: "en", uiCulture: "en");
                  options.SupportedCultures = supportedCultures;
                  options.SupportedUICultures = supportedCultures;
                  options.RequestCultureProviders.Insert(0, new CookieRequestCultureProvider()); // type of CultureProvider you want.
              });
       }
       public void Configure(IApplicationBuilder app, IHostingEnvironment env)
       {
              var localizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
              // IT IS IMPORTANT TO CALL UseRequestLocalization BEFORE UseMvc
              app.UseRequestLocalization(localizationOptions.Value);
              app.UseMvc(routes =>
              {
                  routes.MapRoute(
                      name: "default",
                      template: "{controller=Home}/{action=Index}/{id?}"
                  );
              });
       }
      

      现在您几乎完成了,但您需要设置 Culture cookie,这里有一个代码示例:Globalization and localization。 希望它可以帮助某人。

      【讨论】:

        【解决方案7】:

        挪威 IdentityErrorDescriber,以防有人需要。

        public class NorwegianIdentityErrorDescriber : IdentityErrorDescriber
        {
        
            public override IdentityError DefaultError()
            {
                return new IdentityError()
                {
                    Code = "DefaultError",
                    Description = "En ukjent feil har oppstått."
                };
            }
        
            public override IdentityError ConcurrencyFailure()
            {
                return new IdentityError()
                {
                    Code = "ConcurrencyFailure",
                    Description = "Optimistisk samtidighet feilet, objektet har blitt endret."
                };
            }
        
            public override IdentityError PasswordMismatch()
            {
                return new IdentityError()
                {
                    Code = "PasswordMismatch",
                    Description = "Feil passord."
                };
            }
        
            public override IdentityError InvalidToken()
            {
                return new IdentityError()
                {
                    Code = "InvalidToken",
                    Description = "Feil token."
                };
            }
        
            public override IdentityError LoginAlreadyAssociated()
            {
                return new IdentityError()
                {
                    Code = "LoginAlreadyAssociated",
                    Description = "En bruker med dette brukernavnet finnes allerede."
                };
            }
        
            public override IdentityError InvalidUserName(string userName)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "InvalidUserName";
                string str = $"Brkernavnet '{userName}' er ikke gyldig. Det kan kun inneholde bokstaver og tall.";
                identityError.Description = str;
                return identityError;
            }
        
            public override IdentityError InvalidEmail(string email)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "InvalidEmail";
                string str = $"E-post '{email}' er ugyldig.";
                identityError.Description = str;
                return identityError;
            }
        
            public override IdentityError DuplicateUserName(string userName)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "DuplicateUserName";
                string str = $"Brukernavn '{userName}' er allerede tatt.";
                identityError.Description = str;
                return identityError;
            }
        
            public override IdentityError DuplicateEmail(string email)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "DuplicateEmail";
                string str = $"E-post '{email}' er allerede tatt.";
                identityError.Description = str;
                return identityError;
            }
        
            public override IdentityError InvalidRoleName(string role)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "InvalidRoleName";
                string str = $"Rollenavn '{role}' er ugyldig.";
                identityError.Description = str;
                return identityError;
            }
        
            public override IdentityError DuplicateRoleName(string role)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "DuplicateRoleName";
                string str = $"Rollenavn '{role}' er allerede tatt.";
                identityError.Description = str;
                return identityError;
            }
        
            public virtual IdentityError UserAlreadyHasPassword()
            {
                return new IdentityError()
                {
                    Code = "UserAlreadyHasPassword",
                    Description = "Bruker har allerede passord satt."
                };
            }
        
            public override IdentityError UserLockoutNotEnabled()
            {
                return new IdentityError()
                {
                    Code = "UserLockoutNotEnabled",
                    Description = "Utestenging er ikke slått på for denne brukeren."
                };
            }
        
            public override IdentityError UserAlreadyInRole(string role)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "UserAlreadyInRole";
                string str = $"Brukeren er allerede i rolle '{role}'.";
                identityError.Description = str;
                return identityError;
            }
        
            public override IdentityError UserNotInRole(string role)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "UserNotInRole";
                string str = $"Bruker er ikke i rolle '{role}'.";
                identityError.Description = str;
                return identityError;
            }
        
            public override IdentityError PasswordTooShort(int length)
            {
                IdentityError identityError = new IdentityError();
                identityError.Code = "PasswordTooShort";
                string str = $"Passordet må være på minimum {length} tegn.";
                identityError.Description = str;
                return identityError;
            }
        
            public override IdentityError PasswordRequiresNonAlphanumeric()
            {
                return new IdentityError()
                {
                    Code = "PasswordRequiresNonAlphanumeric",
                    Description = "Passordet må inneholde minst ett spesialtegn."
                };
            }
        
            public override IdentityError PasswordRequiresDigit()
            {
                return new IdentityError()
                {
                    Code = "PasswordRequiresDigit",
                    Description = "Passordet må inneholde minst ett siffer."
                };
            }
        
            public override IdentityError PasswordRequiresLower()
            {
                return new IdentityError()
                {
                    Code = "PasswordRequiresLower",
                    Description = "Passordet må inneholde minst en liten bokstav (a-z)."
                };
            }
        
            public override IdentityError PasswordRequiresUpper()
            {
                return new IdentityError()
                {
                    Code = "PasswordRequiresUpper",
                    Description = "Passordet må inneholde minst en stor bokstav (A-Z)."
                };
            }
        }
        

        【讨论】:

          【解决方案8】:

          Swedish IdentityErrorDescriber,以防有人需要。

          public class SwedishIdentityErrorDescriber : IdentityErrorDescriber
          {
              public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = "Ett okänt fel har inträffat." }; }
              public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Objektet har ändrats sedan uppläsning." }; }
              public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = "Felaktigt lösenord." }; }
              public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = "Ogiltigt token." }; }
              public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "En användare med den här inloggningen finns redan." }; }
              public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"Användarnamnet '{userName}' är ogiltigt, kan endast innehålla bokstäver eller siffror." }; }
              public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"E-postadressen {email} är ogiltig." }; }
              public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"Användarnamnet '{userName}' finns redan." }; }
              public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"E-postadressen {email} finns redan." }; }
              public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"Rollen '{role}' är ogiltig." }; }
              public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = $"Rollen '{role}' finns redan." }; }
              public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "Användaren har redan angett ett lösenord." }; }
              public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "Lockout är inte aktiverat för den här användaren." }; }
              public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"Användaren har redan rollen '{role}'." }; }
              public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = $"Användaren har inte rollen '{role}'." }; }
              public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = $"Lösenordet måste ha minst {length} tecken." }; }
              public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "Lösenordet måste ha minst ett icke alfanumeriskt tecken." }; }
              public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "Lösenordet måste innehålla minst en siffra ('0'-'9')." }; }
              public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = "Lösenordet måste innehålla minst en gemen ('a'-'z')." }; }
              public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "Lösenordet måste innehålla minst en versal ('A'-'Z')." }; }
          }
          

          【讨论】:

            猜你喜欢
            • 2016-10-16
            • 1970-01-01
            • 1970-01-01
            • 2020-11-29
            • 1970-01-01
            • 1970-01-01
            • 2019-01-28
            • 1970-01-01
            • 2016-12-24
            相关资源
            最近更新 更多