3

我想使用自定義操作篩選器來處理來自我的服務類的特定異常,以填充模型狀態並返回視圖。如何在模型狀態錯誤中使用HandleError

例如,把我以前的代碼:

public ActionResult SomeAction(SomeViewModel model) 
{ 
    try 
    { 
     _someService.SomeMethod(model); 
    } 
    catch (ServiceException ex) 
    { 
     ModelState.AddModelError(ex.Key, ex.ErrorMessage); 
    } 

    return View(); 
} 

基本上,它會調用一個服務,如果ServiceException被拋出,就知道有問題瓦特/模型數據,並添加該錯誤給ModelState,然後只返回視圖。但是我注意到了一些非DRY類型的模式,因爲我在每個操作方法中都有相同的try/catch代碼。

所以,要幹一番了,我基本上創建了一個新HandleServiceError動作過濾器:

public class HandleServiceErrorAttribute : HandleErrorAttribute 
{ 
    public override void OnException(ExceptionContext context) 
    { 
     ((Controller)context.Controller) 
      .ModelState 
      .AddModelError(
       ((ServiceException)context.Exception).Key, 
       ((ServiceException)context.Exception).ErrorMessage 
      ); 
     context.ExceptionHandled = true; 
    } 
} 

然後簡化我的操作方法如下所示:

public ActionResult SomeAction(SomeViewModel model) 
{ 
    _someService.SomeMethod(model); 
    return View(); 
} 

問題是,一旦行動過濾器處理錯誤,它不會返回到我的操作方法。我有點理解爲什麼會發生這種情況。但我仍然想找出一條辦法去做我想做的事。

這可能嗎?

在此先感謝。

UPDATE:

我試圖從他的回答中article Darin provided的建議,但跑進嘗試使用構造器注入與控制器的模型狀態的問題。

例如,如果你看看他們的控制器\ ProductController.cs代碼,他們可以選擇使用服務定位器來創建服務控制器的空構造,通過在控制器的ModelState在這一點上:

public ProductController() 
{ 
    _service = new ProductService(new ModelStateWrapper(this.ModelState), 
            new ProductRepository()); 
} 

但是,如果你看看注入的構造,它假定的ModelState將注入的構造函數服務:

public ProductController(IProductService service) 
{ 
    _service = service; 
} 

我不知道怎麼去CI與電流控制器的ModelState中工作。如果我能弄清楚,那麼這種方法可能會奏效。

回答

0

您仍然可以返回相應的視圖:

context.Result = new ViewResult 
{ 
    ViewName = context.RouteData.GetRequiredString("action") 
}; 

您也可以看看的following article有關如何在服務層進行驗證的替代品。

+1

謝謝。我試着按照那篇文章使用ModelStateWrapper的方式,結果是Unity IoC很痛苦。我無法弄清楚如何將Controller.ModelState注入到我的服務層。如果我從構造函數注入到服務定位器,我可以做到這一點,但我不想爲此轉換到服務定位器。我看了,我沒有找到任何優雅的解決方案(其中大多數似乎黑客或複雜的方式)。 – 2011-03-28 18:02:42

+0

我已更新我的帖子w /有關此更多信息。好奇看看是否有一種方法可以使用構造函數注入來實現這個功能。 – 2011-06-23 15:22:11

+0

該文章的方法要求您手動檢查每個服務方法的真實性,並且不提供任何特定的錯誤信息,只是「通過或失敗」。另外,如果你在一個動作中調用多個服務,或者如果一個服務調用另一個服務,你必須檢查堆棧中的真實性。傑拉德的原始方法,雖然需要嘗試捕捉,但更優雅的海事組織。 – 2013-01-25 18:59:13

相關問題