Jer*_*ose 5 asp.net-mvc exception-handling action-filter asp.net-mvc-3 asp.net-mvc-2
我想使用自定义操作过滤器来处理来自我的服务类的特定异常以填充模型状态,然后返回视图。
以我之前的代码为例:
public ActionResult SomeAction(SomeViewModel model)
{
try
{
_someService.SomeMethod(model);
}
catch (ServiceException ex)
{
ModelState.AddModelError(ex.Key, ex.ErrorMessage);
}
return View();
}
Run Code Online (Sandbox Code Playgroud)
基本上,它会调用一个服务,如果抛出 ServiceException,它就会知道模型数据存在问题,并将错误添加到 ModelState,然后返回视图。但是我注意到一些非常不干的模式,因为我在每个操作方法中都有相同的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后像这样简化我的操作方法:
public ActionResult SomeAction(SomeViewModel model)
{
_someService.SomeMethod(model);
return View();
}
Run Code Online (Sandbox Code Playgroud)
问题是,一旦动作过滤器处理了错误,它就不会返回到我的动作方法。我有点明白,在幕后,为什么会发生这种情况。但我仍然想找出一种方法来做我想做的事情。
这可能吗?
提前致谢。
更新:
我尝试了Darin在他的回答中提供的文章中的建议,但在尝试将构造函数注入与控制器的模型状态一起使用时遇到了问题。
例如,如果你查看他们的 Controllers\ProductController.cs 代码,他们有控制器的空构造函数,使用服务定位器来创建服务,此时传入控制器的 ModelState:
public ProductController()
{
_service = new ProductService(new ModelStateWrapper(this.ModelState),
new ProductRepository());
}
Run Code Online (Sandbox Code Playgroud)
但是如果你查看注入的构造函数,它假设 ModelState 将被注入到服务的构造函数中:
public ProductController(IProductService service)
{
_service = service;
}
Run Code Online (Sandbox Code Playgroud)
我不知道如何让 CI 与当前控制器的 ModelState 一起工作。如果我能弄清楚这一点,那么这种方法可能会奏效。
您仍然可以返回相应的视图:
context.Result = new ViewResult
{
ViewName = context.RouteData.GetRequiredString("action")
};
Run Code Online (Sandbox Code Playgroud)
您还可以查看以下文章,了解有关如何在服务层执行验证的替代方法。
归档时间: |
|
查看次数: |
3142 次 |
最近记录: |