【发布时间】:2016-10-14 04:54:24
【问题描述】:
我正在尝试在我的 ASP.NET MVC 项目中实现不断变化的电子邮件功能。我的应用程序的性质要求每个用户的电子邮件地址都是唯一的。因此,在我的 ASP.NET Identity 实现中,我创建了自定义 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 Identity 的 UserStore 的自定义实现,其中包括更改/设置电子邮件地址的功能。如果电子邮件地址已被现有用户实体使用,则此类将引发 ArgumentException。而这个异常应该在AccountController类的方法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 抛出的异常没有被控制器方法捕获。为什么会这样?它与“等待”声明有关吗?有人可以帮忙吗?
【问题讨论】:
-
检查this 一个。也许 Rob Church 的回答可能对你有所帮助
-
@Qsprec:不,我认为 Rob Church 的回答没有帮助。我把CheckExistingUser()的签名改成返回Task,抛出的异常依然没有被捕获。所有调用堆栈也返回任务,我不认为这是问题所在......
-
异常是否包含在聚合异常中?如果将 catch(ArgumentException ae) 更改为 catch(Exception e) 会有所不同吗?
-
好吧,我改成捕获基本异常 System.Exception,实际上并没有什么区别。
标签: c# asp.net-mvc exception-handling asp.net-mvc-5 asp.net-identity