Comment localiser les messages d’erreur ASP.NET Identity UserName et Password?

Est-il possible de fournir des chaînes localisées pour les messages d’erreur “system” ASP.NET Identity v1, comme ” Nom XYZ est déjà pris ” ou ” Nom d’utilisateur XYZ non valide, ne peut contenir que des lettres ou des chiffres “?

Pas encore, nous avons un bug de suivi de cet élément de travail pour permettre de spécifier d’où proviennent les ressources.

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

Créez une classe qui hérite de IdentityErrorDescriber et remplace les messages d’erreur souhaités.

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(ssortingng userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"User name '{userName}' is invalid, can only contain letters or digits." }; } public override IdentityError InvalidEmail(ssortingng email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"Email '{email}' is invalid." }; } public override IdentityError DuplicateUserName(ssortingng userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"User Name '{userName}' is already taken." }; } public override IdentityError DuplicateEmail(ssortingng email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"Email '{email}' is already taken." }; } public override IdentityError InvalidRoleName(ssortingng role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"Role name '{role}' is invalid." }; } public override IdentityError DuplicateRoleName(ssortingng 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(ssortingng role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"User already in role '{role}'." }; } public override IdentityError UserNotInRole(ssortingng 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')." }; } } 

Sur votre classe de démarrage, enregistrez le ErrorDescriber personnalisé dans ConfigureServices:

 services.AddIdentity() .AddErrorDescriber(); // Add this line 

MISE À JOUR: Ci dessous, vous pouvez trouver des versions déjà traduites pour l’espagnol et le portugais. Vérifiez les deux!

 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 objecto 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(ssortingng 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(ssortingng email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"La dirección de email '{email}' es incorrecta." }; } public override IdentityError DuplicateUserName(ssortingng userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"El usuario '{userName}' ya existe, por favor ingrese un nombre diferente." }; } public override IdentityError DuplicateEmail(ssortingng 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(ssortingng role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"El nombre de rol '{role}' es inválido." }; } public override IdentityError DuplicateRoleName(ssortingng 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(ssortingng role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"El usuario ya es parte del rol '{role}'." }; } public override IdentityError UserNotInRole(ssortingng 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')." }; } } 

Portugais: (merci beaucoup à 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 objecto 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(ssortingng userName) { return new IdentityError { Code = nameof(InvalidUserName), Description = $"Login '{userName}' é inválido, pode conter apenas letras ou dígitos." }; } public override IdentityError InvalidEmail(ssortingng email) { return new IdentityError { Code = nameof(InvalidEmail), Description = $"Email '{email}' é inválido." }; } public override IdentityError DuplicateUserName(ssortingng userName) { return new IdentityError { Code = nameof(DuplicateUserName), Description = $"Login '{userName}' já está sendo utilizado." }; } public override IdentityError DuplicateEmail(ssortingng email) { return new IdentityError { Code = nameof(DuplicateEmail), Description = $"Email '{email}' já está sendo utilizado." }; } public override IdentityError InvalidRoleName(ssortingng role) { return new IdentityError { Code = nameof(InvalidRoleName), Description = $"A permissão '{role}' é inválida." }; } public override IdentityError DuplicateRoleName(ssortingng 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(ssortingng role) { return new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"Usuário já possui a permissão '{role}'." }; } public override IdentityError UserNotInRole(ssortingng 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')." }; } } 

À partir de la version 2 d’identité publiée le 20 mars 2014, vous pouvez désormais afficher des messages d’erreur localisés.

D’abord, installez le package d’identité localisée.

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

Ensuite, la culture appropriée doit être définie pour obtenir des messages localisés. Par exemple, une manière de définir la culture est dans web.config.

    

J’ai rencontré le même problème et trouvé une solution rapide et sale. J’ai regardé à l’intérieur de l’assembly Microsoft.AspNet.Identity.Core aide de DotPeek (je suppose que tout décompilateur C # le fera) et j’ai trouvé deux classes responsables de ces messages:

  • Microsoft.AspNet.Identity.UserValidator (lié à UserName)
  • Microsoft.AspNet.Identity.MinimumLengthValidator (lié au mot de passe)

Ces classes ne contiennent aucune référence externe (autre que les ressources de chaîne que vous souhaitez remplacer), de sorte que leur implémentation dans votre propre code devrait être assez simple.

Après cela, n’oubliez pas de les utiliser correctement dans votre UserManager :

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

Solution de contournement ASP NET Core (25.11.2016)

Vous pouvez injecter ISsortingngLocalizer dans IdentityErrorDescriber personnalisé

1) Créez un IdentityErrorDescriber personnalisé (voir la réponse de Gerardo Grignoli)

 public class MultilanguageIdentityErrorDescriber : IdentityErrorDescriber { private readonly ISsortingngLocalizer _localizer; public MultilanguageIdentityErrorDescriber(ISsortingngLocalizer localizer) { _localizer = localizer; } public override IdentityError DuplicateEmail(ssortingng email) { return new IdentityError() { Code = nameof(DuplicateEmail), Description = ssortingng.Format(_localizer["Email {0} is already taken."], email) }; } // DuplicateUserName, InvalidEmail, DuplicateUserName etc } 

2) Enregistrez MultilanguageIdentityErrorDescriber dans Startup.cs

 services.AddIdentity() .AddErrorDescriber() .AddDefaultTokenProviders(); 

3) Ajoutez des messages d’erreur à SharedResource.language.resx.

1La méthode d’AmirJalali fonctionne parfaitement. Si vous définissez la culture dans les travaux de web.config, elle peut également être définie dynamicment si nécessaire. Voici comment procéder:

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

Dans l’exemple de code ci-dessus, cultureName, est le nom de la culture à définir. Une liste de cultures se trouve sous “Remarques” ici: http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo%28v=vs.80%29.aspx

J’espère que cela t’aides.

Je ne veux pas passer outre la logique (c.-à-d. Réinventer la roue) et je ne veux pas non plus passer à ASP NET Core. Tout ce que je veux faire, c’est remplacer les messages d’erreur et utiliser plusieurs fichiers de ressources (par langue) pour adapter l’expérience utilisateur à la langue choisie.

Voici ma solution:

  1. J’ai créé un fichier de ressources ‘IdentityErrors.resx’ avec les éléments suivants:

      An unknown failure has occured.   Email '{0}' is already taken.   Name {0} is already taken.   A user with that external login already exists.   Email '{0}' is invalid.   Invalid token.   User name {0} is invalid, can only contain letters or digits.   Lockout is not enabled for this user.   No IUserTokenProvider is registered.   No IUserTwoFactorProvider for '{0}' is registered.   Incorrect password.   Passwords must have at least one digit ('0'-'9').   Passwords must have at least one lowercase ('a'-'z').   Passwords must have at least one non letter or digit character.   Passwords must have at least one uppercase ('A'-'Z').   Passwords must be at least {0} characters.   {0} cannot be null or empty.   Role {0} does not exist.   Store does not implement IQueryableRoleStore<TRole>.   Store does not implement IQueryableUserStore<TUser>.   Store does not implement IUserClaimStore<TUser>.   Store does not implement IUserConfirmationStore<TUser>.   Store does not implement IUserEmailStore<TUser>.   Store does not implement IUserLockoutStore<TUser>.   Store does not implement IUserLoginStore<TUser>.   Store does not implement IUserPasswordStore<TUser>.   Store does not implement IUserPhoneNumberStore<TUser>.   Store does not implement IUserRoleStore<TUser>.   Store does not implement IUserSecurityStampStore<TUser>.   Store does not implement IUserTwoFactorStore<TUser>.   User already has a password set.   User already in role.   UserId not found.   User {0} does not exist.   User is not in role.  
  2. J’ai créé une classe ‘IdentityResultErrorMessages.cs’:

     public class IdentityResultErrorMessages { public static List GetResourceEquivalent(IEnumerable errors) { List errorList = new List(); if (errors != null) { foreach (Ssortingng 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(Ssortingng.Format(IdentityErrors.DuplicateEmail, error.Replace("Email '", "").Replace("' is already taken.", ""))); } else if (error.StartsWith("Name ") && error.EndsWith(" is already taken.")) { errorList.Add(Ssortingng.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(Ssortingng.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(Ssortingng.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(Ssortingng.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(Ssortingng.Format(IdentityErrors.PasswordTooShort, error.Replace("Passwords must be at least ", "").Replace(" characters.", ""))); } else if (error.EndsWith(" cannot be null or empty.")) { errorList.Add(Ssortingng.Format(IdentityErrors.PropertyTooShort, error.Replace(" cannot be null or empty.", ""))); } else if (error.StartsWith("Role ") && error.EndsWith(" does not exist.")) { errorList.Add(Ssortingng.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(Ssortingng.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. J’ai modifié la méthode AddErrors du contrôleur comme suit:

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

Maintenant, je peux créer des fichiers de ressources pour les autres contenus linguistiques que je souhaite diffuser sur mon site Web.

Ce problème me gênait depuis un certain temps déjà, alors j’ai essayé de trouver quelque chose de générique, car la solution avec l’installation d’Identity.Core pour une culture particulière ne fonctionne que si le paquet est disponible du tout 🙂

Voici comment j’ai réalisé la localisation appropriée:

  1. Considéré l’implémentation de Microsoft.AspNet.Identity.PasswordValidator utilisant dotPeak qui est utilisé par défaut dans ApplicationUserManager ,
  2. Puis je suis venu avec ma propre implémentation de la class CustomPasswordValidator : PasswordValidator et class CustomPasswordValidator : PasswordValidator la méthode ValidateAsync pour ne pas renvoyer IdentityResult avec des messages d’erreur, mais plutôt avec les “codes” de ces messages d’erreur tous préfixés par la chaîne “CustomValidator”.
  3. Ensuite, dans AddErrors j’ai modifié AddErrors qui est appelé depuis Register post pour fournir des messages d’erreur localisés à partir de mes propres fichiers de ressources basés sur des codes d’erreur.

Voici la classe CustomPasswordValidator et la classe utilitaire PasswordValidatorCodes contenant des codes d’erreur et une méthode permettant de récupérer les messages d’erreur localisés en fonction de ces codes (AccountSsortingng étant un fichier de ressources):

 public static class PasswordValidatorCodes { public const ssortingng ErrorCodePrefix = "CustomPassword"; public const ssortingng PasswordTooShort = ErrorCodePrefix + "TooShort"; public const ssortingng PasswordRequireNonLetterOrDigit = ErrorCodePrefix + "RequireNonLetterOrDigit"; public const ssortingng PasswordRequireDigit = ErrorCodePrefix + "RequireDigit"; public const ssortingng PasswordRequireLower = ErrorCodePrefix + "RequireLower"; public const ssortingng PasswordRequireUpper = ErrorCodePrefix + "RequireUpper"; public static ssortingng GetLocalizedMessageForCode(ssortingng code) { switch (code) { case PasswordTooShort: return ssortingng.Format(AccountSsortingngs.ValidationPasswordTooShort, CustomPasswordValidator.RequiredPasswordLength); case PasswordRequireNonLetterOrDigit: return AccountSsortingngs.ValidationPasswordRequireNonLetterOrDigit; case PasswordRequireDigit: return AccountSsortingngs.ValidationPasswordRequireDigit; case PasswordRequireLower: return AccountSsortingngs.ValidationPasswordRequireLower; case PasswordRequireUpper: return AccountSsortingngs.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 ValidateAsync(ssortingng item) { if (item == null) throw new ArgumentNullException("item"); var list = new List(); if (ssortingng.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)); } } 

Et voici la méthode AccountController.AddErrors modifiée. Comme vous pouvez le constater, j’ajoute une erreur au modèle pour la propriété Password car si le Password ne Password pas la validation, je souhaite que le message d’erreur s’affiche dans le champ Password et non dans le résumé de validation. C’est la seule raison pour laquelle mon CustomPasswordValidator génère des codes d’erreur plutôt que des messages d’erreur directement:

 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(ssortingng.Empty, error); } } 

Enfin, n’oubliez pas de modifier le fichier IdentityConfig , à savoir:

 manager.PasswordValidator = new CustomPasswordValidator(); 

METTRE À JOUR:

Seulement maintenant j’ai remarqué que Marselus Chia (voir les autres réponses) a trouvé la solution similaire, sauf pour le VB.

Laissez-moi partager avec vous ce que j’ai fait pour accomplir cela en espagnol. Là, vous pouvez personnaliser les messages facilement!

ssortingng Errores = result.Errors.FirstOrDefault(); Errores = Errores.Replace("Name " + Email.Text + " is already taken.", "- El mail " + Email.Text + " ya fue registrado. Intente recuperar la clave.
"); Errores = Errores.Replace("Passwords must be at least 6 characters.", "- La clave debe contener por lo menos 6 caracteres.
"); 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.
"); 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).
"); Errores = Errores.Replace("Passwords must have at least one uppercase ('A'-'Z').", "- La clave debe contener al menos una letra (entre A y Z).
"); ErrorMessage.Text = "Errores:

" + Errores;

Ma solution consiste à créer une nouvelle classe de validation de mot de passe personnalisée hérite de Microsoft.AspNet.Identity.PasswordValidator, Substitue le ValidateAsync qui envoie le message d’erreur. Personnalisez le message d’erreur ici et ça marche pour moi …

Ces classes supposent que vous avez un validateur de noms de fichiers de ressources global. Le script de ces classes et l’exemple de fichier de ressources se trouvent ici. Identité ASP.NET – Exemple de code Codeplex

Voici mon exemple de code de travail dans vb.net


 Imports System.Threading.Tasks Imports Microsoft.AspNet.Identity Namespace MyNameSpace Public Class MyPasswordValidator Inherits PasswordValidator Public Overrides Function ValidateAsync(item As Ssortingng) As Task(Of IdentityResult) Dim errorMessage As Ssortingng = Ssortingng.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 Ssortingng.IsNullOrWhiteSpace(item) AndAlso item.Length >= Me.RequiredLength Then bolminChar = True Else bolminChar = False errorMessage = Ssortingng.Format(CultureInfo.CurrentCulture, Resources.validator.PasswordTooShort & "
", 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 & ".
" End If End If If Me.RequireLowercase Then Dim LCrex As New Regex("^(?=.*[az]).+$") Dim LCMatch As Match = LCrex.Match(item) If LCMatch.Success Then bolminLcase = True Else bolminLcase = False errorMessage &= Resources.validator.PasswordRequireLower & "
" 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 & "
" End If End If If Me.RequireUppercase Then Dim UCrex As New Regex("^(?=.*[AZ]).+$") Dim UCMatch As Match = UCrex.Match(item) If UCMatch.Success Then bolminUCase = True Else bolminUCase = False errorMessage &= Resources.validator.PasswordRequireUpper & "
" 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 Ssortingng() {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 Ssortingng)() 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 Ssortingng)) If Ssortingng.IsNullOrWhiteSpace(User.UserName) Then errors.Add(Ssortingng.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(Ssortingng.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(Ssortingng.Format(CultureInfo.CurrentCulture, Resources.validator.DuplicateName, User.UserName)) End If End If End Sub Private Sub ValidateEmail(User As ApplicationUser, errors As List(Of Ssortingng)) Dim email As Ssortingng = Ssortingng.Empty If User.Id > 0 Then email = _manager.GetEmail(User.Id) End If If Ssortingng.IsNullOrWhiteSpace(email) Then errors.Add(Ssortingng.Format(CultureInfo.CurrentCulture, Resources.validator.PropertyTooShort, "Email")) Return End If Try Dim m As New MailAddress(email) Catch ex As Exception errors.Add(Ssortingng.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(Ssortingng.Format(CultureInfo.CurrentCulture, Resources.validator.DuplicateName, email)) End If End Sub End Class

Remember to update the setting in your identityConfig.vb file to used these class.

My solution was a little bit dirty but It works as expected. The idea is to assign all the errors that the IdentityResult object result brings when we register a new user:

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

To a new one that we will create. First, we need to create a List that will contain our custom errors:

 var erroresEspanol = new List(); 

Then, we need to iterate trough the errors inside result and add a new custom error for every one of them depending on which was the cause of it (Duplicate user, email, etc.):

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

So after that we just create a new IdentityResult object:

 var resultado = new IdentityResult(erroresEspanol); 

And pass it to the AddErrors method at the end of our Register action:

 AddErrors(resultado); 

Having come across the same problem one can provide your own resource files to achieve this. Of course it requires a bit of reflection hacking! First you will need to be running with full security, ie set in your web.config:

     ... 

Next in your app start up code:

 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)); 

Travail terminé!

Here is Gerardo Grignoli’s answer with French translation

 ///  ///  /// Service to enable localization (french) for application facing identity errors. ///  public class FrenchIdentityErrorDescriber : IdentityErrorDescriber { ///  public override IdentityError DefaultError() => new IdentityError { Code = nameof(DefaultError), Description = "Une erreur inconnue est survenue." }; ///  public override IdentityError ConcurrencyFailure() => new IdentityError { Code = nameof(ConcurrencyFailure), Description = "Erreur de concurrence simultanée optimiste, l'object a été modifié." }; ///  public override IdentityError PasswordMismatch() => new IdentityError { Code = nameof(PasswordMismatch), Description = "Mot de passe incorrect." }; ///  public override IdentityError InvalidToken() => new IdentityError { Code = nameof(InvalidToken), Description = "Jeton invalide." }; ///  public override IdentityError LoginAlreadyAssociated() => new IdentityError { Code = nameof(LoginAlreadyAssociated), Description = "Un utilisateur avec ce nom de compte existe déjà." }; ///  public override IdentityError InvalidUserName(ssortingng userName) => new IdentityError { Code = nameof(InvalidUserName), Description = $"Le nom de compte '{userName}' est invalide. Seuls les lettres et chiffres sont autorisés." }; ///  public override IdentityError InvalidEmail(ssortingng email) => new IdentityError { Code = nameof(InvalidEmail), Description = $"L'email '{email}' est invalide." }; ///  public override IdentityError DuplicateUserName(ssortingng userName) => new IdentityError { Code = nameof(DuplicateUserName), Description = $"Le nom de compte '{userName}' est déjà utilisé." }; ///  public override IdentityError DuplicateEmail(ssortingng email) => new IdentityError { Code = nameof(DuplicateEmail), Description = $"L'email '{email} est déjà utilisée." }; ///  public override IdentityError InvalidRoleName(ssortingng role) => new IdentityError { Code = nameof(InvalidRoleName), Description = $"Le nom du rôle '{role}' est invalide." }; ///  public override IdentityError DuplicateRoleName(ssortingng role) => new IdentityError { Code = nameof(DuplicateRoleName), Description = $"Le nom du rôle '{role}' est déjà utilisé." }; ///  public override IdentityError UserAlreadyHasPassword() => new IdentityError { Code = nameof(UserAlreadyHasPassword), Description = "L'utilisateur a déjà un mot de passe." }; ///  public override IdentityError UserLockoutNotEnabled() => new IdentityError { Code = nameof(UserLockoutNotEnabled), Description = "Le verouillage n'est pas activé pour cet utilisateur." }; ///  public override IdentityError UserAlreadyInRole(ssortingng role) => new IdentityError { Code = nameof(UserAlreadyInRole), Description = $"L'utilisateur a déjà le rôle '{role}'." }; ///  public override IdentityError UserNotInRole(ssortingng role) => new IdentityError { Code = nameof(UserNotInRole), Description = $"L'utilisateur n'a pas le rôle '{role}'." }; ///  public override IdentityError PasswordTooShort(int length) => new IdentityError { Code = nameof(PasswordTooShort), Description = $"Le mot de passe doit contenir au moins {length} caractères." }; ///  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." }; ///  public override IdentityError PasswordRequiresDigit() => new IdentityError { Code = nameof(PasswordRequiresDigit), Description = "Le mot de passe doit contenir au moins un chiffre ('0'-'9')." }; ///  public override IdentityError PasswordRequiresLower() => new IdentityError { Code = nameof(PasswordRequiresLower), Description = "Le mot de passe doit contenir au moins un charactère minuscule ('a'-'z')." }; ///  public override IdentityError PasswordRequiresUpper() => new IdentityError { Code = nameof(PasswordRequiresUpper), Description = "Le mot de passe doit contenir au moins un charactère majuscule ('A'-'Z')." }; } 

I managed to find a solution to create localized version of AspNet.Identity for cultures that no ready-to-use package is available for. Les étapes sont les suivantes:

  1. Download the source code from GitHub and open the src/Microsoft.AspNet.Identity.Core project in visual studio.
  2. Add a new item (Resource file) to the project. Name it Resources.aa-BB.resx which aa-BB is the culture you need to localize the assembly for. eg.: Resources.fa-IR.resx .
  3. Open the new created file and copy resource items from Resources.resx to it.
  4. Localize the texts as you want.
  5. Construire le projet
  6. Go to the bin folder and under the Debug or Release directory you will see a folder named aa-BB (the culture you entered before). Copy the folder to the bin directory of your project.
  7. Make the changes that @1AmirJalali said ( this post ).
  8. Bien joué! Localization is complete. Try to share your localized package 🙂

Hi Here My Solution to to translate identity errors:

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

Exemple