Nice programing

ASP.NET Identity UserName 및 Password 오류 메시지를 지역화하는 방법은 무엇입니까?

nicepro 2020. 12. 9. 21:44
반응형

ASP.NET Identity UserName 및 Password 오류 메시지를 지역화하는 방법은 무엇입니까?


"시스템"ASP.NET Identity v1 오류 메시지에 대해 " XYZ 이름이 이미 사용되었습니다 "또는 " 사용자 이름 XYZ가 잘못되었습니다. 문자 나 숫자 만 포함 할 수 있습니다. "와 같은 지역화 된 문자열을 제공 할 수 있습니까?


아직은 리소스의 출처를 지정할 수 있도록이 작업 항목을 추적하는 버그가 있습니다.


ASP.NET Core : (Microsoft.AspNetCore.Identity 1.0.0)

IdentityErrorDescriber를 상속하고 원하는 오류 메시지를 재정의하는 클래스를 만듭니다.

public class CustomIdentityErrorDescriber : IdentityErrorDescriber
{
    public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = $"An unknown failure has occurred." }; }
    public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Optimistic concurrency failure, object has been modified." }; }
    public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = "Incorrect password." }; }
    public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = "Invalid token." }; }
    public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "A user with this login already exists." }; }
    public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"User name '{userName}' is invalid, can only contain letters or digits." }; }
    public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"Email '{email}' is invalid."  }; }
    public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"User Name '{userName}' is already taken."  }; }
    public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"Email '{email}' is already taken."  }; }
    public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"Role name '{role}' is invalid."  }; }
    public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = $"Role name '{role}' is already taken."  }; }
    public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "User already has a password set." }; }
    public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "Lockout is not enabled for this user." }; }
    public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"User already in role '{role}'."  }; }
    public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = $"User is not in role '{role}'."  }; }
    public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = $"Passwords must be at least {length} characters."  }; }
    public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "Passwords must have at least one non alphanumeric character." }; }
    public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "Passwords must have at least one digit ('0'-'9')." }; }
    public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = "Passwords must have at least one lowercase ('a'-'z')." }; }
    public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "Passwords must have at least one uppercase ('A'-'Z')." }; }
}

Startup 클래스에서 ConfigureServices 내부에 사용자 지정 ErrorDescriber를 등록합니다.

services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddErrorDescriber<CustomIdentityErrorDescriber>(); // Add this line

업데이트 : 아래에서 이미 번역 된 스페인어 및 포르투갈어 버전을 찾을 수 있습니다. 다시 확인하세요!

public class SpanishIdentityErrorDescriber : IdentityErrorDescriber
{
    public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = $"Ha ocurrido un error." }; }
    public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Ha ocurrido un error, el objeto ya ha sido modificado (Optimistic concurrency failure)." }; }
    public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = "Password Incorrecta." }; }
    public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = "Ha ingresado un código Inválido." }; }
    public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "Un usuario con ese nombre ya existe." }; }
    public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"El nombre de usuario '{userName}' es inválido. Solo puede contener letras y números." }; }
    public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"La dirección de email '{email}' es incorrecta."  }; }
    public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"El usuario '{userName}' ya existe, por favor ingrese un nombre diferente."  }; }
    public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"La direccion de email '{email}' ya se encuentra registrada. Puede recupar su contraseña para ingresar nuevamente al sistema."  }; }
    public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"El nombre de rol '{role}' es inválido."  }; }
    public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = $"El nombre de rol '{role}' ya existe."  }; }
    public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "El usuario ya tiene contraseña." }; }
    public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "El bloqueo no esta habilitado para este usuario." }; }
    public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"El usuario ya es parte del rol '{role}'."  }; }
    public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = $"El usuario no es parte del rol '{role}'."  }; }
    public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = $"La contraseña deben tener un largo mínimo de {length} caracteres."  }; }
    public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "La contraseña debe contener al menos un caracter alfanumérico." }; }
    public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "La contraseña debe incluir al menos un dígito ('0'-'9')." }; }
    public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = "La contraseña debe incluir al menos una letra minúscula ('a'-'z')." }; }
    public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "La contraseña debe incluir al menos una letra MAYÚSCULA ('A'-'Z')." }; }
}

포르투갈어 : ( furlanrapha 덕분에 많이 )

public class PortugueseIdentityErrorDescriber : IdentityErrorDescriber
{
    public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = $"Um erro desconhecido ocorreu." }; }
    public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Falha de concorrência otimista, o objeto foi modificado." }; }
    public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = "Senha incorreta." }; }
    public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = "Token inválido." }; }
    public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "Já existe um usuário com este login." }; }
    public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"Login '{userName}' é inválido, pode conter apenas letras ou dígitos." }; }
    public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"Email '{email}' é inválido." }; }
    public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"Login '{userName}' já está sendo utilizado." }; }
    public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"Email '{email}' já está sendo utilizado." }; }
    public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"A permissão '{role}' é inválida." }; }
    public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = $"A permissão '{role}' já está sendo utilizada." }; }
    public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "Usuário já possui uma senha definida." }; }
    public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "Lockout não está habilitado para este usuário." }; }
    public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"Usuário já possui a permissão '{role}'." }; }
    public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = $"Usuário não tem a permissão '{role}'." }; }
    public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = $"Senhas devem conter ao menos {length} caracteres." }; }
    public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "Senhas devem conter ao menos um caracter não alfanumérico." }; }
    public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "Senhas devem conter ao menos um digito ('0'-'9')." }; }
    public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = "Senhas devem conter ao menos um caracter em caixa baixa ('a'-'z')." }; }
    public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "Senhas devem conter ao menos um caracter em caixa alta ('A'-'Z')." }; }
}

2014 년 3 월 20 일에 릴리스 된 ID 버전 2부터는 이제 현지화 된 오류 메시지를 가질 수 있습니다.

먼저 현지화 된 ID 패키지를 설치합니다.

Install-Package Microsoft.AspNet.Identity.Core.fr

그런 다음 현지화 된 메시지를 얻으려면 적절한 문화를 설정해야합니다. 예를 들어 문화를 설정하는 한 가지 방법은 web.config에 있습니다.

<system.web>
      <globalization culture="fr-FR" uiCulture="fr"/>
</system.web>

ASP NET Core 해결 방법 (2016 년 11 월 25 일)

IStringLocalizer를 사용자 지정 IdentityErrorDescriber에 삽입 할 수 있습니다.

1) 사용자 지정 IdentityErrorDescriber 만들기 (Gerardo Grignoli 답변 참조)

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

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

    public override IdentityError DuplicateEmail(string email)
    {
        return new IdentityError()
        {
            Code = nameof(DuplicateEmail),
            Description = string.Format(_localizer["Email {0} is already taken."], email)
        };
    }

    // DuplicateUserName, InvalidEmail, DuplicateUserName etc
}

2) Startup.cs에 MultilanguageIdentityErrorDescriber 등록

