Catching HttpWebRequest Timeout - c#

public int loginEmail(string email, string password)
{
HttpWebRequest request = null;
string responseStr = null;
string Email = email;
string Pass = password;
UTF8Encoding encoding = new UTF8Encoding();
string postData = "PostData";
byte[] data = encoding.GetBytes(postData);
request = (HttpWebRequest)WebRequest.Create("url");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.AllowAutoRedirect = false;
request.KeepAlive = false;
request.Proxy = null;
request.ServicePoint.ConnectionLimit = 1000;
request.ContentLength = data.Length;
request.Timeout = 5000;
request.ServicePoint.ConnectionLeaseTimeout = 5000;
request.ServicePoint.MaxIdleTime = 5000;
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
responseStr = response.Headers["Set-Cookie"];
}
}
catch
{
return 1;
}
string[] cooktemp;
string[] seperatortemp = new string[] { ";" };
cooktemp = responseStr.Split(seperatortemp, StringSplitOptions.None);
LoginHeaders[0] = cooktemp[0] + ";";
return 0;
}
This code runs just fine, but sometimes the request does not get a response back. When the request doesn't get a response back the program will hang and then finally it will give a timeout error that crashes the program. All I am trying to do right now is just catch the timeout error so I can handle it, but nothing seems to be catching it.

It is most likely timing out in GetRequestStream(). The documentation specifically states that it may throw WebException if the time-out period for the request expired.
So include that block of code inside your try/catch and you should be able to catch it.

This is an old thread, but an issue which I also hit today.
What I didn't realise is that if you have a web service which, say, attempts to write to a file which is locked... then having the code in a simple try..catch is not enough.
You must specifically have a catch which handles WebExceptions.
try
{
// Run your web service code
}
catch (WebException ex)
{
// Handle a WebException, such as trying to write to a "locked" file on the network
}
catch (Exception ex)
{
// Handle a regular Exception
}
I always thought that a WebException was a type of Exception, so these would get caught by this catch handler:
catch (Exception ex)
{
// Handle a regular Exception
}
It doesn't.
So to avoid your code throwing "Request timed out" messages, with no suggestion about what caused them, do remember to add these second catch handler.
Btw, on my web services tutorial, here's the code I recommend, which looks out for Exceptions, and returns them in the Response header:
try
{
// Put your code in here
}
catch (WebException ex)
{
// Return any exception messages back to the Response header
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
response.StatusDescription = ex.Message.Replace("\r\n", "");
return null;
}
catch (Exception ex)
{
// Return any exception messages back to the Response header
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
response.StatusDescription = ex.Message.Replace("\r\n", "");
return null;
}

try { ... }
catch (System.Net.WebException sne)
{
MessageBox.Show(req.Timeout.ToString());
}
I think the timeout will always be "5000" no matter what.
If you tell it "timeout is 5 seconds" it will always try for 5 seconds before giving up.

Related

HttpWebRequest.GetRequestStream() connection gets actively refused in executable but not in WPF standalone application

I am working with web server to make calls to its API via HttpWebRequests. I wrote a standalone WPF application for testing purposes and all of my requests were functioning correctly. When I referenced the working project file in my production application it is now returning that the request is being actively refused by the server.
public string Post(string xmlData, Transaction transaction)
{
var result = "";
try
{
var webReq = (HttpWebRequest)WebRequest.Create(BaseUrl);
webReq.Accept = "application/xml";
webReq.ContentType = "application/xml";
webReq.Method = "POST";
webReq.KeepAlive = false;
webReq.Proxy = WebRequest.DefaultWebProxy;
webReq.ProtocolVersion = HttpVersion.Version10;
// If we passed in data to be written to the body of the request add it
if (!string.IsNullOrEmpty(xmlData))
{
webReq.ContentLength = xmlData.Length;
using (var streamWriter = new StreamWriter(webReq.GetRequestStream())) /**CONNECTION REFUSED EXCEPTION HERE**/
{
streamWriter.Write(xmlData);
streamWriter.Flush();
streamWriter.Close();
}
}
else //Otherwise write empty string as body
{
webReq.ContentLength = 0;
var data = "";
using (var streamWriter = new StreamWriter(webReq.GetRequestStream()))
{
streamWriter.Write(data);
streamWriter.Flush();
streamWriter.Close();
}
}
//Attempt to get response from web request, catch exception if there is one
using (var response = (HttpWebResponse)webReq.GetResponse())
{
using (var streamreader =
new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException()))
{
result = streamreader.ReadToEnd();
}
}
return result;
}
catch (WebException e)
{
//Handle web exceptions here
}
catch (Exception e)
{
//Handle other exceptions here
}
}
Has anyone else encountered this problem?
After reviewing your fiddler requests I can say that the reason is probably the IP address difference.
You use 192.168.1.186:44000 first time and 192.168.1.86:44000 second time.

