Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Error handling 如何判断哪个控制器引发了异常_Error Handling_Controller_Asp.net Core Mvc_Asp.net Core 2.0 - Fatal编程技术网

Error handling 如何判断哪个控制器引发了异常

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,

我想创建一个错误处理中间件,它处理不同于页面请求的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();
    }
}
[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));
    });