c# - 如何将 Polly 与 Flurl.Http 一起使用?

标签 c# httpresponse polly flurl

目前我有这个请求:

await url
    .SetQueryParams(queryString)
    .SetClaimsToken()
    .GetJsonAsync<T>()

我现在想开始使用 Polly ( https://github.com/App-vNext/Polly ) 来处理重试并提供更好的用户体验。例如,由于网络连接不良,不会在第一次尝试时“挂断”用户。这是我尝试使用的示例:

int[] httpStatusCodesWorthRetrying = { 408, 500, 502, 503, 504 };
Policy
    .Handle<HttpException>()
    .OrResult<HttpResponse>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode))
    .WaitAndRetryAsync(new[] {
                    TimeSpan.FromSeconds(1),
                    TimeSpan.FromSeconds(2),
                    TimeSpan.FromSeconds(3)
                })
    .ExecuteAsync( await url... )

但它需要HttpResponse 为返回类型。从我的 Flurl 示例中可以看出,它返回 T,即使它是一个 HttpResponseT 只是用于反序列化 StringContent 的类型。

第一个示例根本不起作用,因为我在 PCL 中使用它并且我无法在那里获得对 System.Web 的引用。所以我尝试了这个:

Policy
    .HandleResult(HttpStatusCode.InternalServerError)
    .OrResult(HttpStatusCode.BadGateway)
    .OrResult(HttpStatusCode.BadRequest)
    .WaitAndRetryAsync(new[] {
        TimeSpan.FromSeconds(1),
        TimeSpan.FromSeconds(2),
        TimeSpan.FromSeconds(3)
    })
    .ExecuteAsync(async () =>
    {
        await url...
    });

但这一个也不起作用,因为 Polly 期望 HttpStatusCode 作为返回类型。所以我的问题是:如何告诉 polly 处理那些 HttpStatusCode 并且仍然允许我返回 T 类型?

最佳答案

您不需要中断使用像 GetJsonAsync<T>() 这样的便捷方法,因为 Flurl 在非 2XX 响应(或者你 configure 它)上抛出异常,这应该允许它与 Polly 一起玩得很好。只需删除 .Handle<HttpException>.OrResult<HttpResponse>原始代码和句柄中的零件 FlurlHttpException相反:

T poco = await Policy
    .Handle<FlurlHttpException>(ex => httpStatusCodesWorthRetrying.Contains((int)ex.Call.Response.StatusCode))
    .WaitAndRetryAsync(...)
    .ExecuteAsync(() => url
        .SetQueryParams(queryString)
        .SetClaimsToken()
        .GetJsonAsync<T>());

还有一个进一步清理的建议:

T poco = await Policy
    .Handle<FlurlHttpException>(IsWorthRetrying)
    .WaitAndRetryAsync(...)
    .ExecuteAsync(() => url
        .SetQueryParams(queryString)
        .SetClaimsToken()
        .GetJsonAsync<T>());

private bool IsWorthRetrying(FlurlHttpException ex) {
    switch ((int)ex.Call.Response.StatusCode) {
        case 408:
        case 500:
        case 502:
        case 504:
            return true;
        default:
            return false;
    }
}

关于c# - 如何将 Polly 与 Flurl.Http 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40745809/

相关文章:

c# - 如何在 C# 中解析 JSON 子集合

c# - 根据 t 计算贝塞尔曲线上的点

c# - 我如何实现 HTTP 响应过滤器以一次对整个内容进行操作,不分块

c# - Polly 库的包装器,以便实现可以保留在一个地方

c# - 如何使用 Moq 从 IHttpClientFactory 模拟 HTTPClient 并结合 .NET Core 中的 Polly 策略

c# - 用于查找 List<List<int>> 最大值的 Linq 表达式?

c# - 在哪里存储应用程序全局设置?

java - Spring RestTemplate - 错误处理

scala - Spray:如何将 respondWithHeaders 应用于所有路线而不是每个路线

c# - 通过 Lambda Func 发出 Http 请求