Error handling 如何判断哪个控制器引发了异常
我想创建一个错误处理中间件,它处理不同于页面请求的AJAX请求。如果控制器中的特定方法用于提供对AJAX请求的响应,我希望在抛出异常时返回JSON响应。对于任何失败的页面请求,我将重定向到标准错误页面 我必须这样做的一个想法是使用自定义属性。理论上,我可以设置是否应该使用JSON或重定向错误处理。但是,我不知道如何判断是哪个控制器抛出了错误,以便尝试读取自定义属性Error handling 如何判断哪个控制器引发了异常,error-handling,controller,asp.net-core-mvc,asp.net-core-2.0,Error Handling,Controller,Asp.net Core Mvc,Asp.net Core 2.0,我想创建一个错误处理中间件,它处理不同于页面请求的AJAX请求。如果控制器中的特定方法用于提供对AJAX请求的响应,我希望在抛出异常时返回JSON响应。对于任何失败的页面请求,我将重定向到标准错误页面 我必须这样做的一个想法是使用自定义属性。理论上,我可以设置是否应该使用JSON或重定向错误处理。但是,我不知道如何判断是哪个控制器抛出了错误,以便尝试读取自定义属性 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
[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();
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple=true)]
公共类例外HandlerAttribute:属性
{
public ExceptionOutputMethod OutputMethod{get;private set;}
公共例外HandlerAttribute(例外输出方法)
{
OutputMethod=方法;
}
}
公共枚举例外输出方法{
///
///对于对API的AJAX调用,可以返回JSON错误对象
///
JSON,
///
///对于失败的页面呈现,请使用此选项重定向到自定义错误页面
///
重新使用
};
公共类HomeController:控制器
{
[ExceptionHandler(ExceptionOutputMethod.Redirect)]
公共IActionResult索引()
{
抛出新异常(“全局处理程序将重定向到错误页”);
返回视图();
}
[ExceptionHandler(ExceptionOutputMethod.JSON)]
公共示例对象GetAjaxExample()
{
抛出新异常(“从全局处理程序创建JSON响应”);
返回新的ExampleObject();
}
}
有人知道如何判断哪个控制器引发了异常吗?或者,我可以找到一种方法为每种类型配置所有路径,然后根据请求进行查找。不过,这听起来需要进行大量的设置和维护工作,我希望新开发人员能够更容易地选择和使用它。您可以使用来捕获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" :)
}
}
如果您希望中间件捕获任何异常,那么可以将此过滤器用作一个实用工具,将MVC操作中发生的数据添加到异常中间件中。使用HttpContext.Items属性添加要在中间件中获取的信息
但是,为了确保中间件在返回的过程中遇到异常,请确保没有将exceptionhandled标记为true并正确测试 我希望将我的异常处理添加为第一个中间件,以使它有最好的机会从管道中的任何一点捕获异常。不过,这看起来确实很有用,我会花点时间来玩弄这个概念。编辑了你后续的答案。。。希望能有帮助。我有点想做这样的事情,但它不能完全解决问题。如果您有一个来自中间件的异常,那么它将无法告诉您联系了哪个控制器,因为异常过滤器将无法捕获它。错误处理程序中间件将不知道如何处理它。这可能是你能得到的最好结果,在这种情况下,我只需要有一个默认值。
services.AddMvc(options =>
{
options.Filters.Add(typeof(GlobalExceptionCatcher));
});