我正在尝试在ASP.NET MVC项目中实现更改电子邮件功能。我的应用程序的性质要求电子邮件地址对每个用户都是唯一的。因此,在我的ASP.NET身份实现中,我创建了自定义SetEmailAsync()方法,以便在电子邮件地址已被使用时抛出ArgumentException。实施如下所示:
class IdentityUserStore
{
// Unrelated methods omitted for simplicity
public Task SetEmailAsync(ApplicationUser User, string email)
{
var user = UnitOfWork.Users.FindByEmail(email);
CheckExistingUser(user);
user.Email = email;
return Task.FromResult(0);
}
private void CheckExistingUser(User user){
if (user != null)
{
throw new ArgumentException("The Email Address is already in use.");
}
}
}
class AccountController : Controller
{
// Unrelated Methods omitted for simplicity
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Email(ChangeEmailFormModel model)
{
ViewBag.ReturnUrl = Url.Action("Email");
if (ModelState.IsValid)
{
try
{
var result = await userManager.SetEmailAsync(User.Identity.GetUserId(), model.NewEmail);
if (result.Succeeded)
{
return RedirectToAction("Email", new { Message = ManageMessageId.ChangeEmailSuccess });
}
else
{
result.Errors.Each(error => ModelState.AddModelError("", error));
}
}
catch(ArgumentException ae)
{
ModelState.AddModelError("", ae.Message);
}
}
return View();
}
}
如您所见,IdentityUserStore是用于ASP.NET身份的UserStore的自定义实现,其中包括更改/设置电子邮件地址的功能。如果现有用户实体已在使用电子邮件地址,则此类将抛出ArgumentException。这个异常应该在AccountController类中被捕获&#39;方法Email(),但它没有被抓住。相反,它会抛出以下错误消息:
An exception of type 'System.ArgumentException' occurred in MVCApp.Application.dll but was not handled in user code
Additional information: The Email Address is already in use.
所以我完全糊涂了,我想如果抛出异常,客户端代码应该能够捕获并处理它。但是这没有发生,UserStore引发的异常没有被控制器方法捕获。为什么会这样?是否与等待&#39;有关?声明?有人可以帮忙吗?
答案 0 :(得分:0)
Identity framework为您提供了强制执行电子邮件唯一性的选项。这是在UserValidator<>
类中完成的,它是UserManager
的一部分:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
//.. other code
this.UserValidator = new UserValidator<ApplicationUser>(this)
{
RequireUniqueEmail = true,
};
}
这样可以防止设置重复的电子邮件。而且无需自己构建它。