控制器中的操作没有捕捉到异常
我希望有人能解释发生了什么。控制器中的操作没有捕捉到异常
我创建了一个存储库类“InvoicesRepository.cs”,用于管理列表,插入,更新,删除等“Invoice.cs”对象的所有逻辑。更清洁,更容易维护。
public class InvoicesRepository
{
protected MySQLContext db;
public InvoicesRepository(MySQLContext db)
{
this.db = db;
}
public async void Insert(Invoice obj)
{
this.db.Invoices.Add(obj);
await this.db.SaveChangesAsync();
// performing other tasks...
}
// other useful methods...
}
有一个“InvoicesController.cs”,包含我需要的所有操作。在这个控制器内部,我创建一个“InvoiceTepository”obj,然后用它将信息保存到数据库。而且,在每一个动作
public class InvoicesController : Controller
{
private InvoicesRepository invoices;
public InvoicesController()
{
this.invoices = new InvoicesRepository(new MySQLContext());
}
[HttpPost]
public async Task<ActionResult> Upload(Invoice invoice)
{
try
{
this.invoices.Insert(invoice);
}
catch (DbEntityValidationException ex)
{
foreach (var eve in ex.EntityValidationErrors)
{
foreach (var err in eve.ValidationErrors)
{
ModelState.AddModelError(err.PropertyName, err.ErrorMessage);
}
}
}
catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
{
ModelState.AddModelError("", ex.ToString());
}
catch (System.Data.Entity.Core.UpdateException ex)
{
ModelState.AddModelError("", ex.ToString());
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
ModelState.AddModelError("", ex.ToString());
}
catch (Exception ex)
{
ModelState.AddModelError("", ex.ToString());
}
return View();
}
// other useful action methods...
}
为了进行测试,我将已在数据库中的重复数据(唯一列)期待抛出一个异常,然后我的动作捕捉它,并显示正确的“发票”对象在视图中的错误,但...异常是“抛出”,但没有“抓住”。
我调试过,看看抛出了什么样的异常(包括它们的内部异常)并添加了所需的“捕获”,但仍然没有“捕获”异常。
如果我改变控制器直接使用“MySQLContext.cs”类来保存信息的异常被“逮住”的代码:
[HttpPost]
public async Task<ActionResult> Upload(Invoice invoice)
{
try
{
// this is "catched" ¿?
this.db.Invoices.Add(obj);
await this.db.SaveChangesAsync();
}
catch (Exception ex)
{
ModelState.AddModelError("", ex.ToString());
}
return View();
}
这究竟是为什么?我需要能够捕获我的“插入”或“InvoiceRepository”类中的任何其他函数抛入控制器内的任何异常。
任何帮助,将不胜感激。
您不是await
方法Insert
方法,因此您的操作无法捕捉任何异常。 Visual Studio应该给你一个警告消息,说明在这种方法中什么都没有被等待。你的代码改成这样:
await this.invoices.Insert(invoice);
而且,你的资料库不应使用async void
,它应该返回一个Task
您正在回答不相关的问题...这是关于“为什么异步从异步void无法捕获”... –
它是如何不相关? – DavidG
我添加了“await”,但它用来标记错误。当你告诉我,并且“await”错误不再被标记时,我将返回更改为“Task”。有用。谢谢。 –
这是一个非常糟糕的方式来处理这样的错误是诚实的。你可以简单地做一些额外的检查,以确保你没有尝试插入重复的值。如果该值存在,那么返回一些东西并很好地处理它,而不是在任何地方抛出错误。与抛出异常相关的成本是 –
我可以做到这一点,但我需要准备好捕捉任何类型的异常。无论我执行多少次验证,我的代码都必须准备好捕获任何异常。 –