Flurl 客户端 - 是否可以从失败的请求中访问 headers?

Flurl Client - Is it possible to access the headers from a failed request?

我正在使用 Flurl 客户端调用带有 post 数据的 restful API。服务器对我提交的数据进行了验证,它 returns 返回一个 header 包含用户的错误消息。

由于请求要求不满足服务器将请求标记为400 BadRequest。在下面 cli.Request(uri).PostJsonAsync(data) 行的代码中,它会抛出 FlurlHttpException 和适当的状态代码。

现在,由于用户输入的数据存在问题,我想在 header 中向用户报告我从服务器收到的错误消息。但是,由于请求失败,我无法访问响应 headers。

有没有其他方法可以使用 Flurl 访问失败请求的响应 header?

  try
  {
    using (var cli = new FlurlClient(baseUrl))
    {
        var httpResponse = await cli.Request(uri).PostJsonAsync(data);
        var errorMessage = httpResponse.GetHeaderValue("errorMessage");
    }
  }
  catch (FlurlHttpException ex)
  {
  }

我正在配置错误事件处理程序来报告任何错误。因此,代码不会跳转到异常块,它会异步触发事件处理程序,并且我的后续代码的其余部分执行正常,并带有适当的 httpResponseMessage、StatusCode、headers everything.

  ...
    FlurlHttp.Configure(settings => settings.OnErrorAsync = HandleFlurlErrorAsync);
    using (var cli = new FlurlClient(baseUrl))
    {
        var httpResponse = await cli.Request(uri).PostJsonAsync(data);
        var errorMessage = httpResponse.GetHeaderValue("errorMessage");
    }
  ...

private async Task HandleFlurlErrorAsync(HttpCall call)
{
  //Log your exception here
  call.ExceptionHandled = true;
}

使用事件处理程序可行,但我认为这些更适合横切关注点,例如您不想让应用程序的主流混乱的日志记录。您基本上希望 and/or 处理 400 个响应作为该主流的一部分。你可以更直接地使用AllowHtttpStatus,它可以在客户端设置:

cli.AllowHtttpStatus(HttpStatusCode.BadRequest);

或要求:

var httpResponse = await cli
    .Request(uri)
    .AllowHttpStatus(HttpStatusCode.BadRequest)
    .PostJsonAsync(data);

无论哪种方式,调用都不会抛出 400。

执行此操作的另一种方法,如果您的应用程序逻辑在错误条件下采用与成功条件完全不同的路径,我建议您保持 try/catch 不变并使用Response 属性 处理错误条件的异常:

try
{
    await cli.Request(uri).PostJsonAsync(data);
    // handle success condition
}
catch (FlurlHttpException ex) when (ex.Response?.StatusCode == 400)
{
    var errorMessage = ex.Response.GetHeaderValue("errorMessage");
    // handle error condition
}

附带说明一下,3.0 中有一些重大变化,您应该注意这些变化,因为它们直接涉及其中一些领域:

https://github.com/tmenier/Flurl/issues/354

https://github.com/tmenier/Flurl/issues/488