services.AddIdentity<IdentityUser, IdentityRole>()
            .AddErrorDescriber<MultilanguageIdentityErrorDescriber>()
            .AddDefaultTokenProviders();

3) SharedResource.language.resx에 오류 메시지를 추가합니다.


나는 같은 문제에 부딪 쳤고 빠르고 더러운 해결 방법을 찾았습니다. Microsoft.AspNet.Identity.CoreDotPeek를 사용 하여 어셈블리 내부를 살펴 보았고 (모든 C # 디 컴파일러가 수행 할 것이라고 가정합니다) 이러한 메시지를 담당하는 두 개의 클래스를 찾았습니다.

  • Microsoft.AspNet.Identity.UserValidator<TUser> (사용자 이름 관련)
  • Microsoft.AspNet.Identity.MinimumLengthValidator (비밀번호 관련)

이러한 클래스에는 외부 참조 (어쨌든 대체하려는 문자열 리소스 제외)가 포함되어 있지 않으므로 자체 코드에서이를 다시 구현하는 것은 매우 간단해야합니다.

그렇게 한 후에는 다음에서 올바르게 사용하는 것을 잊지 마십시오 UserManager.

UserManager.UserValidator = new MyCustomUserValidator<MyUserType>(UserManager);
UserManager.PasswordValidator = new MyCustomMinimumLengthValidator(6);

@GerardoGrignoli의 솔루션 용 독일어 버전

public class CustomIdentityErrorDescriber : IdentityErrorDescriber
{
    public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = $"Ein unbekannter Fehler ist aufgetreten." }; }
    public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Fehler bzgl. der Optimistischen Nebenläufigkeit, das Objekt wurde verändert." }; }
    public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = "Ungültiges Passwort." }; }
    public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = "Ungültiger Token." }; }
    public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "Es ist bereits ein Nutzer mit diesem Login vorhanden." }; }
    public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"Nutzername '{userName}' ist ungültig. Erlaubt sind nur Buchstaben und Zahlen." }; }
    public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"E-Mail '{email}' ist ungültig." }; }
    public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"Nutzername '{userName}' ist bereits vergeben." }; }
    public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"E-Mail '{email}' ist bereits vergeben." }; }
    public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"Rollen-Name '{role}' ist ungültig." }; }
    public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = $"Rollen-Name '{role}' ist bereits vergeben." }; }
    public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "Nutzer hat bereits ein Passwort gesetzt." }; }
    public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "Aussperrung ist für diesen Nutzer nicht aktiviert." }; }
    public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"Nutzer ist bereits in Rolle '{role}'." }; }
    public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = $"Nutzer ist nicht in Rolle '{role}'." }; }
    public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = $"Passwörter müssen mindestens {length} Zeichen lang sein." }; }
    public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "Passwörter müssen mindestens ein Sonderzeichen enthalten." }; }
    public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "Passwörter müssen mindestens eine Ziffer enthalten ('0'-'9')." }; }
    public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = "Passwörter müssen mindestens einen Kleinbuchstaben enthalten ('a'-'z')." }; }
    public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "Passwörter müssen mindestens einen Großbuchstaben enthalten ('A'-'Z')." }; }
}

이것은 친애하는 페르시아어 사용자를위한 것입니다.

using Microsoft.AspNetCore.Identity;

namespace WebApplication.Admin.Helpers
{
    public class CustomIdentityErrorDescriber : IdentityErrorDescriber
    {
        public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = $"یک خطای ناشناخته رخ داده است." }; }
        public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = "رکورد جاری پیشتر ویرایش شده‌است و تغییرات شما آن‌را بازنویسی خواهد کرد." }; }
        public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = "کلمه عبور نادرست است." }; }
        public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = "کلمه عبور نامعتبر است." }; }
        public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "این کاربر قبلأ اضافه شده‌است." }; }
        public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"نام کاربری '{userName}' نامعتبر است، فقط می تواند حاوی حروف ویا اعداد باشد." }; }
        public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"ایمیل '{email}' نامعتبر است." }; }
        public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"این نام کاربری '{userName}' به کاربر دیگری اختصاص یافته است." }; }
        public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"ایمیل '{email}' به کاربر دیگری اختصاص یافته است." }; }
        public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"نام نقش '{role}' نامعتبر است." }; }
        public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = $"این نام نقش '{role}' به کاربر دیگری اختصاص یافته است." }; }
        public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "کلمه‌ی عبور کاربر قبلأ تنظیم شده‌است." }; }
        public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "این کاربر فعال است." }; }
        public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"این نقش '{role}' قبلأ به این کاربر اختصاص یافته است." }; }
        public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = $"این نقش '{role}' قبلأ به این کاربر اختصاص نیافته است." }; }
        public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = $"کلمه عبور باید حداقل {length} کاراکتر باشد." }; }
        public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "کلمه عبور باید حداقل یک کاراکتر غیر از حروف الفبا داشته باشد." }; }
        public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "کلمه عبور باید حداقل یک عدد داشته باشد." }; }
        public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = "کلمه عبور باید حداقل یک حروف کوچک داشته باشد." }; }
        public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "کلمه عبور باید حداقل یک حروف بزرگ داشته باشد." }; }
        public override IdentityError RecoveryCodeRedemptionFailed() { return new IdentityError { Code = nameof(RecoveryCodeRedemptionFailed), Description = "بازیابی ناموفق بود." }; }
        public override IdentityError PasswordRequiresUniqueChars(int uniqueChars) { return new IdentityError { Code = nameof(PasswordRequiresUniqueChars), Description = $"کلمه‌ی عبور باید حداقل داراى {0} حرف متفاوت باشد." }; }
    }
}

1AmirJalali의 방법은 완벽하게 작동합니다. web.config에서 문화 설정이 작동하는 동안 필요한 경우 동적으로 설정할 수도 있습니다.이를 수행하는 방법은 다음과 같습니다.

Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

위의 코드 예제에서 cultureName은 설정할 문화권의 이름입니다. 문화 목록은 다음의 "설명"제목에서 찾을 수 있습니다. http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo%28v=vs.80%29.aspx

도움이 되었기를 바랍니다.


논리를 재정의하거나 (즉, 휠을 다시 발명) ASP NET Core로 전환하고 싶지도 않습니다. 내가 원하는 것은 오류 메시지를 무시하고 여러 리소스 파일 (언어 당)을 사용하여 선택한 언어에 맞게 사용자 경험을 조정하는 것입니다.

