I have a method that works, looks something like this:
public IObservable<List<Stuff>> GetGoodStuff()
{
return Observable.FromAsync(GetAccessTokenAsync)
.SelectMany(accessToken =>
{
return httpClient.SendAsync(request);
})
.SelectMany(response =>
{
response.EnsureSuccessStatusCode();
return response.Content.ReadAsStringAsync();
})
.Select(json =>
{
return JsonConvert.DeserializeObject<List<Stuff>>(json);
});
}
"GetAccessTokenAsync" returns the cached access token for the api, or, for the first time, you will receive a token. The rest is pretty standard in terms of httpclient and Rx.
Here's what: I would like to catch error 401, update the access token, and then repeat everything. But only once - after that he can throw an exception to the caller.
In this middle block, I can do this:
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
InvalidateAccessToken();
}
But then what? Not seeing how the recursive call will work. How to wrap it all up? Not seeing this yet ...
EDIT 1 - 7Nov2015
. , , "", .
, @Timothy Shields, , (, , , : -)
async Task<string> MakeRequestWithAccessToken(string requestUri, CancellationToken cancellationToken)
{
const int RetryCount = 1;
HttpResponseMessage response = null;
for (int i = 0; i <= RetryCount; i++)
{
var accessToken = await GetAccessTokenAsync();
var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
request.Headers.Add("Authorization", "Bearer " + accessToken);
var client = new RemoteService(ApiUrl).NewClient();
response = await client.SendAsync(request, cancellationToken);
if (i < RetryCount && response.StatusCode == HttpStatusCode.Unauthorized)
{
InvalidateAccessToken();
continue;
}
response.EnsureSuccessStatusCode();
}
return await response.Content.ReadAsStringAsync();
}
public IObservable<List<Stuff>> GetGoodStuff(int maxCount)
{
return Observable.FromAsync(async cancellationToken =>
{
var requestUri = string.Format("mypath.json?count={0}", maxCount);
var json = await MakeRequestWithAccessToken(requestUri, cancellationToken);
return JsonConvert.DeserializeObject<List<Stuff>>(json);
});
}