我想使用自定義操作篩選器來處理來自我的服務類的特定異常,以填充模型狀態並返回視圖。如何在模型狀態錯誤中使用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中工作。如果我能弄清楚,那麼這種方法可能會奏效。
謝謝。我試着按照那篇文章使用ModelStateWrapper的方式,結果是Unity IoC很痛苦。我無法弄清楚如何將Controller.ModelState注入到我的服務層。如果我從構造函數注入到服務定位器,我可以做到這一點,但我不想爲此轉換到服務定位器。我看了,我沒有找到任何優雅的解決方案(其中大多數似乎黑客或複雜的方式)。 – 2011-03-28 18:02:42
我已更新我的帖子w /有關此更多信息。好奇看看是否有一種方法可以使用構造函數注入來實現這個功能。 – 2011-06-23 15:22:11
該文章的方法要求您手動檢查每個服務方法的真實性,並且不提供任何特定的錯誤信息,只是「通過或失敗」。另外,如果你在一個動作中調用多個服務,或者如果一個服務調用另一個服務,你必須檢查堆棧中的真實性。傑拉德的原始方法,雖然需要嘗試捕捉,但更優雅的海事組織。 – 2013-01-25 18:59:13