控制器中的操作没有捕捉到异常

问题描述:

我希望有人能解释发生了什么。控制器中的操作没有捕捉到异常

我创建了一个存储库类“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”类中的任何其他函数抛入控制器内的任何异常。

任何帮助,将不胜感激。

+0

这是一个非常糟糕的方式来处理这样的错误是诚实的。你可以简单地做一些额外的检查,以确保你没有尝试插入重复的值。如果该值存在,那么返回一些东西并很好地处理它,而不是在任何地方抛出错误。与抛出异常相关的成本是 –

+0

我可以做到这一点,但我需要准备好捕捉任何类型的异常。无论我执行多少次验证,我的代码都必须准备好捕获任何异常。 –

您不是await方法Insert方法,因此您的操作无法捕捉任何异常。 Visual Studio应该给你一个警告消息,说明在这种方法中什么都没有被等待。你的代码改成这样:

await this.invoices.Insert(invoice); 

而且,你的资料库不应使用async void,它应该返回一个Task

+0

您正在回答不相关的问题...这是关于“为什么异步从异步void无法捕获”... –

+0

它是如何不相关? – DavidG

+0

我添加了“await”,但它用来标记错误。当你告诉我,并且“await”错误不再被标记时,我将返回更改为“Task”。有用。谢谢。 –