2017-07-28 112 views
0

我希望有人能解釋發生了什麼。控制器中的操作沒有捕捉到異常

我創建了一個存儲庫類「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

我可以做到這一點,但我需要準備好捕捉任何類型的異常。無論我執行多少次驗證,我的代碼都必須準備好捕獲任何異常。 –

回答

2

您不是await方法Insert方法,因此您的操作無法捕捉任何異常。 Visual Studio應該給你一個警告消息,說明在這種方法中什麼都沒有被等待。你的代碼改成這樣:

await this.invoices.Insert(invoice); 

而且,你的資料庫不應使用async void,它應該返回一個Task

+0

您正在回答不相關的問題...這是關於「爲什麼異步從異步void無法捕獲」... –

+0

它是如何不相關? – DavidG

+0

我添加了「await」,但它用來標記錯誤。當你告訴我,並且「await」錯誤不再被標記時,我將返回更改爲「Task」。有用。謝謝。 –