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

相关问题