如何避免在控制器中使用try ... catch?

4
我尝试在应用程序的较低层处理异常,因为它们可以被处理(记录日志)。然而,有些错误应该使应用程序崩溃,比如参数为空的情况下,我会抛出ArgumentNullException。
如果考虑到调用服务层的控制器层。我想避免服务层抛出异常,因为我希望在这里处理所有异常(记录日志),但是我感觉在这种情况下这是不可能的(比如空值情况)。
那么避免在控制器中使用try...catch的最佳方法是什么?或者我真的应该在控制器中使用try...catch?
2个回答

9

我更喜欢在Application_Error方法中处理所有未处理的异常(不应该发生的事情)。您可以在其中记录异常并根据其性质显示适当的错误视图。

像自定义模型绑定器、验证器、操作过滤器等都可以允许拦截一些异常条件,以避免在控制器中到处使用try/catch导致混乱。

对于我打算处理的所有内容,例如业务错误等,使用try/catch是没有问题的,甚至更好的做法是使用if语句,并让服务层通知您某些操作是否成功或失败(TryXXX模式)。

因此,像往常一样,您的问题的答案是:这取决于各种因素,当然还有许多可能的解决方案,包括您的应用程序组织方式、服务层组织方式、可能发生的潜在错误、您希望明确处理的错误等等。


4

为了协作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,因为对于我来说,这使得分离不同的功能更容易。 (例如日志记录,检查应用程序是否能够处理等)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接