HttpWebRequest timeout handling

I have a really simple question. I am uploading files to a server using HTTP POST. The thing is I need to specially handle connection timeouts and add a bit of a waiting algorithm after a timeout has occurred to relive the server.
My code is pretty simple:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("SomeURI");
request.Method = "POST";
request.ContentType = "application/octet-stream";
request.KeepAlive = true;
request.Accept = "*/*";
request.Timeout = 300000;
request.AllowWriteStreamBuffering = false;
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
WebHeaderCollection headers = response.Headers;
using (Stream Answer = response.GetResponseStream())
{
// Handle.
}
}
}
catch (WebException e)
{
if (Timeout_exception)
{
//Handle timeout exception
}
}
I omitted the file reading code as it is not our concern. Now I need to make sure that once a WebException is thrown, I filter the exception to see if it is indeed a timeout exception. I thought of comparing against the exception message yet I am not sure if this is the right way since the application in question is a commercial app and I am afraid that the message varies between different languages. And what message should I be looking for.
Any suggestions?
You can look at WebException.Status. The WebExceptionStatus enum has a Timeout flag:
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
WebHeaderCollection headers = response.Headers;
using (Stream answer = response.GetResponseStream())
{
// Do stuff
}
}
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.Timeout)
{
// Handle timeout exception
}
else throw;
}
Using C# 6 exception filters can come in handy here:
try
{
var request = WebRequest.Create("http://www.google.com");
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
WebHeaderCollection headers = response.Headers;
using (Stream answer = response.GetResponseStream())
{
// Do stuff
}
}
}
catch (WebException e) when (e.Status == WebExceptionStatus.Timeout)
{
// If we got here, it was a timeout exception.
}
Yuval's answer is quite a direct hit but here's a version of mine which I've tried since I've undergone in the same circumstance if you want to target via Status codes:
catch (WebException ex)
{
var hwr = (HttpWebResponse)ex.Response;
if (hwr != null)
{
var responseex = hwr.StatusCode;
int statcode = (int)responseex;
if (statcode == 404)
{
Utility.Instance.log(logPath, "The file might not be availble yet at the moment. Please try again later or contact your system administrator.", true);
}
if (statcode == 401)
{
Utility.Instance.log(logPath, "Username and Password do not match.", true);
}
if (statcode == 408)
{
Utility.Instance.log(logPath, "The operation has timed out", true);
}
}
else
{
Utility.Instance.log(logPath, ex + ". Please contact your administrator.", true);//Or you can do a different thing here
}
}

c# sending json to website every 3 minutes issues

I have a windows app that sends a json to a website every 3 minutes. But I am not getting through to the web and I am not catching any exceptions which is strange. How it works.
Timer set to go off every 3min(180000milisecs)
timer1 = new System.Timers.Timer(180000);
timer1.Elapsed += new System.Timers.ElapsedEventHandler(onTimerEvent);
timer1.Start();
The timer calls a backround worker to run the update
//run the worker job every 3 minutes
private void onTimerEvent(object sender, EventArgs e)
{
minerQuery.RunWorkerAsync();
}
The worker calls the function to gather the data and then send the json
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string user_worker = textBox2.Text.Trim().ToLower() + ":" + textBox1.Text.Trim().ToLower();
bool logging = false;
if (this.radioButton1.Checked)
{
logging = true;
}
WorkerUpdate workerUpdate = new WorkerUpdate();
workerUpdate.update(user_worker, logging);
}
Once the function gathers the data in sends the request using this function
static void HttpPutRequest(string Json, bool logging)
{
try{
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https:/blah/here/update");
Request.ContentType = "application/json";
Request.Method = "PUT";
Request.Timeout = 120000; //not sure if correct
Stream dataStream = Request.GetRequestStream();
byte[] bytes = Encoding.UTF8.GetBytes(Json);
Request.ContentLength = bytes.Length;
dataStream.Write(bytes, 0, bytes.Length);
dataStream.Close();
HttpWebResponse response = (HttpWebResponse)Request.GetResponse();
Stream RdataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(RdataStream);
if (logging)
{
Logger("Sending JSON: " + Json);
Logger("To URL: " + Request.ToString());
Logger("Status: " + ((HttpWebResponse)response).StatusDescription);
Logger("Response: " + reader.ReadToEnd());
}
reader.Close();
RdataStream.Close();
response.Close();
}
catch (WebException we)
{
if (logging)
{
Logger("Web Expection Catch: " + we.ToString());
WebExceptionStatus status = we.Status;
if (status == WebExceptionStatus.ProtocolError)
{
HttpWebResponse http = (HttpWebResponse)we.Response;
Logger("The Server returned protocal Error: " + (int)http.StatusCode + " - " + http.StatusCode);
}
}
}
}
When I run my program it works and I see logging for other events. But when it comes to the http put request none of the logging in this code is every printed onto the screen. So I know something is going wrong. I put this code together from the MSDN examples which aren't the best.
Where I think the problem may be
Not sure if running this function under a timer event and a background worker is suppressing my expections?
Code to send http is not correct
HttpPutRequest is called here
this.wun = user_worker;
this.a = Convert.ToInt32(FindKey(SummaryQuery, "Accepted"), US);
this.r = Convert.ToInt32(FindKey(SummaryQuery, "Rejected"), US);
this.he = Convert.ToInt32(FindKey(SummaryQuery, "Hardware Errors"), US);
this.gs = gpuList.ToArray();
//create JSON from the workerUpdate object
string JSON = JsonConvert.SerializeObject(this);
//send to website
HttpPutRequest(JSON, logging);
Update
Running the code in debug mode I found this exception.
System.InvalidOperationException
from this line of code
Request.ContentLength = bytes.Length;
The InvalidOperationException is caused by calling GetRequestStream() before setting ContentLength
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.contentlength(v=vs.110).aspx
ContentLength: InvalidOperationException is thrown if the request has
been started by calling the GetRequestStream, BeginGetRequestStream,
GetResponse, or BeginGetResponse method.
Try:
byte[] bytes = Encoding.UTF8.GetBytes(Json);
Request.ContentLength = bytes.Length;
Stream dataStream = Request.GetRequestStream();
Edit:
As for the Logging issue is could be because you are accessing UI controls in the BackgroundWorkers thread. and because you are only catching WebExceptions the error will not be logged.
Try adding all exceptions also in your try catch to be sure
Example:
try
{
// all my cool logic
}
catch (WebException we)
{
// log WebException
}
catch (Exception ex)
{
// log other exceptions
}