내 해결책은 다음과 같습니다.

  1. 다음과 같이 'IdentityErrors.resx'리소스 파일을 만들었습니다.

    <data name="DefaultError" xml:space="preserve">
        <value>An unknown failure has occured.</value>
    </data>
    <data name="DuplicateEmail" xml:space="preserve">
        <value>Email '{0}' is already taken.</value>
    </data>
    <data name="DuplicateName" xml:space="preserve">
        <value>Name {0} is already taken.</value>
    </data>
    <data name="ExternalLoginExists" xml:space="preserve">
        <value>A user with that external login already exists.</value>
    </data>
    <data name="InvalidEmail" xml:space="preserve">
        <value>Email '{0}' is invalid.</value>
    </data>
    <data name="InvalidToken" xml:space="preserve">
        <value>Invalid token.</value>
    </data>
    <data name="InvalidUserName" xml:space="preserve">
        <value>User name {0} is invalid, can only contain letters or digits.</value>
    </data>
    <data name="LockoutNotEnabled" xml:space="preserve">
        <value>Lockout is not enabled for this user.</value>
    </data>
    <data name="NoTokenProvider" xml:space="preserve">
        <value>No IUserTokenProvider is registered.</value>
    </data>
    <data name="NoTwoFactorProvider" xml:space="preserve">
        <value>No IUserTwoFactorProvider for '{0}' is registered.</value>
    </data>
    <data name="PasswordMismatch" xml:space="preserve">
        <value>Incorrect password.</value>
    </data>
    <data name="PasswordRequireDigit" xml:space="preserve">
        <value>Passwords must have at least one digit ('0'-'9').</value>
    </data>
    <data name="PasswordRequireLower" xml:space="preserve">
        <value>Passwords must have at least one lowercase ('a'-'z').</value>
    </data>
    <data name="PasswordRequireNonLetterOrDigit" xml:space="preserve">
        <value>Passwords must have at least one non letter or digit character.</value>
    </data>
    <data name="PasswordRequireUpper" xml:space="preserve">
        <value>Passwords must have at least one uppercase ('A'-'Z').</value>
    </data>
    <data name="PasswordTooShort" xml:space="preserve">
        <value>Passwords must be at least {0} characters.</value>
    </data>
    <data name="PropertyTooShort" xml:space="preserve">
        <value>{0} cannot be null or empty.</value>
    </data>
    <data name="RoleNotFound" xml:space="preserve">
        <value>Role {0} does not exist.</value>
    </data>
    <data name="StoreNotIQueryableRoleStore" xml:space="preserve">
        <value>Store does not implement IQueryableRoleStore&amp;lt;TRole&amp;gt;.</value>
    </data>
    <data name="StoreNotIQueryableUserStore" xml:space="preserve">
        <value>Store does not implement IQueryableUserStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserClaimStore" xml:space="preserve">
        <value>Store does not implement IUserClaimStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserConfirmationStore" xml:space="preserve">
        <value>Store does not implement IUserConfirmationStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserEmailStore" xml:space="preserve">
        <value>Store does not implement IUserEmailStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserLockoutStore" xml:space="preserve">
        <value>Store does not implement IUserLockoutStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserLoginStore" xml:space="preserve">
        <value>Store does not implement IUserLoginStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserPasswordStore" xml:space="preserve">
        <value>Store does not implement IUserPasswordStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserPhoneNumberStore" xml:space="preserve">
        <value>Store does not implement IUserPhoneNumberStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserRoleStore" xml:space="preserve">
        <value>Store does not implement IUserRoleStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserSecurityStampStore" xml:space="preserve">
        <value>Store does not implement IUserSecurityStampStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="StoreNotIUserTwoFactorStore" xml:space="preserve">
        <value>Store does not implement IUserTwoFactorStore&amp;lt;TUser&amp;gt;.</value>
    </data>
    <data name="UserAlreadyHasPassword" xml:space="preserve">
        <value>User already has a password set.</value>
    </data>
    <data name="UserAlreadyInRole" xml:space="preserve">
        <value>User already in role.</value>
    </data>
    <data name="UserIdNotFound" xml:space="preserve">
        <value>UserId not found.</value>
    </data>
    <data name="UserNameNotFound" xml:space="preserve">
        <value>User {0} does not exist.</value>
    </data>
    <data name="UserNotInRole" xml:space="preserve">
        <value>User is not in role.</value>
    </data>
    
  2. 'IdentityResultErrorMessages.cs'클래스를 만들었습니다.

    public class IdentityResultErrorMessages
    {
      public static List<String> GetResourceEquivalent(IEnumerable<string> errors)
      {
        List<String> errorList = new List<String>();
        if (errors != null)
        {
          foreach (String error in errors)
          {
            if (error.StartsWith("An unknown failure has occured."))
            {
              errorList.Add(IdentityErrors.DefaultError);
            }
            else if (error.StartsWith("Email '") && error.EndsWith("' is already taken."))
            {
              errorList.Add(String.Format(IdentityErrors.DuplicateEmail, error.Replace("Email '", "").Replace("' is already taken.", "")));
            }
            else if (error.StartsWith("Name ") && error.EndsWith(" is already taken."))
            {
              errorList.Add(String.Format(IdentityErrors.DuplicateName, error.Replace("Name ", "").Replace(" is already taken.", "")));
            }
            else if (error.StartsWith("A user with that external login already exists."))
            {
              errorList.Add(IdentityErrors.ExternalLoginExists);
            }
            else if (error.StartsWith("Email '") && error.EndsWith("' is invalid."))
            {
              errorList.Add(String.Format(IdentityErrors.InvalidEmail, error.Replace("Email '", "").Replace("' is invalid.", "")));
            }
            else if (error.StartsWith("Invalid token."))
            {
              errorList.Add(IdentityErrors.InvalidToken);
            }
            else if (error.StartsWith("User name ") && error.EndsWith(" is invalid, can only contain letters or digits."))
            {
              errorList.Add(String.Format(IdentityErrors.InvalidUserName, error.Replace("User name ", "").Replace(" is invalid, can only contain letters or digits.", "")));
            }
            else if (error.StartsWith("Lockout is not enabled for this user."))
            {
              errorList.Add(IdentityErrors.LockoutNotEnabled);
            }
            else if (error.StartsWith("No IUserTokenProvider is registered."))
            {
              errorList.Add(IdentityErrors.NoTokenProvider);
            }
            else if (error.StartsWith("No IUserTwoFactorProvider for '") && error.EndsWith("' is registered."))
            {
              errorList.Add(String.Format(IdentityErrors.NoTwoFactorProvider, error.Replace("No IUserTwoFactorProvider for '", "").Replace("' is registered.", "")));
            }
            else if (error.StartsWith("Incorrect password."))
            {
              errorList.Add(IdentityErrors.PasswordMismatch);
            }
            else if (error.StartsWith("Passwords must have at least one digit ('0'-'9')."))
            {
              errorList.Add(IdentityErrors.PasswordRequireDigit);
            }
            else if (error.StartsWith("Passwords must have at least one lowercase ('a'-'z')."))
            {
              errorList.Add(IdentityErrors.PasswordRequireLower);
            }
            else if (error.StartsWith("Passwords must have at least one non letter or digit character."))
            {
              errorList.Add(IdentityErrors.PasswordRequireNonLetterOrDigit);
            }
            else if (error.StartsWith("Passwords must have at least one uppercase ('A'-'Z')."))
            {
              errorList.Add(IdentityErrors.PasswordRequireUpper);
            }
            else if (error.StartsWith("Passwords must be at least ") && error.EndsWith(" characters."))
            {
              errorList.Add(String.Format(IdentityErrors.PasswordTooShort, error.Replace("Passwords must be at least ", "").Replace(" characters.", "")));
            }
            else if (error.EndsWith(" cannot be null or empty."))
            {
              errorList.Add(String.Format(IdentityErrors.PropertyTooShort, error.Replace(" cannot be null or empty.", "")));
            }
            else if (error.StartsWith("Role ") && error.EndsWith(" does not exist."))
            {
              errorList.Add(String.Format(IdentityErrors.RoleNotFound, error.Replace("Role ", "").Replace(" does not exist.", "")));
            }
            else if (error.StartsWith("Store does not implement IQueryableRoleStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIQueryableRoleStore);
            }
            else if (error.StartsWith("Store does not implement IQueryableUserStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIQueryableUserStore);
            }
            else if (error.StartsWith("Store does not implement IUserClaimStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserClaimStore);
            }
            else if (error.StartsWith("Store does not implement IUserConfirmationStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserConfirmationStore);
            }
            else if (error.StartsWith("Store does not implement IUserEmailStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserEmailStore);
            }
            else if (error.StartsWith("Store does not implement IUserLockoutStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserLockoutStore);
            }
            else if (error.StartsWith("Store does not implement IUserLoginStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserLoginStore);
            }
            else if (error.StartsWith("Store does not implement IUserPasswordStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserPasswordStore);
            }
            else if (error.StartsWith("Store does not implement IUserPhoneNumberStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserPhoneNumberStore);
            }
            else if (error.StartsWith("Store does not implement IUserRoleStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserRoleStore);
            }
            else if (error.StartsWith("Store does not implement IUserSecurityStampStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserSecurityStampStore);
            }
            else if (error.StartsWith("Store does not implement IUserTwoFactorStore"))
            {
              errorList.Add(IdentityErrors.StoreNotIUserTwoFactorStore);
            }
            else if (error.StartsWith("User already has a password set."))
            {
              errorList.Add(IdentityErrors.UserAlreadyHasPassword);
            }
            else if (error.StartsWith("User already in role."))
            {
              errorList.Add(IdentityErrors.UserAlreadyInRole);
            }
            else if (error.StartsWith("UserId not found."))
            {
              errorList.Add(IdentityErrors.UserIdNotFound);
            }
            else if (error.StartsWith("User ") && error.EndsWith(" does not exist."))
            {
              errorList.Add(String.Format(IdentityErrors.UserNameNotFound, error.Replace("User ", "").Replace(" does not exist.", "")));
            }
            else if (error.StartsWith("User is not in role."))
            {
              errorList.Add(IdentityErrors.UserNotInRole);
            }
          }
        }
        return errorList;
      }
    }
    
  3. Controller의 AddErrors 메서드를 다음과 같이 변경했습니다.

    private void AddErrors(IdentityResult result)
    {
      foreach (var error in IdentityResultErrorMessages.GetResourceEquivalent(result.Errors))
      {
        ModelState.AddModelError("", error);
      }
    }
    

이제 웹 사이트에서 제공 할 다른 언어 콘텐츠에 대한 리소스 파일을 만들 수 있습니다.


이 문제는 이미 꽤 오랫동안 나를 괴롭 혔으므로 특정 문화에 대한 Identity.Core를 설치하는 솔루션은 패키지가 전혀 사용 가능한 경우에만 작동하기 때문에 일반적인 것을 생각해 보았습니다. :)

적절한 현지화를 달성하는 방법은 다음과 같습니다.

  1. 에서 Microsoft.AspNet.Identity.PasswordValidator기본적으로 사용되는 dotPeak 사용 구현을 살펴 보았습니다 ApplicationUserManager.
  2. 그런 다음 오류 메시지를 반환하지 않고 "CustomValidator"문자열로 접두사가 붙은 이러한 오류 메시지의 "코드"를 사용 class CustomPasswordValidator : PasswordValidator하여 ValidateAsync메서드를 직접 구현 하고 재정의했습니다 IdentityResult.
  3. 그런 다음 오류 코드를 기반으로 내 자체 리소스 파일에서 현지화 된 오류 메시지를 제공하기 위해 게시물에서 호출되는 AccountController것을 변경했습니다 .AddErrorsRegister

다음은 이러한 코드를 기반으로 지역화 된 오류 메시지를 검색하는 오류 코드와 메서드를 포함 하는 CustomPasswordValidator및 유틸리티 클래스 PasswordValidatorCodes입니다 (AccountStrings는 리소스 파일 임).

public static class PasswordValidatorCodes
{
    public const string ErrorCodePrefix = "CustomPassword";
    public const string PasswordTooShort = ErrorCodePrefix + "TooShort";
    public const string PasswordRequireNonLetterOrDigit = ErrorCodePrefix + "RequireNonLetterOrDigit";
    public const string PasswordRequireDigit = ErrorCodePrefix + "RequireDigit";
    public const string PasswordRequireLower = ErrorCodePrefix + "RequireLower";
    public const string PasswordRequireUpper = ErrorCodePrefix + "RequireUpper";

    public static string GetLocalizedMessageForCode(string code)
    {
        switch (code)
        {
            case PasswordTooShort:
                return string.Format(AccountStrings.ValidationPasswordTooShort, CustomPasswordValidator.RequiredPasswordLength);
            case PasswordRequireNonLetterOrDigit:
                return AccountStrings.ValidationPasswordRequireNonLetterOrDigit;
            case PasswordRequireDigit:
                return AccountStrings.ValidationPasswordRequireDigit;
            case PasswordRequireLower:
                return AccountStrings.ValidationPasswordRequireLower;
            case PasswordRequireUpper:
                return AccountStrings.ValidationPasswordRequireUpper;
            default:
                throw new ArgumentException("code");
        }
    }
}

public class CustomPasswordValidator : PasswordValidator
{
    public const int RequiredPasswordLength = 6;

    public CustomPasswordValidator()
    {
        RequiredLength = RequiredPasswordLength;
        RequireNonLetterOrDigit = false;
        RequireDigit = true;
        RequireLowercase = true;
        RequireUppercase = false;
    }

    public override Task<IdentityResult> ValidateAsync(string item)
    {
        if (item == null) throw new ArgumentNullException("item");
        var list = new List<string>();

        if (string.IsNullOrWhiteSpace(item) || item.Length < RequiredLength)
        {
            list.Add(PasswordValidatorCodes.PasswordTooShort);
        }

        if (RequireNonLetterOrDigit && item.All(IsLetterOrDigit))
        {
            list.Add(PasswordValidatorCodes.PasswordRequireNonLetterOrDigit);
        }

        if (RequireDigit && item.All(c => !IsDigit(c)))
        {
            list.Add(PasswordValidatorCodes.PasswordRequireDigit);
        }

        if (RequireLowercase && item.All(c => !IsLower(c)))
        {
            list.Add(PasswordValidatorCodes.PasswordRequireLower);
        }

        if (RequireUppercase && item.All(c => !IsUpper(c)))
        {
            list.Add(PasswordValidatorCodes.PasswordRequireUpper);
        }

        return Task.FromResult(list.Count == 0
            ? IdentityResult.Success
            : new IdentityResult(list));
    }
}

그리고 여기에 수정 된 AccountController.AddErrors방법이 있습니다. 보시다시피 속성에 대한 모델에 오류를 추가하고 있습니다. Password왜냐하면 Password유효성 검사를 통과하지 못하면 Password유효성 검사 요약이 아닌 필드에 오류 메시지가 표시되기를 원하기 때문 입니다. 이것이 CustomPasswordValidator오류 메시지가 아닌 오류 코드를 직접 생성 하는 유일한 이유입니다 .

private void AddErrors(IdentityResult result)
{
    foreach (var error in result.Errors)
    {
        if (error.StartsWith(PasswordValidatorCodes.ErrorCodePrefix))
        {
            ModelState.AddModelError("Password", PasswordValidatorCodes.GetLocalizedMessageForCode(error));
            continue;
        }
        ModelState.AddModelError(string.Empty, error);
    }
}

마지막으로 IdentityConfig파일 을 수정하는 것을 잊지 마십시오 . 예 :

manager.PasswordValidator = new CustomPasswordValidator();

최신 정보:

이제 나는 Marselus Chia (다른 답변 참조)가 비슷한 솔루션을 찾았지만 VB에 대해 알아 냈습니다.


다음은 제라르 Grignoli의 대답 프랑스어 번역와 함께

/// <inheritdoc />
/// <summary>
/// Service to enable localization (french) for application facing identity errors.
/// </summary>
public class FrenchIdentityErrorDescriber : IdentityErrorDescriber
{
    /// <inheritdoc />
    public override IdentityError DefaultError() => new IdentityError { Code = nameof(DefaultError), Description = "Une erreur inconnue est survenue." };

    /// <inheritdoc />
    public override IdentityError ConcurrencyFailure() => new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Erreur de concurrence simultanée optimiste, l'objet a été modifié." };

    /// <inheritdoc />
    public override IdentityError PasswordMismatch() => new IdentityError { Code = nameof(PasswordMismatch), Description = "Mot de passe incorrect." };

    /// <inheritdoc />
    public override IdentityError InvalidToken() => new IdentityError { Code = nameof(InvalidToken), Description = "Jeton invalide." };

    /// <inheritdoc />
    public override IdentityError LoginAlreadyAssociated() => new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "Un utilisateur avec ce nom de compte existe déjà." };

    /// <inheritdoc />
    public override IdentityError InvalidUserName(string userName) => new IdentityError { Code = nameof(InvalidUserName), Description = $"Le nom de compte '{userName}' est invalide. Seuls les lettres et chiffres sont autorisés." };

    /// <inheritdoc />
    public override IdentityError InvalidEmail(string email) => new IdentityError { Code = nameof(InvalidEmail), Description = $"L'email '{email}' est invalide." };

    /// <inheritdoc />
    public override IdentityError DuplicateUserName(string userName) => new IdentityError { Code = nameof(DuplicateUserName), Description = $"Le nom de compte '{userName}' est déjà utilisé." };

    /// <inheritdoc />
    public override IdentityError DuplicateEmail(string email) => new IdentityError { Code = nameof(DuplicateEmail), Description = $"L'email '{email} est déjà utilisée." };

    /// <inheritdoc />
    public override IdentityError InvalidRoleName(string role) => new IdentityError { Code = nameof(InvalidRoleName), Description = $"Le nom du rôle '{role}' est invalide." };

    /// <inheritdoc />
    public override IdentityError DuplicateRoleName(string role) => new IdentityError { Code = nameof(DuplicateRoleName), Description = $"Le nom du rôle '{role}' est déjà utilisé." };

    /// <inheritdoc />
    public override IdentityError UserAlreadyHasPassword() => new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "L'utilisateur a déjà un mot de passe." };

    /// <inheritdoc />
    public override IdentityError UserLockoutNotEnabled() => new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "Le verouillage n'est pas activé pour cet utilisateur." };

    /// <inheritdoc />
    public override IdentityError UserAlreadyInRole(string role) => new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"L'utilisateur a déjà le rôle '{role}'." };

    /// <inheritdoc />
    public override IdentityError UserNotInRole(string role) => new IdentityError { Code = nameof(UserNotInRole), Description = $"L'utilisateur n'a pas le rôle '{role}'." };

    /// <inheritdoc />
    public override IdentityError PasswordTooShort(int length) => new IdentityError { Code = nameof(PasswordTooShort), Description = $"Le mot de passe doit contenir au moins {length} caractères." };

    /// <inheritdoc />
    public override IdentityError PasswordRequiresNonAlphanumeric() => new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "Le mot de passe doit contenir au moins un caractère non alpha-numérique." };

    /// <inheritdoc />
    public override IdentityError PasswordRequiresDigit() => new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "Le mot de passe doit contenir au moins un chiffre ('0'-'9')." };

    /// <inheritdoc />
    public override IdentityError PasswordRequiresLower() => new IdentityError { Code = nameof(PasswordRequiresLower), Description = "Le mot de passe doit contenir au moins un charactère minuscule ('a'-'z')." };

    /// <inheritdoc />
    public override IdentityError PasswordRequiresUpper() => new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "Le mot de passe doit contenir au moins un charactère majuscule ('A'-'Z')." };
}

Hi Here My Solution to translate identity errors :

 public string TranslateIdentityResult(string massage)
    {

        var list = new List<KeyValuePair<string, string>>() {
            new KeyValuePair<string, string>("An unknown failure has occured.", "حدث خطأ غير معروف"),
            new KeyValuePair<string, string>("Email '{0}' is already taken.", "هذا البريد '{0}' موجود بالفعل"),
            new KeyValuePair<string, string>("Name {0} is already taken.", "الاسم {0} مأخوذ بالفعل."),
            new KeyValuePair<string, string>("A user with that external login already exists.", "يوجد بالفعل مستخدم له معلومات تسجيل الدخول الخارجية."),
            new KeyValuePair<string, string>("Email '{0}' is invalid.", "البريد الإلكتروني '{0}' غير صحيح."),
            new KeyValuePair<string, string>("Invalid token.", "المفتاح غير صالح"),
            new KeyValuePair<string, string>("User name {0} is invalid, can only contain letters or digits.", "اسم المستخدم {0} غير صالح ، يمكن أن يحتوي فقط على أحرف أو أرقام."),
            new KeyValuePair<string, string>("Lockout is not enabled for this user.", "تأمين المستخدم غير متاح لهذا المستخدم"),
            new KeyValuePair<string, string>("Incorrect password.", "الرقم السري غير صحيح"),
            new KeyValuePair<string, string>("Passwords must have at least one digit ('0'-'9').", "الرقم السري يجب أ،ن يحتوي على الأقل رقم واحد (0-9)"),
            new KeyValuePair<string, string>("Passwords must have at least one lowercase ('a'-'z').", "يجب أن تحتوي كلمات المرور على حرف صغير واحد على الأقل ('a' - 'z')."),
            new KeyValuePair<string, string>("Passwords must have at least one non letter or digit character.", "يجب أن يكون لكلمة مرور حرف واحد على الأقل غير الحرف أو الرقم."),
            new KeyValuePair<string, string>("Passwords must have at least one uppercase ('A'-'Z').", "يجب أن تحتوي كلمات المرور على حرف كبير واحد على الأقل ('A' - 'Z')."),
            new KeyValuePair<string, string>("Passwords must be at least {0} characters.", "يجب أن تكون كلمات المرور على الأقل {0} حرفًا."),
            new KeyValuePair<string, string>("{0} cannot be null or empty.", "لا يمكن أن يكون {0} خاليًا أو فارغًا."),
            new KeyValuePair<string, string>("Role {0} does not exist.", "صلاحية {0} غير موجود."),
            new KeyValuePair<string, string>("User already has a password set.", "المستخدم لديه بالفعل كلمة مرور محددة."),
            new KeyValuePair<string, string>("User already in role.", "المستخدم بالفعل لديه هذي الصلاحية."),
            new KeyValuePair<string, string>("UserId not found.", "لم يتم العثور على هوية المستخدم."),
            new KeyValuePair<string, string>("User {0} does not exist.", "المستخدم {0} غير موجود."),
            new KeyValuePair<string, string>("User is not in role.", "المستخدم ليس لديه صلاحية.")
        };

        return list.Find(x => x.Key.Equals(massage)).Value;
    }

 private void AddErrors(IdentityResult result)
    {
        foreach (var error in result.Errors)
        {
            //if my function is not found error it will print it as it's
            foreach(var msg in error.Split('.'))
            {
                ModelState.AddModelError("", accBClass.TranslateIdentityResult(msg.TrimStart(' ')) ?? msg);
            }
        }
    }


@Gerardo Grinolli 외에도 러시아어로 번역 된이 버전에 대한 답변 :

public class CustomIdentityErrorDescriber : IdentityErrorDescriber
{
    public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = $"Произошла неизвестная ошибка" }; }
    public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Ошибка оптимистичного контроля параллелизма, объект был изменён" }; }
    public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = "Некорретный пароль" }; }
    public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = "Недействительный токен" }; }
    public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "Пользователь с таким логином уже существует" }; }
    public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"Имя пользователя '{userName}' некорректно, может содержать только буквы и цифры" }; }
    public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"Email '{email}' некорректен" }; }
    public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"Пользователь с именем '{userName}' уже существует" }; }
    public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"Email '{email}' уже используется" }; }
    public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"Имя роли '{role}' некорректно" }; }
    public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = $"Имя роли '{role}' уже используется" }; }
    public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "Пользователь уже установил пароль" }; }
    public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "Блокировка недоступна для этого пользователя" }; }
    public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"Пользователю уже присвоена роль '{role}'." }; }
    public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = $"У пользователя нет роли '{role}'." }; }
    public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = $"Пароль должен быть длиной не менее {length} символов" }; }
    public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "Пароль должен быть содержать хотя бы один не буквенно-цифровой символ" }; }
    public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "Пароль должен содержать хотя бы одну цифру ('0'-'9')." }; }
    public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = "Пароль должен содержать хотя бы один символ в нижнем регистре ('a'-'z')." }; }
    public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "Пароль должен содержать хотя бы один символ в верхнем регистре ('A'-'Z')" }; }
}

