首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >HttpStatusCode.Unauthorized后使用Polly重试

HttpStatusCode.Unauthorized后使用Polly重试
EN

Stack Overflow用户
提问于 2017-01-28 13:00:38
回答 4查看 15.1K关注 0票数 17

我正在调用外部API,并希望处理调用返回Unauthorized HttpResponseMessage的事件。当发生这种情况时,我希望刷新访问令牌并再次进行调用。

我试图在下面的代码中使用Polly

代码语言:javascript
代码运行次数:0
运行
复制
    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 --有人能帮我实现我想要实现的目标吗?

我看过Polly文档&关于堆栈溢出的Polly问题,但是我不知道发生了什么。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-01-28 15:41:45

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

如果您的实际代码读取与上面的代码示例完全相同,则.ExecuteAsync(...)将抛出同步策略.Retry(...)与异步执行.ExecuteAsync(...)之间的不匹配。由于抛出了此异常,因此实际上从未调用过CallApiAsync()。调用MakeGetRequestAsync()时,您应该能够看到抛出的异常。

总的来说,代码方法看起来不错:这种重试-刷新-身份验证是一个用Polly证明的模式

票数 11
EN

Stack Overflow用户

发布于 2020-06-14 15:03:11

我在回答这个老问题时,只想指出Polly wiki页面,其中这个模式是正式记录的:

重试刷新授权

特别是,这是建议的代码片段:

代码语言:javascript
代码运行次数:0
运行
复制
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将其传递给通过策略执行的委托。

票数 6
EN

Stack Overflow用户

发布于 2022-09-24 10:00:28

我可能会迟到,但我给未来的读者留了一篇文章。我已经为这个带重试问题的刷新令牌创建了两个稍微不同的解决方案。

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

  • 下面是描述通信流程的序列图。
  • 这是全源代码

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

这个版本以一种不同的方式将责任分开:

  • 下面是描述通信流程的序列图。
  • 这是全源代码

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41910066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档