我想使用自定义操作过滤器来处理来自我的服务类的特定异常,以填充模型状态,然后返回视图。
例如,请使用我之前的代码:
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();
}
问题是,一旦动作过滤器处理错误,它就不会返回我的动作方法。我有点理解,为什么会发生这种情况。但我仍然想找到一种方法来做我想做的事。
这可能吗?
提前致谢。
更新
我在他的回答中尝试了article Darin provided的建议,但遇到了试图使用构造函数注入控制器模型状态的问题。
例如,如果你查看他们的Controllers \ ProductController.cs代码,他们有控制器的空构造函数使用服务定位器来创建服务,在那时传入控制器的ModelState:
public ProductController()
{
_service = new ProductService(new ModelStateWrapper(this.ModelState),
new ProductRepository());
}
但是如果你看一下注入的构造函数,它假定ModelState将被注入到服务的构造函数中:
public ProductController(IProductService service)
{
_service = service;
}
我不知道如何让CI与当前控制器的ModelState一起使用。如果我能弄清楚这一点,那么这种方法可能会奏效。
答案 0 :(得分:0)
您仍然可以返回相应的视图:
context.Result = new ViewResult
{
ViewName = context.RouteData.GetRequiredString("action")
};
您还可以查看following article,了解如何在服务层执行验证。