폴란드어 버전

public class CustomErrorDescriber : IdentityErrorDescriber
{
    public override IdentityError DefaultError() {      return new IdentityError { Code = nameof(DefaultError), Description = $"Wystąpił nieanany błąd." }; }
    public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Błąd współbieżności, obiekt został zmodyfikowany." }; }
    public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = "Nieprawidłowe hasło." }; }
    public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = "Nieprawidłowy token." }; }
    public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "Użytkownik o takiej nazwie już istnieje." }; }
    public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"Nazwa użytkownika \"'{userName}'\" jest nieprawidłowa, może posiadać tylko znaki i cyfry." }; }
    public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"Email \"'{email}'\" jest nieprawidłowy." }; }
    public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"Nazwa użytkownika \"'{userName}'\" jest zajęta." }; }
    public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"Adres \"'{email}'\" jest zajęty." }; }
    public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"Grupa \"'{role}'\" jest nieprawidłowa." }; }
    public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = $"Nazwa grupy \"'{role}'\" jest zajęta." }; }
    public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "Hasło użytkownika jest już ustawione." }; }
    public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "Blokada nie jest ustawiona dla tego użytkownika." }; }
    public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"Użytkownik ma już przypisaną grupę \"'{role}'\"." }; }
    public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = $"Użytkownik nie należy do grupy \"'{role}'\"." }; }
    public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = $"Hasło musi posiadać conajmniej {length} znaków." }; }
    public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "Hasło musi posiadać przynajmniej jeden znak alfanumeryczny." }; }
    public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "Hasło musi posiadać przynajmniej jedną cyfrę ('0'-'9')." }; }
    public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = "Hasło musi posiadać przynajmniej jedną małą literę ('a'-'z')." }; }
    public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "Hasło musi posiadać przynajmniej jedną wielką literę ('A'-'Z')." }; }
    public override IdentityError PasswordRequiresUniqueChars(int uniqueChars) { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = "Hasło musi posiadać przynajmniej jeden znak specjalny." }; }
}

