gpt4 book ai didi

c# - 如果 ExceptionHandler 捕获到异常,则不会调用 DelegatingHandler

转载 作者:行者123 更新时间:2023-11-30 22:58:47 24 4
gpt4 key购买 nike

我正在尝试了解 Web API Http 管道的工作原理!

在我的 Web API 项目中,我使用以下技术来记录/处理异常:

  • ExceptionHandler -> 在全局级别处理异常
  • ExceptionFilterAttribute -> 处理用户抛出的自定义异常
  • DelegatingHandler -> 记录请求和响应数据

每个实现的示例代码:

异常过滤器:

public class CustomExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var request = context.ActionContext.Request;
if (context.Exception is ItemNotFoundException)
{
context.Response = request.CreateResponse(HttpStatusCode.NotFound, context.Exception.Message);
}
else if (context.Exception is InvalidRequestException)
{
context.Response = request.CreateResponse(HttpStatusCode.BadRequest, context.Exception.Message);
}
}
}

异常处理程序:

public class GlobalExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
var result = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(Constant.ErrorMessage.InternalServerError)
};
context.Result = new ErrorMessageResult(context.Request, result);
}
}

public class ErrorMessageResult : IHttpActionResult
{
private readonly HttpRequestMessage _request;
private readonly HttpResponseMessage _httpResponseMessage;

public ErrorMessageResult(HttpRequestMessage request, HttpResponseMessage httpResponseMessage)
{
_request = request;
_httpResponseMessage = httpResponseMessage;
}

public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(_httpResponseMessage);
}
}

委托(delegate)处理程序:

public class LogRequestAndResponseHandler : DelegatingHandler
{
private readonly ILoggingService _loggingService;

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
string requestBody = await request.Content.ReadAsStringAsync();
_loggingService.FirstLevelServiceLog(requestBody);
var result = await base.SendAsync(request, cancellationToken);
if (result.Content != null)
{
var responseBody = await result.Content.ReadAsStringAsync();
_loggingService.FirstLevelServiceLog(responseBody);
}
return result;
}
}

观察:

  • 当出现自定义异常时 CustomExceptionFilter 被调用,随后响应被记录在 LogRequestAndResponseHandler 中。
  • 但是,如果未处理异常,它会进入 GlobalExceptionHandler,然后响应不会到达 LogRequestAndResponseHandler 进行记录。

谁能告诉我,必须在 CustomExceptionFilter/GlobalExceptionHandler 中更改哪些代码才能在 DelegatingHandler 中接收响应?

Solution: (Updated 10/09/2018)

好的,所以我找到了解决方案 here

通过修改 ExceptionHandler 代码,我能够在 DelegatingHandler 中捕获响应

关键是继承自 IExceptionHandler 而不是 ExceptionHandler

代码:

public class GlobalExceptionHandler : IExceptionHandler
{
public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
var httpResponse = context.Request.CreateResponse(HttpStatusCode.InternalServerError, Constant.ErrorMessage.InternalServerError);
context.Result = new ResponseMessageResult(httpResponse);

return Task.FromResult(0);
}
}

问题:

  • 我还是不明白它是如何工作的? IExceptionHandlerExceptionHandler 有什么区别?

任何人都可以阐明这一点吗?

最佳答案

ExceptionHandler 像这样实现 IExceptionHandler:

Task IExceptionHandler.HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
if (context == null)
throw new ArgumentNullException(nameof (context));
ExceptionContext exceptionContext = context.ExceptionContext;
if (!this.ShouldHandle(context))
return TaskHelpers.Completed();
return this.HandleAsync(context, cancellationToken);
}

我怀疑您看到的区别在于 ShouldHandle 检查,它是这样实现的:

public virtual bool ShouldHandle(ExceptionHandlerContext context)
{
if (context == null)
throw new ArgumentNullException(nameof (context));
return context.ExceptionContext.CatchBlock.IsTopLevel;
}

我对管道不是很熟悉,但据我所见,似乎可以在不同的点处理异常,并且 ExceptionHandler 基类假定您可能只想在管道的顶层处理异常执行栈。我见过 other handlers like CORS get in the way of this 的案例,并且 catch block 永远不会在顶层结束。

如果这是您所看到的,您仍然可以扩展 ExceptionHandler,并覆盖 ShouldHandle 方法以始终返回 true。或者你可以更外科手术并专门检测 CORS 是否可能妨碍顶级检查 as suggested in this comment .

关于c# - 如果 ExceptionHandler 捕获到异常,则不会调用 DelegatingHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52712460/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com