У меня есть следующий код, чтобы сделать запросы к REST API, с помощью Xamarin и Android устройства:System.Net.Http.HttpClient с AutomaticDecompression и GetAsync (тайм-аут) против GetStringAsync (рабочий
public class ApiBase
{
HttpClient m_HttpClient;
public ApiBase(string baseAddress, string username, string password)
{
if (!baseAddress.EndsWith("/"))
{
baseAddress += "/";
}
var handler = new HttpClientHandler();
if (handler.SupportsAutomaticDecompression)
{
handler.AutomaticDecompression = DecompressionMethods.GZip;
}
m_HttpClient = new HttpClient(handler);
m_HttpClient.BaseAddress = new Uri(baseAddress);
var credentialsString = Convert.ToBase64String(Encoding.UTF8.GetBytes(username + ":" + password));
m_HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentialsString);
m_HttpClient.Timeout = new TimeSpan(0, 0, 30);
}
protected async Task<XElement> HttpGetAsync(string method)
{
try
{
HttpResponseMessage response = await m_HttpClient.GetAsync(method);
if (response.IsSuccessStatusCode)
{
// the request was successful, parse the returned string as xml and return the XElement
var xml = await response.Content.ReadAsAsync<XElement>();
return xml;
}
// the request was not successful -> return null
else
{
return null;
}
}
// some exception occured -> return null
catch (Exception)
{
return null;
}
}
}
Если бы я так оно и есть, первый и второй вызовы HttpGetAsync работают отлично, но с третьего на GetAsync
киосках и, в конце концов, выдает исключение из-за таймаута. Я посылаю эти вызовы последовательно, их нет одновременно, поскольку результаты предыдущего вызова необходимы для принятия решения о следующем вызове. Я попытался использовать приложение Packet Capture, чтобы посмотреть на запросы и ответы, чтобы узнать, отправляю ли я прямой запрос. Но похоже, что запрос, который терпит неудачу, никогда не отправляется.
Через эксперименты я узнал, что все работает нормально, если не установить AutomaticDecompression
.
Он также отлично работает, если я изменить HttpGetAsync
метод для этого:
protected async Task<XElement> HttpGetAsync(string method)
{
try
{
// send the request
var response = await m_HttpClient.GetStringAsync(method);
if (string.IsNullOrEmpty(response))
{
return null;
}
var xml = XElement.Parse(response);
return xml;
}
// some exception occured -> return null
catch (Exception)
{
return null;
}
}
Так в основном с использованием я m_HttpClient.GetStringAsync
вместо m_HttpClient.GetAsync
, а затем изменить пуха вокруг него, чтобы работать с другим типом возвращаемого значения. Если я сделаю это так, все будет работать без проблем.
Кто-нибудь есть идея, почему GetAsync
не работает должным образом (не похоже, чтобы отправить запрос на 3-й) с AutomaticDecompression
, где, как GetStringAsync
работает безупречно?
Существует несколько ошибок с HTTP-клиентом, а также он не использует собственные обработчики. Я использую Modern Http Client быстрее. –