使用Polly在HttpStatusCode.Unauthorized后重试

问题描述 投票:0回答:4

我正在调用外部 API,并希望处理调用返回

Unauthorized
HttpResponseMessage
的事件。发生这种情况时,我想刷新访问令牌并再次拨打电话。

我正在尝试将

Polly
与以下代码一起使用:

    public async Task<HttpResponseMessage> MakeGetRequestAsync()
    {
        var retryPolicy = Policy
            .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized)
            .Retry(1, (exception, retryCount) =>
            {
                RefreshAccessToken();
            });

        var result = await retryPolicy.ExecuteAsync(() => CallApiAsync());

        return result;
    }


    private async Task<HttpResponseMessage> CallApiAsync()
    {
        var url = Options.ResourceSandboxUrl;

        var httpClient = new HttpClient();
        SetRequestHeaders(httpClient);
        var response = await httpClient.GetAsync(url);

        response.StatusCode = HttpStatusCode.Unauthorized;
        return response;
    }

我在

ExecuteAsync
语句和
DoSomethingAsync
中放置了断点 - 当我跨过
ExecuteAsync
时,不会调用
DoSomethingAsync
,控制权返回到调用
MakeGetRequestAsync

的函数

我不明白为什么不调用

DoSomethingAsync
- 任何人都可以帮助我实现我想要实现的目标吗?

我查看了 Stack Overflow 上的 Polly 文档和 Polly 问题,但我不知道发生了什么..

c# asp.net-mvc dotnet-httpclient refresh-token polly
4个回答
12
投票

要使用

ExecuteAsync()
,您必须将策略声明为
.RetryAsync(...)
,而不是
.Retry(...)

如果您的实际代码与上面的代码示例完全相同,则将因

.ExecuteAsync(...)
[同步策略] 和
.Retry(...)
[异步执行] 之间的不匹配而抛出
.ExecuteAsync(...)
。由于抛出了这个异常,
CallApiAsync()
确实从未被调用。当调用
MakeGetRequestAsync()

时,你应该能够看到抛出的异常

整体代码方法看起来不错:这种重试刷新身份验证是一种经过 Polly 验证的模式!


8
投票
官方记录了这种模式

。特别是这是建议的代码片段: var authorisationEnsuringPolicy = Policy .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized) .RetryAsync( retryCount: 1, // Consider how many retries. If auth lapses and you have valid credentials, one should be enough; too many tries can cause some auth systems to blacklist. onRetryAsync: async (outcome, retryNumber, context) => FooRefreshAuthorizationAsync(context), /* more configuration */); var response = authorisationEnsuringPolicy.ExecuteAsync(context => DoSomethingThatRequiresAuthorization(context), cancellationToken);

FooRefreshAuthorizationAsync(...)

方法可以获取新的授权令牌,并将其传递给使用

Polly.Context
通过策略执行的委托。

    


1
投票

重试策略、委派处理程序和自定义异常

这是描述通信流程的序列图
  • 这是
  • 完整源代码

重试策略、委托处理程序和 Polly.Context

此版本以不同的方式分离职责:

这是描述通信流程的序列图
  • 这是
  • 完整源代码


-1
投票
await

时,会发生两件事


    代码的当前线程应该释放以使代码异步,这意味着您的方法应该返回
  1. 当您等待的任务完成时,您的方法应该从原来的位置继续
© www.soinside.com 2019 - 2024. All rights reserved.