Returning Stream from WebRequest - c#

I'm having an issue when i return a Stream from a WebRequest, it says that the stream was closed, when i have everything in the same method then it works here is the code example:
public static Stream MethodOne()
{
Uri uri = new Uri(url, true);
WebRequest request = WebRequest.Create(uri);
request.Method = "GET";
Stream responseStream = null;
using (WebResponse webResponse = request.GetResponse())
{
responseStream = webResponse.GetResponseStream();
}
}
The other method is:
public static XDocument MethodTwo()
{
Stream stream = MethodOne();
if (stream == null)
{
return null;
}
XmlReader xmlReader = XmlReader.Create(stream);
return XDocument.Load(xmlReader);
}
The error that i get is where i try to create an xmlReader from the stream with the following message: The request was aborted: The connection was closed unexpectedly.
Any idea how to resolve it?

your using statement calls Dispose on the Response before you read the stream.
I would return the WebResponse from Method one.
public static XDocument MethodTwo()
{
WebResponse response = MethodOne();
if (response == null)
{
response null;
}
try
{
var stream = response.GetResponseStream();
XmlReader xmlReader = XmlReader.Create(stream);
return XDocument.Load(xmlReader);
}
finally
{
response.Dispose();
}
}
Update: Better solution
public static XDocument MethodTwo()
{
using (var response = MethodOne())
using (var stream = response.GetResponseStream())
{
var stream = response.GetResponseStream();
XmlReader xmlReader = XmlReader.Create(stream);
return XDocument.Load(xmlReader);
}
}
public static Stream MethodOne()
{
Uri uri = new Uri(url, true);
WebRequest request = WebRequest.Create(uri);
request.Method = "GET";
return request;
}
This will ensure that your resources are disposed (even if an exception occures).

As SchlaWiener pointed out, the problem you're facing is that the using statement calls Dispose() on the stream before you can read the stream. You should refactor your code as follows:
public static Stream GetResponseStream()
{
var uri = new Uri(url, true);
WebRequest request = WebRequest.Create(uri);
request.Method = WebRequestMethods.Http.Get;
WebResponse response = request.GetResponse();
return response.GetResponseStream();
}
public static XDocument GetXDocument()
{
using(Stream stream = GetResponseStream())
{
XmlReader xmlReader = XmlReader.Create(stream);
return XDocument.Load(xmlReader);
}
}
This way, you'll make sure the stream is closed only after the read.

Related

WebRequest WebResponse Operation has timed out

I have several Http Web Requests in various loops etc. The web requests get data from a variety of APIs.
These seem to work some of the time, but most of the time (recently) I am getting Timeout exception errors (Operation has timed out) and am not sure why.
I accept that every so often or once in a while you will get a time out error, but this is happening too often.
Here are two of my WebRequest codes:
public static EventList getEvents()
{
Uri myURI = new Uri("http://feeds.betway.com/events?key=XXX&keywords=horse-racing,uk-and-ireland&and=true");
WebRequest webRequest = WebRequest.Create(myURI);
webRequest.Timeout = 3000;
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream stream = webResponse.GetResponseStream())
{
using (var reader = XmlReader.Create(stream))
{
XmlSerializer serializer = new XmlSerializer(typeof(EventList));
EventList data = (EventList)serializer.Deserialize(reader);
return data;
}
}
}
}
public static List<WilliamHillData.Event> GetAllCompetitionEvents(string compid)
{
string res = "";
Uri myURI = new Uri("https://gw.whapi.com/v2/sportsdata/competitions/" + compid + "/events/?&sort=startDateTime");
WebRequest webRequest = WebRequest.Create(myURI);
webRequest.Headers.Add("Content-Type", "application/json");
webRequest.Headers.Add("apiKey", "xxx");
webRequest.Timeout = 2000;
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream stream = webResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
res = reader.ReadToEnd();
}
}
JObject jobject = JObject.Parse(res);
List<WilliamHillData.Event> list = jobject["events"].ToObject<List<WilliamHillData.Event>>();
return list;
}
I cannot see anything wrong with my code as I am disposing objects correctly and have set the Timeout. Does the timeout need increasing or am I missing something?
Could this also possibly be a network issue on our end?

Getting The remote server returned an error: (504) Gateway Timeout for WebAPI

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?
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.
}
}

