我正在调用外部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
--有人能帮我实现我想要实现的目标吗?
我看过Polly文档&关于堆栈溢出的Polly问题,但是我不知道发生了什么。
发布于 2017-01-28 15:41:45
要使用ExecuteAsync()
,必须将策略声明为.RetryAsync(...)
,而不是.Retry(...)
。
如果您的实际代码读取与上面的代码示例完全相同,则.ExecuteAsync(...)
将抛出同步策略.Retry(...)
与异步执行.ExecuteAsync(...)
之间的不匹配。由于抛出了此异常,因此实际上从未调用过CallApiAsync()
。调用MakeGetRequestAsync()
时,您应该能够看到抛出的异常。
总的来说,代码方法看起来不错:这种重试-刷新-身份验证是一个用Polly证明的模式!
发布于 2020-06-14 15:03:11
我在回答这个老问题时,只想指出Polly wiki页面,其中这个模式是正式记录的:
特别是,这是建议的代码片段:
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
将其传递给通过策略执行的委托。
https://stackoverflow.com/questions/41910066
复制相似问题