asp.net标识用户名是唯一的

本文关键字:唯一 用户 net 标识 asp | 更新日期: 2023-09-27 17:58:04

我读到了关于Microsoft中用户身份的文章,并试图将它们应用到我的MVC5应用程序中。

据我所知,Id是密钥,而userName不是密钥,定义说它可以为null,所以我在问自己。。。为什么在MVC5项目模板中,当您输入一个已经存在的用户名时,您会收到一条错误消息??

我试图访问用户名验证,但无法。

以下是数据库定义:

CREATE TABLE [dbo].[AspNetUsers] (
    [Id]            NVARCHAR (128) NOT NULL,
    [UserName]      NVARCHAR (MAX) NULL,

这是IdentityUser的定义,注意(无验证):

namespace Microsoft.AspNet.Identity.EntityFramework
{
    public class IdentityUser : IUser
    {
        public IdentityUser();
        public IdentityUser(string userName);
        public virtual ICollection<IdentityUserClaim> Claims { get; }
        public virtual string Id { get; set; }
        public virtual ICollection<IdentityUserLogin> Logins { get; }
        public virtual string PasswordHash { get; set; }
        public virtual ICollection<IdentityUserRole> Roles { get; }
        public virtual string SecurityStamp { get; set; }
        public virtual string UserName { get; set; }
    }
}

在注册时,调用UserManager.CreateAsync方法,定义如下:

     public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser() { UserName = model.UserName };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    await SignInAsync(user, isPersistent: false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    AddErrors(result);
                }
            }
            // If we got this far, something failed, redisplay form
            return View(model);
        }

这是我关于CreateAsync:的最后一件事

public virtual Task<IdentityResult> CreateAsync(TUser user, string password);

我在代码中没有看到验证,但它不允许您输入现有的用户名。

我认为了解这是如何工作的将改善我对asp.net身份概念的体验,并将改进我的代码。

非常感谢任何指导

asp.net标识用户名是唯一的

这发生在IdentityDbContext<TUser>,ApplicationDbContext可能从中继承。它重写DbContext的ValidateEntity方法来进行检查。查看此反编译代码:

    protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        if ((entityEntry != null) && (entityEntry.State == EntityState.Added))
        {
            TUser user = entityEntry.Entity as TUser;
            if ((user != null) && this.Users.Any<TUser>(u => string.Equals(u.UserName, user.UserName)))
            {
                return new DbEntityValidationResult(entityEntry, new List<DbValidationError>()) { ValidationErrors = { new DbValidationError("User", string.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateUserName, new object[] { user.UserName })) } };
            }
            IdentityRole role = entityEntry.Entity as IdentityRole;
            if ((role != null) && this.Roles.Any<IdentityRole>(r => string.Equals(r.Name, role.Name)))
            {
                return new DbEntityValidationResult(entityEntry, new List<DbValidationError>()) { ValidationErrors = { new DbValidationError("Role", string.Format(CultureInfo.CurrentCulture, IdentityResources.RoleAlreadyExists, new object[] { role.Name })) } };
            }
        }
        return base.ValidateEntity(entityEntry, items);
    }

如果你不想要这种行为,你可以直接从DbContext继承。

当我查看ASP.NET Identity的示例时(https://www.nuget.org/packages/Microsoft.AspNet.Identity.Samples)我注意到他们使用的UserValidator默认设置为RequireUniqueEmail = true;

该示例使用以下代码将RequireUniqueEmail属性设置为true。

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        return manager;
    }

也许这就是用户名在MVC应用程序中是唯一的原因。尝试将属性设置为false!?