Uri.IsWellFormedUriString returns true, but cannot read from a url

I am trying to check if the url http://master.dev.brandgear.net is valid by the following method:
private bool UrlIsValid(string url)
{
using (var webClient = new WebClient())
{
bool response;
try
{
webClient.UseDefaultCredentials = true;
using (Stream strm = webClient.OpenRead(url))
{
response = true;
}
}
catch (WebException we)
{
response = false;
}
return response;
}
}
However, I am getting a web exception "404 not found.". I have checked the uri with Uri.IsWellFormedUriString and it is returning true. However, the same url can be opened through a browser. Any idea how to validate it?
I ran your example with following URL http://master.dev.brandgear.net and exception is also raised. If you open same URL in browser (for example Firefox) and run Firebug plugin, open Network tab you will see error 404 (Page not found). Your code is OK, but server returns 404.
To really get a response, you have to use WebException instead of GetResponse or GetResponseStream methods when the 404 exception happens.Also use HttpWebRequest and HttpWebResponse in these situations for better control,so after the exception occurs you check its state to see if its a ProtocolError and if so get the response from there:
private bool UrlIsValid(string url)
{
bool response = false;
HttpWebResponse rep = null;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
rep = (HttpWebResponse)request.GetResponse();
}
catch (WebException we)
{
if (we.Status == WebExceptionStatus.ProtocolError)
rep = (HttpWebResponse)we.Response;
}
if (rep != null)
{
try
{
using (Stream strm = rep.GetResponseStream())
{
response = true;
}
}
catch (WebException ex)
{
//no need variable is already false if we didnt succeed.
//response = false;
}
}
return response;
}

C# How can I get server error from a URL?

We have a url and we need to check whether web page is active or not. We tried following code:
WebResponse objResponse = null;
WebRequest objRequest = HttpWebRequest.Create(URL);
objRequest.Method = "HEAD";
try
{
objResponse = objRequest.GetResponse();
objResponse.Close();
}
catch (Exception ex)
{
}
Above code gave exception if unable to get a response but also works fine even if we have a "server error" on that page? Any help how to get server error?
The HttpResponse class has a StatusCode property which you can check. If it's 200 everything is ok.
You can change your code to this:
HttpWebResponse objResponse = null;
var objRequest = HttpWebRequest.Create("http://google.com");
objResponse = (HttpWebResponse) objRequest.GetResponse();
if(objResponse.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine("It failed");
}else{
Console.WriteLine("It worked");
}
For one thing, use a using statement on the response - that way you'll dispose of it whatever happens.
Now, if a WebException is thrown, you can catch that and look at WebException.Response to find out the status code and any data sent back:
WebRequest request = WebRequest.Create(URL);
request.Method = "HEAD";
try
{
using (WebResponse response = request.GetResponse())
{
// Use data for success case
}
}
catch (WebException ex)
{
HttpWebResponse errorResponse = (HttpWebResponse) ex.Response;
HttpStatusCode status = errorResponse.StatusCode;
// etc
}

Categories

Resources