스페인어로이 작업을 수행하기 위해 제가 한 일을 여러분과 공유하겠습니다. 메시지를 쉽게 사용자 지정할 수 있습니다!

string Errores = result.Errors.FirstOrDefault();
Errores = Errores.Replace("Name " + Email.Text + " is already taken.", "- El mail " + Email.Text + " ya fue registrado. Intente recuperar la clave.<br/>");
Errores = Errores.Replace("Passwords must be at least 6 characters.", "- La clave debe contener por lo menos 6 caracteres.<br/>");
Errores = Errores.Replace("Passwords must have at least one non letter or digit character.", "- La clave debe contener por lo menos un caracter que no sea letra ni dígito. Por ejemplo: un punto.<br/>");
Errores = Errores.Replace("Passwords must have at least one digit ('0'-'9').", "- La clave debe contener al menos un dígito (entre 0 y 9).<br/>");
Errores = Errores.Replace("Passwords must have at least one uppercase ('A'-'Z').", "- La clave debe contener al menos una letra (entre A y Z).<br/>");
ErrorMessage.Text = "Errores:<br/><br/>" + Errores;

내 솔루션은 Microsoft.AspNet.Identity.PasswordValidator에서 상속 된 새 사용자 지정 암호 유효성 검사 클래스를 만들고 오류 메시지를 보내는 ValidateAsync를 재정의하는 것입니다. 여기에서 오류 메시지를 사용자 정의하면 저에게 효과적입니다 ...

