1
votes

I am using below code to make an API call from my C# code with WebRequest:

public object GetData() 
{
 object response = "";
 string token = "EF232354";
 string baseUrl = ConfigurationManager.AppSettings["BaseURL"].ToString();
 string endPoint = ConfigurationManager.AppSettings["EndPoint"].ToString();

 var httpWebRequest = (HttpWebRequest) WebRequest.Create(baseUrl + endPoint);

 httpWebRequest.ContentType = "application/json";
 httpWebRequest.Method = HttpVerb.GET.ToString();
 httpWebRequest.Headers.Add("token", token);

 var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
 Stream dataStream = httpResponse.GetResponseStream();
 StreamReader reader = new StreamReader(dataStream);

 using(JsonReader sdr = new JsonTextReader(reader)) 
 {
  JsonSerializer serializer = new JsonSerializer();
  response = serializer.Deserialize(sdr);
 }
  return response;
}

Sometimes I am getting:

Message: The remote server returned an error: (504) Gateway Timeout.

Exception Type: System.Net.WebException

And how many requests can WebRequest make at a time?

1
How much data are you deserializing at any given time? I'd be a bit wary of feeding a response stream into a deserializer without knowing for sure the response data was compact and would read reasonably fast. You could try first reading the response stream into memory (memory stream) closing the response stream, then deserialize from the memory stream. This should help ensure the request/Response isn't open any longer than needed. - Steve Py
@StevePy Thanks for the suggestions, But sometimes it working without an issue - Prashant Pimpale
@StevePy Do I need to Dispose the object that request is using? Or Setting Timeout property? - Prashant Pimpale
I stream readers are disposable, so those should be disposed/using scoped. The "sometimes works, sometimes not" could easily be load determinate when the service is handling multiple requests or otherwise busy. The connection timeouts don't discriminate so you should aim to keep the response reads as quick as possible. - Steve Py
@StevePy any example with code? - Prashant Pimpale

1 Answers

1
votes

I was adapting the question to demonstrate reading to a memory stream, when I noticed that the response was not being disposed. This is 95% likely to be your underlying problem. Streams and StreamReaders are also disposable and should be wrapped with using() closures.

public object GetData() 
{
  object response = "";
  string token = "EF232354";
  string baseUrl = ConfigurationManager.AppSettings["BaseURL"].ToString();
  string endPoint = ConfigurationManager.AppSettings["EndPoint"].ToString();

  var httpWebRequest = (HttpWebRequest) WebRequest.Create(baseUrl + endPoint);

  httpWebRequest.ContentType = "application/json";
  httpWebRequest.Method = HttpVerb.GET.ToString();
  httpWebRequest.Headers.Add("token", token);

  using (var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse())
  {
    using (Stream dataStream = httpResponse.GetResponseStream())
    {
      using (StreamReader reader = new StreamReader(dataStream))
      {
        using(JsonReader sdr = new JsonTextReader(reader)) 
        {
          JsonSerializer serializer = new JsonSerializer();
          response = serializer.Deserialize(sdr);
        }
        return response;
      }
    }
    httpResponse.Close(); // For good measure. *should* be covered by Dispose.
  }
}