The magic number in GZip header is not correct. Make sure you are passing in a GZip stream getting this error

i am working on asp.net webform to passing json string on a url for authenticate but getting error in Gzip.
here is my method to post data
private static string GetResponse(string requestData, string url)
{
string responseXML = string.Empty;
try
{
byte[] data = Encoding.UTF8.GetBytes(requestData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("Accept-Encoding", "gzip");
Stream dataStream = request.GetRequestStream();
dataStream.Write(data, 0, data.Length);
dataStream.Close();
WebResponse webResponse = request.GetResponse();
var rsp = webResponse.GetResponseStream();
if (rsp == null)
{
//throw exception
}
using (StreamReader readStream = new StreamReader(new GZipStream(rsp, CompressionMode.Decompress)))
{
responseXML = JsonConvert.DeserializeXmlNode(readStream.ReadToEnd()).InnerXml;
}
}
catch (WebException webEx)
{
//get the response stream
WebResponse response = webEx.Response;
Stream stream = response.GetResponseStream();
String responseMessage = new StreamReader(stream).ReadToEnd();
}
finally
{
}
return responseXML.ToString();
}
getting this error while i am passing the json object and url
enter image description here

Web service request time out issue

I want to interact with a web service, and for this purpose I am using this code.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(#"http://192.168.2.51/loodappSrv/LoodAppsrv.svc/company/insertcompany?Validation_Token=dc6f3d5e-22c7-405f-abb6-4491de140e7e");
req.Method = "POST";
req.ContentType = #"text/json";
JsonComapnyFormat jcf = new JsonComapnyFormat();
string data = jcf.data();//data in json Format {"companyName":"Alpha","departmentId":3}
using (Stream requestStream = req.GetRequestStream())
{
StreamWriter streamWriter = null;
try
{
//streamWriter = new StreamWriter(requestStream, System.Text.Encoding.Default);
streamWriter = new StreamWriter(requestStream, System.Text.Encoding.Default);
streamWriter.Write(data);
}
catch (Exception ex)
{
throw ex;
}
finally
{
try
{
streamWriter.Close();
requestStream.Close();
streamWriter.Dispose();
streamWriter = null;
requestStream.Dispose();
}
catch
{
}
}
}
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
var result = reader.ReadToEnd();
ViewBag.ABC = result;
return View();
If I Use Fiddler to send POST data on the given URL, it is perfect (sudden response comes out). But when I send same date on the same URL then the message return in an exception "The operation has timed out" at HttpWebResponse response = (HttpWebResponse)req.GetResponse();. Please suggest solutions.
Have you tried what SLaks mentioned ?
The MIME media type for JSON text is application/json.
As can be seen here

Easiest way to read the response from WebResponse

private void RespCallback(IAsyncResult asynchronousResult)
{
try
{
WebRequest myWebRequest1 = (WebRequest)asynchronousResult.AsyncState;
// End the Asynchronous response.
WebResponse webResponse = myWebRequest1.EndGetResponse(asynchronousResult);
}
catch (Exception)
{
// TODO:Log the error
}
}
Now having the webResponse object, what is the easiest way to read its contents?
I would simply use the async methods on WebClient - much easier to work with:
WebClient client = new WebClient();
client.DownloadStringCompleted += (sender,args) => {
if(!args.Cancelled && args.Error == null) {
string result = args.Result; // do something fun...
}
};
client.DownloadStringAsync(new Uri("http://foo.com/bar"));
But to answer the question; assuming it is text, something like (noting you may need to specify the encoding):
using (var reader = new StreamReader(response.GetResponseStream()))
{
string result = reader.ReadToEnd(); // do something fun...
}
Here is one way to do it if the response is coming in from XML.
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("https://www.yoururl.com");
WebResponse response = myReq.GetResponse();
Stream responseStream = response.GetResponseStream();
XmlTextReader reader = new XmlTextReader(responseStream);
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Text)
{
Console.WriteLine("{0}", reader.Value.Trim());
}
Console.ReadLine();
}
internal string Get(string uri)
{
using (WebResponse wr = WebRequest.Create(uri).GetResponse())
{
using (StreamReader sr = new StreamReader(wr.GetResponseStream()))
{
return sr.ReadToEnd();
}
}
}

Categories

Resources