在ASP.NET Core MVC中使用唯一的电子邮件或唯一的用户名注册



我正在开发一个系统,该系统应该允许用户通过唯一的用户名或唯一的电子邮件进行注册。两者都可以注册。

我使用的是经过一些修改的默认身份页面,这里是注册代码的示例:

public class InputModel
{
//[Required] //Validated in server side based on role
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
//[Required] //Validated in server side based on role
[Display(Name = "Username")]
public string UserName { get; set; }
[Required]
[Display(Name = "Name")]
public string Name { get; set; }
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
string username = Input.UserName ?? Input.Email;
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = username,
Email = Input.Email,
Name = Input.Name,
};
}
}

基本上,如果用户输入了用户名,则"用户名"列将为Input.username。如果没有用户名(只有电子邮件(,用户名=输入.电子邮件,因为它显然不能为空。现在,用户名和电子邮件都是相同的默认值。

示例:

用户名:a@a,电子邮件:a@a>gt;无用户名

用户名:xyz,电子邮件:null、>gt;无电子邮件

用户名:abc,电子邮件:a@b、>gt;用户输入了用户名和电子邮件

目前,用户名始终是唯一的,并且始终是必需的(由身份而非用户要求(,但电子邮件的情况并非如此,它可以按预期为null,但它不是唯一的,我在startup.cs中添加了这一行以获得唯一性:

services.AddIdentity<IdentityUser, IdentityRole>(options => {
options.User.RequireUniqueEmail = true;
})

但现在它不能为空,它给出了这个验证错误:

电子邮件"无效。

请尝试为电子邮件实现一个将空字符串转换为null的setter

我在startup.cs中添加了这一行以获得唯一性:options.User.RequireUniqueEmail = true;

,但现在它不能为空,它给出了以下验证错误:Email '' is invalid.

UserManager<TUser>.CreateAsync方法的源代码中,我们可以发现它会在保存用户之前将ValidateUserAsync方法调用给有效的用户。

var result = await ValidateUserAsync(user);

ValidateUserAsync方法的代码中,我们可以发现它调用了另一个方法ValidateAsync,如下所示。

var result = await v.ValidateAsync(this, user);

ValidateAsync方法中,如果我们将RequireUniqueEmail配置为true,则通过调用ValidateEmail方法将有效当前用户的电子邮件。

if (manager.Options.User.RequireUniqueEmail)
{
await ValidateEmail(manager, user, errors);
}

转到ValidateEmail方法的定义,我们可以很容易地发现它会检查email参数是null还是System.String.Empty,或者值是否只由空格字符组成。

// make sure email is not empty, valid, and unique
private async Task ValidateEmail(UserManager<TUser> manager, TUser user, List<IdentityError> errors)
{
var email = await manager.GetEmailAsync(user);
if (string.IsNullOrWhiteSpace(email))
{
errors.Add(Describer.InvalidEmail(email));
return;
}
if (!new EmailAddressAttribute().IsValid(email))
{
errors.Add(Describer.InvalidEmail(email));
return;
}
var owner = await manager.FindByEmailAsync(email);
if (owner != null &&
!string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user)))
{
errors.Add(Describer.DuplicateEmail(email));
}
}

您可以尝试使用FindByNameAsync验证电子邮件或用户名是否已经存在,或者使用UserManager验证FindByEmailAsync。如果返回为null,则表示用户名/电子邮件还不存在。以下是示例方法:

//private readonly UserManager<IdentityUser> _userManager ;
var isUniqueUserName = await _userManager.FindByNameAsync(UserNameFromInput)==null;

var isUniqueEmail = await _userManager.FindByEmailAsync(EmailFromInput) == null;

if (!isUniqueUserName || !isUniqueEmail) 
{
if(!isUniqueUserName)
ModelState.AddModelError("UserName", "UserName already exist.");
if(!isUniqueEmail)
ModelState.AddModelError("Email", "Email already exist.");
return View(registerViewModel);
}

相关内容

最新更新