禁用 ASP.NET Web API 2 中的“所有”异常处理(为我自己的异常处理腾出空间)?

2023-12-24

我想在中间件组件中连接异常处理,如下所示:

public override async Task Invoke(IOwinContext context)
{
    try
    {
        await Next.Invoke(context);
    }
    catch (Exception ex)
    {
        // Log error and return 500 response
    }
}

但是,我想捕获的一些异常正在被捕获并转换为HttpErrorResponse在我能够访问它们之前,先通过 Web API 管道进行处理。在此过程中,我丢失了很多有关错误的详细信息,因此在调试等时无法获得有用的堆栈跟踪(抛出异常时调试器甚至不会停止 - 我必须手动单步执行代码并查看失败的地方......)。

我尝试使用以下实现添加自定义异常处理程序:

public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
    var owinContext = context.Request.GetOwinContext();
    owinContext.Set(Constants.ContextKeys.Exception, context.Exception);
    return Task.FromResult(0);
}

注册通过config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());在我的启动配置中,但是执行后查看它Next.Invoke(context) through

context.Get<Exception>(Constants.ContextKeys.Exception);

still没有提供我想要的所有详细信息,并且无法使用调试器在故障点停止。

有什么办法我可以完全地all内置错误处理,以便我自己的中间件可以处理它?

澄清,因为很多人似乎误解了我的目的:

  • Web API 中的内置错误处理捕获some(但不是全部)异常并将其重写为 500 个响应。
  • 我想抓住all异常,做一些日志记录,以及then发出 500 个响应与我选择的信息(对于其中大多数,请参阅下一个项目符号)。
  • 还有一些异常表示业务逻辑错误,对此我想返回 40x 错误。
  • 我希望它位于(应用程序)管道的顶部,即包装一切else 在请求生命周期中
  • 我想使用 OWIN 来处理这个问题,使其可移植到未来可能的自托管场景(即,这个应用程序将始终托管在 IIS 上并不是一成不变的 - HTTP 模块、Global.asax.cs 等不相关)这里)。

Update: 我在博客上谈到了这个 http://www.jayway.com/2016/01/08/improving-error-handling-asp-net-web-api-2-1-owin/。在研究博客文章时,我发现了一些改进的潜力;我已经更新了这个答案的相关部分。有关为什么我认为这比此处的所有其他建议或默认行为更好的更多详细信息,请阅读整篇文章:)


我现在采用了以下方法,即使不是 100% 符合我正在寻找的内容,它似乎也可以正常工作:

  • 创建一个类PassthroughExceptionHandler:

    public class PassthroughExceptionHandler : IExceptionHandler
    {
        public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
        {
            // don't just throw the exception; that will ruin the stack trace
            var info = ExceptionDispatchInfo.Capture(context.Exception);
            info.Throw();
            return Task.CompletedTask;
        }
    }
    
  • 让那个班级replace the IExceptionHandlerWeb API服务:

    config.Services.Replace(typeof(IExceptionHandler), new PassthroughExceptionHandler());
    
  • 创建一个中间件类来执行我想要的操作:

    public class ExceptionHandlerMiddleware
    {
        public override async Task Invoke(IOwinContext context)
        {
            try
            {
                await Next?.Invoke(context);
            }
            catch (Exception ex)
            {
                // handle and/or log
            }
        }
    }
    
  • 首先在堆栈中注册该中间件:

    app.Use<ExceptionHandlerMiddleware>()
       .UseStageMarker(PipelineStage.Authenticate)
       // other middlewares omitted for brevity
       .UseStageMarker(PipelineStage.PreHandlerExecute)
       .UseWebApi(config);
    

