【问题标题】:How to avoid using try ... catch in controllers?如何避免在控制器中使用 try ... catch?
【发布时间】:2012-02-02 09:25:09
【问题描述】:
我尝试在应用程序的较低层处理我的异常,因为它们可以被处理(记录它们)。但是,如果参数为 NULL 并且不应该在这种情况下我会抛出 ArgumentNullException。
如果您考虑调用服务层的控制器层。我想避免服务层抛出异常,因为我想在这里处理所有异常(日志记录),但我觉得在这种情况下这是不可能的(比如 NULL 情况)。
那么在控制器中避免使用 try...catch 的最佳方法是什么?或者我真的应该在控制器中使用 try...catch 吗?
【问题讨论】:
标签:
asp.net-mvc-3
try-catch
【解决方案1】:
就 Darin Dimitrov 的回答进行合作
诸如自定义模型绑定器、验证器、操作过滤器之类的东西......还有
可以允许拦截一些异常情况以避免
到处都用 try/catch 污染你的控制器。
这是我喜欢的。你可以创建一个IExceptionFilter,看起来像这样:
public class ExceptionLoggingFilter : IExceptionFilter
{
private ILogger _logger;
public ExceptionLoggingFilter(ILogger logger)
{
_logger = logger;
}
public void OnException(ExceptionContext context)
{
Exception ex = context.Exception;
if (_logger != null)
{
_logger.log(ex)
}
}
context.ExceptionHandled = true; //see note
}
注意:如果您不想重新抛出异常,您可以添加它。如果您只想记录,但有另一个过滤器来处理它,您可以删除该行。
然后在你的 Global.aspx 中你会这样做:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ExceptionLoggingFilter(new Log4NetLogger()));
}
我更喜欢创建过滤器而不是创建Application_Error,因为对我来说,它可以更轻松地分离不同的功能。 (例如日志记录、检查应用程序是否可以处理等)
【解决方案2】:
我更喜欢在Application_Error 方法中处理所有未处理的异常(不应该发生的事情)。您可以在此处记录异常并根据其性质显示正确的错误视图。
诸如自定义模型绑定器、验证器、动作过滤器……也可以允许拦截一些异常情况,以避免到处使用 try/catch 污染您的控制器。
对于我打算处理的所有事情,例如业务错误等...使用 try/catch 没有任何问题,甚至更好地使用 if 语句并让服务层通知您某些操作是成功还是失败( TryXXX 模式。)
因此,与往常一样,您的问题的答案是:视情况而定。这取决于您的应用程序的组织方式,服务层的组织方式,可能发生的潜在错误,您希望明确处理的错误,......很多,很多,很多因素,当然还有很多,很多,许多可能的解决方案。