c# - 在 Polly 重试尝试中获取完整的 URI?

标签 c# .net-core dotnet-httpclient polly retry-logic

我正在使用 Polly 重试 HttpClient 尝试:

        services.AddHttpClient<JoinPackageApiClient>(jp => { jp.BaseAddress = new Uri(appSettings.JoinPackageWS.BaseUrl); })
            .AddPolicyHandler(GetRetryPolicy(appSettings, serviceProvider))

其中 GetRetryPolicy 是:

 private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(AppSettings appSettings, ServiceProvider serviceProvider)
        {
            return HttpPolicyExtensions
                .HandleTransientHttpError()
                .OrResult(msg => msg.StatusCode != HttpStatusCode.OK)
                .Or<TimeoutRejectedException>()
                .Or<TaskCanceledException>()
                .Or<OperationCanceledException>()

                .WaitAndRetryAsync(appSettings.PollySettings.RetryAttempts, (retryAttempt, c) =>
                {

                 return TimeSpan.FromSeconds(2);
                }, onRetry: (response, delay, retryCount, context) =>
                {

                   //█how can I access the full(!) HttpClient's URI here ?
                   //e.g. : https://a.com/b/c?d=1
               
                });
        }

问题:

查看 onRetry 参数,我想在 onRetry 部分记录完整的 URL 尝试。

如何获取该部分的完整 URI?

最佳答案

当我在评论中声明这是不可能的时,我错了。

enter image description here

我必须纠正自己:是的,这是可行的,而且实际上非常简单。 :)

您需要做的就是使用不同的重载 AddPolicyHandler

public static IHttpClientBuilder AddPolicyHandler (this IHttpClientBuilder builder, Func<IServiceProvider,HttpRequestMessage,IAsyncPolicy<HttpResponseMessage>> policySelector);

所以,每当您调用 AddPolicyHandler你必须提供一个函数,该函数

  • 收到 IServiceProvider实例能够访问任何 DI 注册服务
  • 还会收到请求,您可以通过 RequestUri property 访问该 URL。
  • 并返回 IAsyncPolicy<HttpResponseMessage>

因此,您必须像这样修改注册代码:

services.AddHttpClient<JoinPackageApiClient>(jp => ...)
        .AddPolicyHandler((provider, request) => GetRetryPolicy(appSettings, provider, request));

GetRetryPolicy方法如下:

private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(
    AppSettings appSettings,
    IServiceProvider serviceProvider, 
    HttpRequestMessage request)
   => HttpPolicyExtensions
        .HandleTransientHttpError()
        ...
        .WaitAndRetryAsync(appSettings.PollySettings.RetryAttempts, 
        (_, __) => TimeSpan.FromSeconds(2),
        (response, delay, retryCount, context) =>
        {
            var url = request.RequestUri;
            // ...
        });

好消息是,每当您发出新请求时,URL 都会发生变化。 (在我的测试客户端中,我已将 BaseAddress 设置为 http://httpstat.us ) 当我运行此测试时

await client.GetAsync("/200");
try
{
    await client.GetAsync("/401");
}
catch { }
await client.GetAsync("/403");

然后重试触发了 4 次(401 为 2 次,403 为 2 次)。 onRetry收到相关HttpRequestMessage所以,记录是准确的。

关于c# - 在 Polly 重试尝试中获取完整的 URI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63172390/

相关文章:

c# - 如何通过代码启用 URI 类的 IDN/IRI 支持?

c# - 添加自定义属性时如何删除 CS0649 编译器警告?

c# - .Net-Core 配置拉取连接字符串错误的提供者

c# - .NET Core 中是否内置了自动转义无效 HTTP header 字符的支持?

c# - 对于涉及跨源请求的 SSO 流,在 iOS 12 中阻止了强制执行 SameSite 策略的 Cookie

c# - HttpClient 对本地主机的请求非常慢,甚至失败

c# - .Net 在两个 Web 服务之间共享 dll

c# - System.Web.Helpers HashPassword 盐和迭代?

c# - HttpClient不报告从Web API返回的异常

C# 使用 httpclient 发出 https 请求