如何判断哪个控制器抛出异常

时间:2018-01-18 20:56:58

标签: error-handling controller asp.net-core-mvc asp.net-core-2.0

我想创建一个错误处理中间件来处理与页面请求不同的AJAX请求。如果控制器中的特定方法用于提供对AJAX请求的响应,我想在抛出异常时返回JSON响应。对于任何失败的页面请求,我将重定向到标准错误页面。

我必须要做的一个想法是使用自定义属性。理论上,我可以设置是否应该有JSON或重定向错误处理。但是,我不知道如何告诉控制器是什么意思,所以我可以尝试阅读自定义属性。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class ExceptionHandlerAttribute : Attribute
{
    public ExceptionOutputMethod OutputMethod { get; private set; }

    public ExceptionHandlerAttribute(ExceptionOutputMethod method)
    {
        OutputMethod = method;
    }
}

public enum ExceptionOutputMethod {
    /// <summary>
    /// For AJAX calls to your API you can return a JSON error object
    /// </summary>
    JSON,

    /// <summary>
    /// For failed page renders use this to redirect to a custom error page
    /// </summary>
    Redirect
};

public class HomeController : Controller
{
    [ExceptionHandler(ExceptionOutputMethod.Redirect)]
    public IActionResult Index()
    {
        throw new Exception("Global handler will redirect to error page");
        return View();
    }

    [ExceptionHandler(ExceptionOutputMethod.JSON)]
    public ExampleObject GetAjaxExample()
    {
        throw new Exception("Create JSON response from global handler");
        return new ExampleObject();
    }
}

任何人都知道如何判断哪个控制器引发了异常?或者,我可以找到一种方法来为每种类型配置所有路径,然后根据请求进行查找。然而,这听起来像设置和维护很多工作,我希望新开发人员更容易拾取和使用。

1 个答案:

答案 0 :(得分:2)

您可以使用ExceptionFilterAttribute来捕获MVC操作中的异常。这是一个起点:

public class GlobalExceptionCatcher : ExceptionFilterAttribute
{

    private readonly IHostingEnvironment _hostingEnvironment;
    private readonly ILogger<GlobalExceptionCatcher> _logger;

    public GlobalExceptionCatcher(
    IHostingEnvironment hostingEnvironment,
    IModelMetadataProvider modelMetadataProvider,
    ILogger<GlobalExceptionCatcher> logger)
    {
        _hostingEnvironment = hostingEnvironment;
        _logger = logger;
    }

    public override void OnException(ExceptionContext context)
    {
        if (!_hostingEnvironment.IsDevelopment())
        {
            // take some action if needed.
            return;
        }

        var ad = context.ActionDescriptor as ControllerActionDescriptor;
        var controllerName = ad.ControllerName;

       //go do whatever it is you need to do.
       //you can also set the ExceptionHandled property to "mark as read" :)

    }

}

然后进入你的创业公司:

    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(GlobalExceptionCatcher));
    });

如果您希望中间件捕获任何异常,那么您可以使用此过滤器作为实用程序将数据添加到MVC操作中发生的异常中间件。使用HttpContext.Items属性添加要在中间件中获取的信息。

但是,为了确保您的中间件在返回的路上遇到异常,请确保您没有将异常标记为true并正确测试。