Наконец я смог решить проблему. Проблема была из-за того, что сервер обновил свой SSL до TLS 1.2 с сертификатом AES128. Я изменил webclient на httpclient и избегал использования блока.
using(var client = new HttpClient())
{
//I removed this code as using block code serves only one time
// And was failing for next subsequent request
}
Я много искал и обнаружил, что если вы используете HttpClient в использовании блока, тогда объект будет удален, но TCP-соединение останется открытым. Это не будет закрыто. Таким образом, вышеприведенный подход работал для одного запроса, а следующие последующие запросы не выполнялись из-за этой проблемы.
Итак, я следовал нижеследующему подходу, и наконец мой код теперь работает как charm.
Я инициализировал HttpClient объект как stati c в моем классе
private static HttpClient httpClient = new HttpClient();
Затем я вызвал это для своих обобщенных c классов, передал всю информацию ему и он вернул мне желаемые результаты.
Ниже приведен полный рабочий код:
public class MyWebClientServices
{
private static HttpClient httpClient = new HttpClient();
public T PrepareWebClient<T>(string preparedURL)
{
try
{
// As my server is using TLS1.2 I kept only that protocol
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualtiyHeaderValue("application/json");
var json = httpClient.GetStringAsync(preparedURL).Result;
//here T is generic PCR class. I have created generic classes for which I need to invoke httpClient & their respective urls as I want to use this same code for all.
//If your class is not generic then instead of T you can use your class
T tJson = JsonConvert.DeserializeObject<T>(json);
return (T)Convert.ChangeType(tJson, typeof(T));
//finally my issue has been fixed and I'm getting data on all subsequent requests too
}
catch(Exception e)
{
throw e;
}
}//end of MyWebClientServices class
Я ссылался ниже на блог, в котором есть вся информация, связанная с этой проблемой: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
2) Если вы создаете одноэлементный шаблон для httpClient и совместно используете его, то он также имеет серьезное поведение.
То есть HttpClientHandler создает группу соединений (названную с помощью своего хэш-кода) и не закрыть соединения в группе, пока не утилизируется. По сути, это означает, что проверка DNS никогда не происходит, пока соединение открыто.
Наивным решением было бы избавляться от HttpClient (отсюда и HttpClientHandler) каждый раз, когда вы его используете.
Другое решение это установить свойство ConnectionClose для DefaultRequestHeaders на вашем HttpClient:
var client = new HttpClient();
client.DefaultRequestHeaders.ConnectionClose = true;
Это установит для заголовка keep-alive HTTP значение false, поэтому сокет будет закрыт после одного запроса. Оказывается, это может добавить примерно 35 мс (с длинными хвостами, то есть усиливающимися выбросами) к каждому из ваших HTTP-вызовов, не позволяя вам воспользоваться преимуществами повторного использования сокета. Итак, каково решение тогда?
Теперь, чтобы исправить это, все, что нам нужно сделать, это получить объект ServicePoint для конечной точки, передав ему URL-адрес и установив ConnectionLeaseTimeout:
var sp = ServicePointManager.FindServicePoint(new Uri("http://foo.bar/baz/123?a=ab"));
sp.ConnectionLeaseTimeout = 60*1000; // 1 minute
Вторая часть, которую я не использовал, но в случае, если кто-то хочет использовать шаблон синглтона, тогда публикуем здесь. Более подробную информацию можно получить в блоге ниже. Важная часть, которую я разместил здесь, на случай, если в будущем ссылка будет разорвана: http://byterot.blogspot.com/2016/07/singleton-httpclient-dns.html
Надеюсь, это поможет кому-то, кто застрял как я.