이 클래스는 전역 리소스 파일 이름 유효성 검사기가 있다고 가정합니다. 이 클래스의 스크립트와 리소스 파일 샘플은 여기에서 찾을 수 있습니다. ASP.NET Identity-Codeplex Sample Code

다음은 vb.net의 샘플 작업 코드입니다.


Imports System.Threading.Tasks 

Imports Microsoft.AspNet.Identity

Namespace MyNameSpace

Public Class MyPasswordValidator
    Inherits PasswordValidator
    Public Overrides Function ValidateAsync(item As String) As Task(Of IdentityResult)
        Dim errorMessage As String = String.Empty
        Dim bolminChar As Boolean = True
        Dim bolminDigit As Boolean = True
        Dim bolminLcase As Boolean = True
        Dim bolminUCase As Boolean = True
        Dim bolminNonAlfanum As Boolean = True

        If Not String.IsNullOrWhiteSpace(item) AndAlso item.Length >= Me.RequiredLength Then
            bolminChar = True
        Else
            bolminChar = False
            errorMessage = String.Format(CultureInfo.CurrentCulture, Resources.validator.PasswordTooShort & "<br/>", RequiredLength)
        End If

        If Me.RequireDigit Then
            Dim regex As New Regex("^(?=.*\d).+$")
            Dim match As Match = regex.Match(item)
            If match.Success Then
                bolminDigit = True
            Else
                bolminDigit = False
                errorMessage &= Resources.validator.PasswordRequireDigit & ".<br/>"
            End If
        End If

        If Me.RequireLowercase Then
            Dim LCrex As New Regex("^(?=.*[a-z]).+$")
            Dim LCMatch As Match = LCrex.Match(item)
            If LCMatch.Success Then
                bolminLcase = True
            Else
                bolminLcase = False
                errorMessage &= Resources.validator.PasswordRequireLower & "<br/>"
            End If
        End If

        If Me.RequireNonLetterOrDigit Then
            Dim NAFRex As New Regex("^(?=.*[-+_!@#$%=^\[\]\{\}()&*.,?]).+$")
            Dim NAFMatch As Match = NAFRex.Match(item)
            If NAFMatch.Success Then
                bolminNonAlfanum = True
            Else
                bolminNonAlfanum = False
                errorMessage &= Resources.validator.PasswordRequireNonLetterOrDigit & "<br/>"
            End If
        End If

        If Me.RequireUppercase Then
            Dim UCrex As New Regex("^(?=.*[A-Z]).+$")
            Dim UCMatch As Match = UCrex.Match(item)
            If UCMatch.Success Then
                bolminUCase = True
            Else
                bolminUCase = False
                errorMessage &= Resources.validator.PasswordRequireUpper & "<br/>"
            End If
        End If

        If bolminChar And bolminDigit And bolminLcase And bolminNonAlfanum And bolminUCase Then
            Return Task.FromResult(Of IdentityResult)(IdentityResult.Success)
        Else
            Return Task.FromResult(Of IdentityResult)(IdentityResult.Failed(New String() {errorMessage}))
        End If
        'Return MyBase.ValidateAsync(item)
    End Function
