我想使用自定义操作筛选器来处理来自我的服务类的特定异常,以填充模型状态并返回视图。如何在模型状态错误中使用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