我仍然会将赏金奖励给提出的任何人(赏金已过期...)我仍在寻找更好的解决方案,例如,当未处理的抛出异常。 (当我在处理程序中重新抛出异常时,这种方法会使 VS 中断,但原始调用堆栈丢失;我必须在故障行设置断点并再次调试,以便能够拦截抛出异常时的状态。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

禁用 ASP.NET Web API 2 中的“所有”异常处理(为我自己的异常处理腾出空间)? 的相关文章

  • 如何在 ASP.Net Core 6 Web Api 中依赖注入 Microsoft Graph 客户端

    我正在尝试使用 ASP Net Core 6 设置 Web api 以便用户可以到达我的端点 然后我使用特权帐户在 Teams 中执行一些工作 我认为我没有正确连接 DI 部分 因为在向 Teams 发出请求时出现以下错误 MsalUiRe
  • 如何设置 web.config 文件以显示完整的错误消息

    我在 Windows Azure 上部署了 MVC 3 应用程序 但现在当我通过请求时staging url它告诉我 很抱歉 在执行您的要求时发生了一个错误 现在我想查看完整的错误消息 默认情况下由于某些安全原因它会隐藏该消息 我知道我们可
  • 如何有效地测试action是否用属性(AuthorizeAttribute)修饰?

    我正在使用 MVC 并且有一种情况OnActionExecuting 我需要确定即将执行的Action方法是否用属性修饰 AuthorizeAttribute尤其 我不是问授权是否成功 失败 而是问该方法是否需要授权 对于非 MVC 人员
  • C# SMO 远程数据库备份到本地机器

    我有一个执行 SQL 数据库备份和恢复的应用程序 这在本地计算机上运行良好 但是如果我针对另一台计算机上托管的 SQL 服务器运行此应用程序 则会出现以下错误 Microsoft SqlServer Management Smo Faile
  • 合并多边形的高效算法

    我有一个多边形列表 在这个列表中 一些多边形重叠 或者接触其他多边形 我的任务是合并所有相互重叠或接触的多边形 我有一个union执行此操作的方法 做到这一点最有效的方法是什么 我目前能想到的是循环遍历多边形列表 检查合并列表以查看该多边形
  • 增强缓冲区调用后丢失自定义点类型的数据

    我有我自己的观点 class LocationWayPoint public latlong container location WORD index PWeakBasicStation station namespace boost n
  • 在“delete this;”语句期间发生了什么?

    请考虑以下代码 class foo public foo foo void done delete this private int x 以下两个选项中发生了什么 并且有效吗 选项1 void main foo a new foo a gt
  • ASP.NET MVC 数据注释属性 Range 从另一个属性值设置

    您好 我的 Asp net MVc 模型中有以下内容 测试模型 cs public class TestModel public double OpeningAmount get set Required ErrorMessage Requ
  • 隐式转换和编译器的不同行为

    Motivated by this question https stackoverflow com q 51972738 5800831 I created the following code struct X X int struct
  • 安全移动 C++ 对象

    我听到过一些警告 不要通过以下方式将对象运送到另一个内存位置memcpy 但不知道具体原因 除非它包含的成员做了依赖于内存位置的棘手事情 否则这应该是完全安全的 或者不是 编辑 预期的用例是像这样的数据结构vector 它存储对象 不是po
  • autofac 中的条件组件注册

    是否可以根据其他组件的状态有条件地注册组件 就像是 ContainerBuilder RegisterConditionally
  • 将 jstring 转换为 QString

    我正在调用一个返回字符串的 Java 函数 QAndroidJniObject obj QAndroidJniObject callStaticObjectMethod
  • 从 ASP.NET Web API 返回 HTML

    如何从 ASP NET MVC Web API 控制器返回 HTML 我尝试了下面的代码 但由于未定义 Response Write 而出现编译错误 public class MyController ApiController HttpP
  • 更改为通用接口对性能的影响

    我使用 Visual Studio 使用 C NET 开发应用程序 ReSharper 在我的方法原型中经常建议我用更通用的类型替换输入参数的类型 例如 如果我仅在方法主体中使用带有 foreach 的列表 则使用 List 和 IEnum
  • 如何获取 EF 中的实体更改增量?

    我只需要获取已更改字段的列表 数据存储区是 ssce 因此没有可用的触发器 EF 是否支持获取列表或构建通用组件 根据上下文的类型和生成的实体 您可以通过多种不同的方式来完成此操作 如果对象继承自 Entity 或 POCO 您可以使用Ob
  • 在运行时生成可执行文件

    好吧 所以我想知道如何创建一个程序 该程序创建第二个程序 就像大多数压缩程序如何创建自解压自可执行文件一样 但这不是我需要的 假设我有 2 个程序 每个都包含一个类 我将使用一个程序来修改类并用数据填充类 第二个文件将是一个也具有该类的程序
  • 以编程方式将 UserControl 从 ContentControl 移动到另一个 ContentControl

    在 WPF 应用程序中 我想在代码中将 UserControl 从 ContentControl 移动到另一个控件 myContentControl2 Content myUserControl 在这种情况下我得到一个错误 指定的元素已经是
  • GCC编译非常慢(文件大)

    我正在尝试编译一个大的 C 文件 专门用于 MATLAB mexing C 文件大约 20 MB 可用来自 GCC 错误跟踪器 https gcc gnu org bugzilla attachment cgi id 36632如果你想玩一
  • C# p/Invoke 如何使用 DirectX 游戏的 SendInput 模拟 keyPRESS 事件

    我经常为各种机器人或其他 GUI 自动化程序模拟键盘按下事件而苦苦挣扎 我已经成功地使用以下方法模拟按键事件 INPUT kInput new INPUT 1 kInput j type SendInputEventType InputKe
  • 布尔实现的atomicCAS

    我想弄清楚是否存在错误答案 https stackoverflow com a 57444538 11248508 现已删除 关于Cuda like的实现atomicCAS for bool是 答案中的代码 重新格式化 static inl

随机推荐