End Class

Public Class MyUserValidator
    Inherits UserValidator(Of applicationUser, int64)
    Private _manager As ApplicationUserManager

    Public Sub New(manager As ApplicationUserManager)
        MyBase.New(manager)
        _manager = manager
    End Sub

    Public Overrides Function ValidateAsync(item As applicationUser) As Task(Of IdentityResult)
        If item Is Nothing Then
            Throw New ArgumentNullException("item")
        End If

        Dim errors As New List(Of String)()
        Validateusername(item, errors)

        If Me.RequireUniqueEmail Then
            ValidateEmail(item, errors)
        End If

        If errors.Count > 0 Then
            Return Task.FromResult(Of IdentityResult)(IdentityResult.Failed(errors.ToArray()))
        End If
        Return Task.FromResult(Of IdentityResult)(IdentityResult.Success)
    End Function

    Private Sub Validateusername(User As applicationUser, errors As List(Of String))
        If String.IsNullOrWhiteSpace(User.UserName) Then
            errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.validator.PropertyTooShort, "Email")) '
        ElseIf Me.AllowOnlyAlphanumericUserNames AndAlso Not Regex.IsMatch(User.UserName, "^[A-Za-z0-9@_\.]+$") Then
            ' If any characters are not letters or digits, its an illegal user name
            errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.validator.InvalidUserName, User.UserName))
        Else
            Dim owner = _manager.FindByName(User.UserName)
            If owner IsNot Nothing AndAlso Not EqualityComparer(Of applicationUser).ReferenceEquals(owner.Id, User.Id) Then
                errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.validator.DuplicateName, User.UserName))
            End If
        End If
    End Sub

    Private Sub ValidateEmail(User As ApplicationUser, errors As List(Of String))
        Dim email As String = String.Empty

        If User.Id > 0 Then
            email = _manager.GetEmail(User.Id)
        End If
        If String.IsNullOrWhiteSpace(email) Then
            errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.validator.PropertyTooShort, "Email"))
            Return
        End If

        Try
            Dim m As New MailAddress(email)
        Catch ex As Exception
            errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.validator.InvalidEmail, email))
            Return
        End Try
        Dim owner = _manager.FindByEmail(email)
        If owner IsNot Nothing AndAlso Not EqualityComparer(Of ApplicationUser).ReferenceEquals(owner.Id, User.Id) Then
            errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.validator.DuplicateName, email))
        End If
    End Sub
End Class

이러한 클래스를 사용하려면 identityConfig.vb 파일의 설정을 업데이트해야합니다.


내 솔루션은 약간 더럽지 만 예상대로 작동합니다. 아이디어는 새 사용자를 등록 할 때 IdentityResult 개체 결과가 가져 오는 모든 오류를 할당하는 것입니다 .

var result = await UserManager.CreateAsync(user, model.Password);

우리가 만들 새로운 것에. 먼저 사용자 지정 오류를 포함 할 목록을 만들어야합니다.

var erroresEspanol = new List<string>();

그런 다음 결과 내부의 오류를 반복 하고 그 원인 (중복 사용자, 이메일 등)에 따라 모든 오류에 대해 새로운 사용자 지정 오류를 추가해야합니다.

foreach (var error in result.Errors)
            {
                if (error == ("Name " + model.Usuario + " is already taken."))
                {
                    erroresEspanol.Add("El Usuario " + model.Usuario + " ya existe.");
                }
                if (error.Substring(0, error.IndexOf(" ")) == "Email")
                {
                    erroresEspanol.Add("El Email " + model.Email + " ya fue ingresado.");
                }
                if (error.Substring(0, error.IndexOf(" ")) == "Passwords")
                {
                    erroresEspanol.Add("La contraseña debe contener mayúscula, minúscula y al menos 6 caracteres de longitud.");
                }
            }

