更新的内容在正确的时间两次调用了缓存令牌。 所以一个人去更新了更新令牌,另一个错误了。
我已将其设置为异步等待,为什么会有两个调用调用同一函数? 我该如何预防?谢谢
我有一个包装器,它创建了一个函数public async Task getCacheToken,该函数是为一些内部/外部服务/应用程序调用而创建的,并且每分钟或更频繁地调用一次。
由于某种原因,我仅收到一个httpRequestException 每小时,精确到分钟和秒。
以下日志显示在每小时XX:45:01的确切时间捕获异常
我试图增加httpclient的超时和http的运行时间,但是它不起作用。我真的很困惑究竟是什么导致它在准确的时间内仅抛出一次错误。
非常感谢您阅读这篇文章。
10 Jul 2019 15:20:02.883
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext().Exception: HttpRequestException {"Message":"Response status code does not indicate success: 400 (Bad Request).","Data":[],…Stack: at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()Category: Exception
10 Jul 2019 15:20:02.812
refresh token after update : e96be27ea80140c9a90c2ea06e7a1fd9
10 Jul 2019 15:20:01.528
refresh token : e2eb37664bb741918d3ebf38587d3801
10 Jul 2019 15:20:01.528
refresh token : e2eb37664bb741918d3ebf38587d3801
10 Jul 2019 15:20:01.528
refresh token is null : Yes
10 Jul 2019 15:20:01.528
refresh token is null : Yes
08 Jul 2019 00:45:01.453
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 23:45:01.385
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 22:45:01.412
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 21:45:01.378
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 20:45:01.536
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 19:45:01.515
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 18:45:01.523
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 17:45:01.688
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 16:45:01.605
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 15:45:01.482
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 14:45:01.522
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 13:45:01.504
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 12:45:01.533
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 11:45:01.418
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 10:45:01.420
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 09:45:01.443
ResultMessage : {"error":"invalid_grant"} Exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext(). Message: Response status code does not indicate success: 400 (Bad Request).. Stacktrace at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at RaisersEdge.Infrastructure.Cache.<GetCacheToken>d__2.MoveNext()
07 Jul 2019 08:45:01.393
这是我的代码
public async Task<string> GetCacheToken()
{
ObjectCache cache = MemoryCache.Default;
string refreshToken = cache.Get("refreshToken", null) == null ? GetToken() : cache.Get("refreshToken", null).ToString();
if (!cache.Contains("apiToken"))
{
//Log.Information("Access token " + cache.Get("apiToken", null));
var isNull = cache.Get("refreshToken", null) == null ? "Yes" : "No";
Log.Information("refresh token is null : " + isNull);
Log.Information("refresh token : " + refreshToken);
var httpContent = new StringContent("", Encoding.UTF8, "application/x-www-form-urlencoded");
var dict = new Dictionary<string, string>();
dict.Add("grant_type", "refresh_token");
dict.Add("refresh_token", refreshToken);
var requestData = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://oauth2.sky.blackbaud.com/token"),
Content = new FormUrlEncodedContent(dict)
};
requestData.Headers.Authorization = new AuthenticationHeaderValue("Basic", Settings.BasicAuth);
var results = await _client.SendAsync(requestData);
var resultResponse = results.Content.ReadAsStringAsync().Result;
try
{
results.EnsureSuccessStatusCode();
var result = _js.Deserialize<TokenModel>(resultResponse);
//token expires in one hour from blackbaud
var expiration = DateTimeOffset.UtcNow.AddMinutes(55);
cache.Set("apiToken", result.access_token, expiration);
cache.Set("refreshToken", result.refresh_token, expiration);
UpdateToken(result.access_token, result.refresh_token);
Log.Information("refresh token after update : " + cache.Get("refreshToken", null));
}
catch (Exception e)
{
var exceptionMessage = $"ResultMessage : {resultResponse} Exception: {e}.";
Log.Exception(e,exceptionMessage);
throw;
}
//Log.Information("after update access token " + cache.Get("apiToken", null));
}
return cache.Get("apiToken", null).ToString();
}
这是外部应用程序调用的终点
public async Task<string> getAccessToken()
{
return await cacheToken.GetCacheToken();
}
对于外部应用程序,这就是他们获取AccessToken的方式
protected string getAccessToken()
{
var requestData = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri($"Settings.Api/getAccessToken"),
};
requestData.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
var results = client.SendAsync(requestData).Result;
var resultResponse = results.Content.ReadAsStringAsync().Result;
if (results.IsSuccessStatusCode)
return resultResponse.Replace("\"", "");
return "";
}
然后在此处传递它,这只是示例之一,还有10个以上吗?调用getCacheToken的地方
protected override ExtractResultStatus PerformExtract()
{
try
{
var dt = GetInfos();
var fileName = String.Format(FilenameBase, DateTime.Now);
if (dt.Rows.Count > 0)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
dt.Columns.Add("FailureReason");
var numErrors = 0;
foreach (DataRow row in dt.Rows)
{
var success = true;
var numberOfTries = 0;
// Post Cons custom fields
numberOfTries = 0;
do
{
var token = getAccessToken();
if (token != null)
{
var content = CreateCCFModel(row);
var json = JsonConvert.SerializeObject(content);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var requestData = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri($"Settings.api/customfields"),
Content = httpContent
};
requestData.Headers.Add("Bb-Api-Subscription-Key", _bb_Api_Subscription_Key);
requestData.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
var results = client.SendAsync(requestData).Result;
var resultResponse = results.Content.ReadAsStringAsync().Result;
if (!results.IsSuccessStatusCode)
{
row["FailureReason"] += " Failure reason: " + resultResponse;
numErrors++;
}
if (results.StatusCode == HttpStatusCode.InternalServerError)
{
success = false;
numberOfTries++;
if (numberOfTries >= 3)
{
throw new Exception("500 response returned three times");
}
}
else success = true;
}
} while (!success && numberOfTries <= 3);
}
SendDataToClients(targetContactEmails, dt.Rows.Count, numErrors, fileName);
}
File.WriteAllBytes(_dataFilePath + fileName, Encoding.ASCII.GetBytes(dt.ToCsv()));
}
catch (Exception e)
{
Log.Exception(e, LogCategory, LogSeverity.Warning);
SendErrorEmail(e);
return ExtractResultStatus.Failure;
}
return ExtractResultStatus.Success;
}