Я работаю над очисткой и обновлением некоторого устаревшего кода, который каждую минуту отправляет около 1 КБ данных на сервер. Сервер находится вне моего контроля, но всегда отвечает с HTTP 100 продолжить перед отправкой HTTP 200 OK
.
Старый код (см. Ниже) работает, но использует HttpWebRequest который не рекомендуется для новых разработок, поэтому я хотел бы обновить код, если это возможно. Код выполняется в фоновом режиме, поэтому нет необходимости в асинхронных вызовах.
Я написал новую реализацию устаревшего кода с помощью HttpClient, но он генерирует исключения. Я предполагаю, что исключение вызвано ответом HTTP 100 continue
сервера, поскольку отправка данных на другой тестовый сервер, который не использует этот ответ, работает нормально.
Устаревший код:
private void Legacy()
{
string s = "POSTDATA";
string output = "";
try
{
Encoding encoding1 = (Encoding)new ASCIIEncoding();
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://myurl.com");
httpWebRequest.Method = "POST";
httpWebRequest.Timeout = 10000;
httpWebRequest.Credentials = CredentialCache.DefaultCredentials;
byte[] bytes = encoding1.GetBytes(s);
httpWebRequest.Headers.Clear();
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = true;
httpWebRequest.Headers.Add("Accept-Language", "it");
httpWebRequest.Headers.Add("Cache-Control", "no-cache");
httpWebRequest.ContentLength = (long)s.Length;
Stream requestStream = httpWebRequest.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
Stream responseStream = httpWebRequest.GetResponse().GetResponseStream();
Encoding encoding2 = Encoding.GetEncoding("utf-8");
StreamReader streamReader = new StreamReader(responseStream, encoding2);
char[] buffer = new char[512];
streamReader.Read(buffer, 0, 512);
requestStream.Close();
requestStream.Dispose();
streamReader.Close();
streamReader.Dispose();
responseStream.Close();
responseStream.Dispose();
for (int index2 = 0; index2 < buffer.Length; ++index2)
output += buffer[index2].ToString();
MessageBox.Show(output);
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
Новый код:
private static readonly HttpClient _httpclient = new HttpClient();
private void NewCode()
{
_httpclient.Timeout = new TimeSpan(0, 0, 5);
_httpclient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
_httpclient.DefaultRequestHeaders.Add("Connection", "keep-alive");
_httpclient.DefaultRequestHeaders.Add("Accept-Language", "it");
var t = Task.Run(TEST);
t.Wait();
string tmp = t.Result;
MessageBox.Show(tmp);
}
private static async Task<String> TEST()
{
try
{
string s = "POSTDATA";
StringContent cont = new StringContent(s, Encoding.ASCII, "application/x-www-form-urlencoded");
HttpResponseMessage Req = await _httpclient.PostAsync("http://myurl.com", cont);
Req.EnsureSuccessStatusCode();
string Response = await Req.Content.ReadAsStringAsync();
return Response;
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
return "";
}
}
Исключение: Error while copying content to a stream.
Не исключение: Unable to read data from the transport connection: The connection was closed.
Отслеживание стека:
at System.Net.ConnectStream.EndRead(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.EndRead(IAsyncResult
asyncResult)
at
System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar)
Я проверил запросы и ответы обеих реализаций с Wireshark, и они абсолютно одинаковы, поэтому я предполагаю, что реализация с HttpClient где-то не так. Итак, мои вопросы:
- Есть ли проблема в моей реализации с HttpClient, или это фундаментальная проблема?
- Есть ли другой способ сделать это без использования устаревших вещей?
- Стоит ли вообще обновлять устаревший код?
Мне бы очень хотелось услышать ваши мысли по этому поводу.