【问题标题】:How can customize Asp.net Identity 2 username already taken validation message?如何自定义 Asp.net Identity 2 用户名已采取验证消息?
【发布时间】:2015-02-23 16:10:56
【问题描述】:

如何自定义 Asp.net Identity 2 用户名已采用验证消息(名称 XYZ 已采用。)?谢谢

【问题讨论】:

  • 我认为您需要查看身份模型并确定是否有任何特殊属性。或查看帐户控制器
  • @qamar。在这种特殊情况下,您错了,因为所有消息都嵌入到身份资源中

标签: asp.net asp.net-mvc asp.net-mvc-5 asp.net-identity asp.net-identity-2


【解决方案1】:

嗯,我没有找到任何简单的解决方案来解决这个问题。简单地说,我的意思是修改属性/模型/控制器中的一些消息。

一种可能的解决方案是:

执行后

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

如果结果不成功,您可以检查它的错误属性“名称 XYZ 已被占用”。模式并将其替换为您的自定义消息。

另一种解决方案(这是我的首选方式)是编写一个自定义的UserValidation 类:

 /// <summary>
    ///     Validates users before they are saved to an IUserStore
    /// </summary>
    /// <typeparam name="TUser"></typeparam>
    public class CustomUserValidator<TUser> : UserValidator<TUser, string>
        where TUser : ApplicationUser
    {
        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="manager"></param>
        public CustomUserValidator(UserManager<TUser, string> manager) : base(manager)
        {
            this.Manager = manager;
        }

        private UserManager<TUser, string> Manager { get; set; }

        /// <summary>
        ///     Validates a user before saving
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public override async Task<IdentityResult> ValidateAsync(TUser item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            var errors = new List<string>();
            await ValidateUserName(item, errors);
            if (RequireUniqueEmail)
            {
                await ValidateEmail(item, errors);
            }
            if (errors.Count > 0)
            {
                return IdentityResult.Failed(errors.ToArray());
            }
            return IdentityResult.Success;
        }

        private async Task ValidateUserName(TUser user, List<string> errors)
        {
            if (string.IsNullOrWhiteSpace(user.UserName))
            {
                errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "Name"));
            }
            else if (AllowOnlyAlphanumericUserNames && !Regex.IsMatch(user.UserName, @"^[A-Za-z0-9@_\.]+$"))
            {
                // If any characters are not letters or digits, its an illegal user name
                errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.InvalidUserName, user.UserName));
            }
            else
            {
                var owner = await Manager.FindByNameAsync(user.UserName);
                if (owner != null && !EqualityComparer<string>.Default.Equals(owner.Id, user.Id))
                {
                    errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.DuplicateName, user.UserName));
                }
            }
        }

        // make sure email is not empty, valid, and unique
        private async Task ValidateEmail(TUser user, List<string> errors)
        {
            if (!user.Email.IsNullOrWhiteSpace())
            {
                if (string.IsNullOrWhiteSpace(user.Email))
                {
                    errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "Email"));
                return;
                }
                try
                {
                    var m = new MailAddress(user.Email);
                }
                catch (FormatException)
                {
                    errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.InvalidEmail, email));
                return;
                }
            }
            var owner = await Manager.FindByEmailAsync(user.Email);
            if (owner != null && !EqualityComparer<string>.Default.Equals(owner.Id, user.Id))
            {
                errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.DuplicateEmail, email));
            }
        }
    }

您可以看到所有正在使用的资源验证错误消息,因此通过在资源中指定自定义格式,您将能够自定义这些消息。

您可以在ApplicationUserManager 类,Create 方法中注册您的验证器:

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
{
   manager.UserValidator = new CustomUserValidator<ApplicationUser>(manager)
   {
       AllowOnlyAlphanumericUserNames = false,
       RequireUniqueEmail = true
   };
}

【讨论】:

  • 难以置信的是,您需要实现自己的验证器才能更改字符串。
  • 而且我什至看不到如何在不创建新的IdentityResult 的情况下替换错误消息,因为Errors 是只读的 IEnumerable。
  • 尝试此操作时,我收到错误 'Resources' is inaccessible due to its protection level。如果我检查 Microsoft.AspNet.Identity.Resources 类,它被标记为内部。
  • 已解决 'Resources' is inaccessible due to its protection level 此处:stackoverflow.com/questions/39123039/…
  • 您的答案(stackoverflow.com/questions/39123039/...)基本相同。您可能错过了这些行:Another solution (this is my preferred way) is to write a custom UserValidation class... You can see that for all the validation error messages Resources being used, So by specifying a custom format in your resources you will be able to customize those messages.
【解决方案2】:

这比接受的答案要容易得多。

添加一个class 并从IdentityErrorDescriber 继承它

public class AppErrorDescriber : IdentityErrorDescriber
    {
        public override IdentityError DuplicateUserName(string userName)
        {
            var error = base.DuplicateUserName(userName);
            error.Description = "This email address has already been registered. Please log in.";
            return error;
        }
    }

现在在你的 Startup.cs 中使用新类,就是这样。

services.AddDefaultIdentity<AppUser>(options => ... )
                .AddErrorDescriber<AppErrorDescriber>();

【讨论】:

  • 很好的解决方案!! PS如果你已经搭建了页面,服务应该添加到IdentityHostingStartup.cs
  • 迄今为止的最佳答案
【解决方案3】:

只需像这样自定义您的 AddErrors 方法:

private void AddErrors(IdentityResult result)
{
    foreach (var error in result.Errors)
    {
        if (error.StartsWith("Name"))
        {
            var NameToEmail= Regex.Replace(error,"Name","Email");
            ModelState.AddModelError("", NameToEmail);
        }
        else
        {
            ModelState.AddModelError("", error);
        }
    }
}

【讨论】:

    【解决方案4】:

    使用XLocalizer - Nuget 包进行本地化。 请参阅文档here

    【讨论】:

      【解决方案5】:

      将您自己的属性添加到ApplicationUser 类的简单方法,例如:

       public class AppUser:IdentityUser
        {
           public string MyUserName{get; set;}
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-20
        • 1970-01-01
        • 2019-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多