그 후에 새로운 IdentityResult 객체를 만듭니다.

var resultado = new IdentityResult(erroresEspanol);

그리고 Register 작업이 끝날 때 AddErrors 메서드에 전달합니다.

AddErrors(resultado);

동일한 문제가 발생하면이를 달성하기 위해 자체 리소스 파일을 제공 할 수 있습니다. 물론 약간의 반사 해킹이 필요합니다! 먼저 완전한 보안으로 실행해야합니다. 즉, web.config에 설정해야합니다.

<system.web>
  <securityPolicy>
     <trustLevel name="Full" policyFile="internal"/>
  </securityPolicy>
...

다음으로 앱 시작 코드 :

var ass = Assembly.Load("Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
Type hack = ass.GetType("Microsoft.AspNet.Identity.Resources");
var field = hack.GetField("resourceMan",
                        BindingFlags.Static |
                        BindingFlags.NonPublic);
// NOTE: this is where you set you own resource manager!
field.SetValue(null, new global::System.Resources.ResourceManager("WebApplication1.Resources", typeof(WebApplication1.Resources).Assembly));

완료되었습니다!


즉시 사용할 수있는 패키지가없는 문화권에 대해 AspNet.Identity의 지역화 된 버전을 만드는 솔루션을 찾았습니다. 단계는 다음과 같습니다.

  1. GitHub 에서 소스 코드를 다운로드하고 Visual Studio에서 src / Microsoft.AspNet.Identity.Core 프로젝트를 엽니 다.
  2. 프로젝트에 새 항목 (리소스 파일)을 추가하십시오. 그 이름을 Resources.aa-BB.resx하는 aa-BB당신이 어셈블리를 지역화하는 데 필요한 문화입니다. 예 : Resources.fa-IR.resx.
  3. 새로 생성 된 파일을 열고 여기에서 리소스 항목을 복사 Resources.resx합니다.
  4. 원하는대로 텍스트를 현지화하십시오.
  5. 프로젝트를 빌드하십시오.
  6. bin폴더로 이동 하면 Debug또는 Release디렉토리 아래에 aa-BB(이전에 입력 한 문화권) 이라는 폴더가 표시됩니다 . bin프로젝트 디렉토리에 폴더를 복사하십시오 .
  7. @ 1AmirJalali가 말한 내용을 변경하십시오 ( 이 게시물 ).
  8. 잘 했어! 현지화가 완료되었습니다. 현지화 된 패키지를 공유해보세요. :)

여기의 답변을 바탕으로 MVC Core 2.2를 기반으로 구축 된 다국어 웹 사이트를 직접 구현했습니다. 여기서 문자열을 하드 코딩 할 수 없습니다.

자동 생성 디자이너와 함께 기본 리소스 파일을 사용하여 문자열을 가져오고 있으며 코드는 다음과 같습니다.

public class LocalizedIdentityErrorDescriber : IdentityErrorDescriber
{
    private ResourceManager ResourceManager { get; set; }

    public LocalizedIdentityErrorDescriber()
    {
        ResourceManager = Translations.ResourceManager;
    }

    public override IdentityError DefaultError() { return new IdentityError { Code = nameof(DefaultError), Description = Translations.Validation_DefaultError }; }
    public override IdentityError ConcurrencyFailure() { return new IdentityError { Code = nameof(ConcurrencyFailure), Description = Translations.Validation_ConcurrencyFailure }; }
    public override IdentityError PasswordMismatch() { return new IdentityError { Code = nameof(PasswordMismatch), Description = Translations.Validation_PasswordMismatch }; }
    public override IdentityError InvalidToken() { return new IdentityError { Code = nameof(InvalidToken), Description = Translations.Validation_InvalidToken }; }
    public override IdentityError LoginAlreadyAssociated() { return new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = Translations.Validation_LoginAlreadyAssociated }; }
    public override IdentityError InvalidUserName(string userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = string.Format(Translations.Validation_InvalidUserName, userName) }; }
    public override IdentityError InvalidEmail(string email) { return new IdentityError { Code = nameof(InvalidEmail), Description = string.Format(Translations.Validation_InvalidEmail, email) }; }
    public override IdentityError DuplicateUserName(string userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = string.Format(Translations.Validation_DuplicateUserName, userName) }; }
    public override IdentityError DuplicateEmail(string email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = string.Format(Translations.Validation_DuplicateEmail, email) }; }
    public override IdentityError InvalidRoleName(string role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = string.Format(Translations.Validation_InvalidRoleName, role) }; }
    public override IdentityError DuplicateRoleName(string role) { return new IdentityError { Code = nameof(DuplicateRoleName), Description = string.Format(Translations.Validation_DuplicateRoleName, role) }; }
    public override IdentityError UserAlreadyHasPassword() { return new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = Translations.Validation_UserAlreadyHasPassword }; }
    public override IdentityError UserLockoutNotEnabled() { return new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = Translations.Validation_UserLockoutNotEnabled }; }
    public override IdentityError UserAlreadyInRole(string role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = string.Format(Translations.Validation_UserAlreadyInRole, role) }; }
    public override IdentityError UserNotInRole(string role) { return new IdentityError { Code = nameof(UserNotInRole), Description = string.Format(Translations.Validation_UserNotInRole, role) }; }
    public override IdentityError PasswordTooShort(int length) { return new IdentityError { Code = nameof(PasswordTooShort), Description = string.Format(Translations.Validation_PasswordTooShort, length) }; }
    public override IdentityError PasswordRequiresNonAlphanumeric() { return new IdentityError { Code = nameof(PasswordRequiresNonAlphanumeric), Description = Translations.Validation_PasswordRequiresNonAlphanumeric }; }
    public override IdentityError PasswordRequiresDigit() { return new IdentityError { Code = nameof(PasswordRequiresDigit), Description = Translations.Validation_PasswordRequiresDigit }; }
    public override IdentityError PasswordRequiresLower() { return new IdentityError { Code = nameof(PasswordRequiresLower), Description = Translations.Validation_PasswordRequiresLower }; }
    public override IdentityError PasswordRequiresUpper() { return new IdentityError { Code = nameof(PasswordRequiresUpper), Description = Translations.Validation_PasswordRequiresUpper }; }
}

그런 다음 Startup.cs의 ID 파이프 라인에 통합됩니다.

services.AddDefaultIdentity<User>()
    .AddErrorDescriber<LocalizedIdentityErrorDescriber>()
    .AddDefaultTokenProviders();

Lastly, I defined the strings in my Translations.resx and sub resource files, where the keys are named Validation_DefaultError, Validation_PasswordMismatch etc.

참고URL : https://stackoverflow.com/questions/19961648/how-to-localize-asp-net-identity-username-and-password-error-messages

반응형