You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core Identity中实现用户名注册登录(保留邮箱收集)

实现ASP.NET Core Identity 用户名+密码登录(同时保留邮箱收集)

1. 调整注册流程:同时收集用户名与邮箱

1.1 修改注册ViewModel(RegisterViewModel)

默认模板的RegisterViewModel通常只有邮箱、密码相关字段,需要添加用户名属性并配置验证规则:

public class RegisterViewModel
{
    [Required]
    [Display(Name = "用户名")]
    [StringLength(256, ErrorMessage = "{0} 长度至少为 {2} 个字符。", MinimumLength = 3)]
    public string UserName { get; set; }

    [Required]
    [EmailAddress]
    [Display(Name = "邮箱")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "{0} 长度至少为 {2} 个字符。", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "密码")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "确认密码")]
    [Compare("Password", ErrorMessage = "密码与确认密码不匹配。")]
    public string ConfirmPassword { get; set; }
}

1.2 更新注册视图(Register.cshtml)

在原有邮箱输入框前插入用户名输入区域,保留原有的邮箱、确认密码等字段:

<div class="form-group">
    <label asp-for="UserName"></label>
    <input asp-for="UserName" class="form-control" />
    <span asp-validation-for="UserName" class="text-danger"></span>
</div>

<div class="form-group">
    <label asp-for="Email"></label>
    <input asp-for="Email" class="form-control" />
    <span asp-validation-for="Email" class="text-danger"></span>
</div>

<div class="form-group">
    <label asp-for="Password"></label>
    <input asp-for="Password" class="form-control" />
    <span asp-validation-for="Password" class="text-danger"></span>
</div>

<div class="form-group">
    <label asp-for="ConfirmPassword"></label>
    <input asp-for="ConfirmPassword" class="form-control" />
    <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>

1.3 修改注册Post方法(AccountController/Register)

创建用户时同时赋值UserName和Email,避免默认用邮箱填充用户名的逻辑:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        // 手动初始化用户实体,分别设置用户名与邮箱
        var user = new IdentityUser { UserName = model.UserName, Email = model.Email };
        var result = await _userManager.CreateAsync(user, model.Password);
        
        if (result.Succeeded)
        {
            // 保留原有后续逻辑(如邮箱确认、自动登录等)
            await _signInManager.SignInAsync(user, isPersistent: false);
            return RedirectToAction(nameof(HomeController.Index), "Home");
        }
        
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }
    // 验证失败返回注册页
    return View(model);
}

2. 调整登录流程:使用用户名+密码验证

2.1 修改登录ViewModel(LoginViewModel)

将原有的Email字段替换为UserName:

public class LoginViewModel
{
    [Required]
    [Display(Name = "用户名")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "密码")]
    public string Password { get; set; }

    [Display(Name = "记住我?")]
    public bool RememberMe { get; set; }
}

2.2 更新登录视图(Login.cshtml)

把邮箱输入框替换为用户名输入框:

<div class="form-group">
    <label asp-for="UserName"></label>
    <input asp-for="UserName" class="form-control" />
    <span asp-validation-for="UserName" class="text-danger"></span>
</div>

<div class="form-group">
    <label asp-for="Password"></label>
    <input asp-for="Password" class="form-control" />
    <span asp-validation-for="Password" class="text-danger"></span>
</div>

<div class="form-group">
    <div class="checkbox">
        <label asp-for="RememberMe">
            <input asp-for="RememberMe" /> @Html.DisplayNameFor(m => m.RememberMe)
        </label>
    </div>
</div>

2.3 修改登录Post方法(AccountController/Login)

调用PasswordSignInAsync时传入用户名而非邮箱:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        // 使用用户名执行登录验证
        var result = await _signInManager.PasswordSignInAsync(
            model.UserName, 
            model.Password, 
            model.RememberMe, 
            lockoutOnFailure: true
        );
        
        if (result.Succeeded)
        {
            return LocalRedirect(returnUrl ?? Url.Content("~/"));
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
        }
        if (result.IsLockedOut)
        {
            return RedirectToAction(nameof(Lockout));
        }
        else
        {
            ModelState.AddModelError(string.Empty, "无效的登录尝试。");
            return View(model);
        }
    }
    // 验证失败返回登录页
    return View(model);
}

3. 额外注意事项

  • 用户名唯一性验证:可在注册前手动检查用户名是否已存在,避免重复:
    var existingUser = await _userManager.FindByNameAsync(model.UserName);
    if (existingUser != null)
    {
        ModelState.AddModelError("UserName", "该用户名已被使用。");
        return View(model);
    }
    
  • 邮箱确认逻辑:原有邮箱确认流程无需修改,因为Email字段已正确保存到用户实体中。
  • 用户信息展示:后续页面若需显示用户名,直接调用User.Identity.Name即可获取。

内容的提问来源于stack exchange,提问作者Massey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 18:37:39