【问题标题】:Using Flurl's OnError to check for custom response headers in ASP.NET Core Web API使用 Flurl 的 OnError 检查 ASP.NET Core Web API 中的自定义响应标头
【发布时间】:2021-09-19 17:08:00
【问题描述】:

我正在开发一种中间件 API,旨在连接到各种系统。我正在使用 Flurl 库向各个系统发出请求。

其中一个系统有时会返回包含错误消息的自定义标头,而不是仅在响应正文中返回它(出于我不知道的原因)。

为了返回正确的错误信息,我使用了 Flurl 的 OnError 事件处理程序。我定义了检查此自定义标头的响应的行为,如果找到,则提取解码的消息并将其设置为请求的响应消息:

/// <summary>
/// Asynchronously checks responses from Thinkwise Indicium for TSFMessage headers and, if found,
/// decodes them and sets them as the actual error message of the response.
/// </summary>
/// <param name="request">The request of which the response must be checked for a Thinkwise message header.</param>
/// <returns>A Task.</returns>
public static async Task HandleThinkwiseErrorAsync(FlurlCall request)
{
  if (request.Response.Headers.TryGetFirst("TSFMessages", out var message))
  {
    var decodedMessage = JsonSerializer.Deserialize<ThinkwiseSoftwareFactoryMessage>(
                       Encoding.UTF8.GetString(Convert.FromBase64String(message)));

    var response = new HttpResponseMessage
    {
      StatusCode = HttpStatusCode.BadRequest,
      RequestMessage = new HttpRequestMessage(request.Request.Verb, request.Request.Url),
      Content = new StringContent(
        decodedMessage?.RawMessage.Split("\"")[1]
        ?? await request.Response.ResponseMessage.Content.ReadAsStringAsync(default))
      };

    request.HttpResponseMessage = response;
    request.ExceptionHandled = false;
  }
}

虽然我之前确实有使用 Flurl 发出 HTTP 请求的经验,但像这样配置它对我来说还是第一次。我已经在 DI 容器中配置了 Flurl:

FlurlHttp.Configure(settings =>
{
  settings.OnErrorAsync = IndiciumFlurlHelper.HandleThinkwiseErrorAsync;
  settings.OnError = IndiciumFlurlHelper.HandleThinkwiseError; // Same as async method
});

我很难找到其他试图做类似事情的文章、问题或 SO 问题。我可能在某个地方犯了一个新手错误,或者只是误解了 FlurlCall 对象的构造方式以及属性的含义。

我遇到的问题是,当我发出请求时,我 知道 应该使用此标头返回错误消息,我的中间件 API 在应该返回 400 响应时返回 204 响应正文中的错误消息。

我做错了什么?请求似乎按预期工作,所以我很确定我以这种方式处理此响应标头做错了。

提前致谢!如果您还有其他问题,请留下评论。

【问题讨论】:

    标签: c# api asp.net-core .net-core flurl


    【解决方案1】:

    这是行不通的,因为 204 不是错误状态,因此 Flurl 不会引发 OnError 事件,您的处理程序也不会受到影响。尽管您可以configure Flurl 应将哪些状态视为错误,但无法指定 2xx 范围内的任何状态都应视为错误。

    您可以改为处理AfterCall 事件,尽管此时更改响应为时已晚。无论如何,我不确定这是一个好主意,这就像假装服务器返回了它没有返回的东西。最好只接受实际响应并相应地处理它。

    当然,另一种选择是完全跳过事件处理,只内联处理这个条件。事件处理程序适用于像日志记录这样的横切关注点,但处理错误条件通常只是正常应用程序流程的一部分。在 3.0 中引入 FlurlResponse 也应该使这个流程更容易。

    【讨论】:

    • 我正在调用的系统没有返回 204,如果对系统的请求成功,我的中间件 API 返回 204。但是,如果我向系统发送请求,我知道肯定会返回 500 响应,即使我将中间件 API 配置为在找到标头时返回 403,我的中间件 API 仍会返回 204。对于没有在问题中明确说明这一点,我深表歉意。
    • 在这种情况下,我认为您可能需要发布中间件代码。您是否尝试过使用调试器单步执行它以确保事件处理程序被命中并且您的中间件看到您正在设置的响应?
    • 贴出的代码是中间件代码。它查找标头,如果找到,将响应更改为错误请求,而不是系统抛出的内部服务器错误,并将解码的消息设置为响应正文(或者,这就是我尝试做的)。我还没有时间逐步使用调试器,如果发现错误,我会这样做并在此处发布答案。
    猜你喜欢
    • 2018-02-21
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 2019-12-28
    • 2012-11-09
    • 2019-07-23
    相关资源
    最近更新 更多