A Rest API call throws an exception on post. And that is
The remote server returned an error: (404) Not Found.
The following code calling the api
try
{
RestClient client = new RestClient(...);
string apiResponse = client.MakeRequest(..);
}
catch (WebException wex)
{
throw wex;
}
It works fine when the fiddler is capturing traffic. But if the fiddler is not capturing then client received the following exception.
The remote server returned an error: (502) Bad Gateway.
PS. Postman (Chrome extension) and Soap UI also received 404: Not Found
UPDATED:
This is the code and the error is received while debugging
public string MakeRequest(string parameters)
{
var request = (HttpWebRequest)WebRequest.Create(_RestEndPoint + (parameters ?? String.Empty));
request.Proxy = WebRequest.DefaultWebProxy;
request.ContentLength = 0;
request.Method = _Method.ToString();
request.ContentType = _ContentType;
request.KeepAlive = true;
if (_RequestHeader != null)
{
foreach (var hdr in _RequestHeader)
{
request.Headers.Add(hdr.Key, hdr.Value);
}
}
if (_Method == HttpVerb.POST || _Method == HttpVerb.PUT)
{
if (!string.IsNullOrEmpty(_PayLoad))
{
var bytes = Encoding.UTF8.GetBytes(_PayLoad);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
writeStream.Close();
}
}
}
using (var response = (HttpWebResponse)request.GetResponse())//Error returns here
{
var responseValue = string.Empty;
checkForResponseExceptions(response.StatusCode, parameters);
// grab the response
using (var responseStream = request.GetResponse().GetResponseStream())
{
if (responseStream != null)
{
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
}
return responseValue;
}
}
Can anyone please point out what am i missing?
Update 2:
I have tried the following code and have the same issue
if (_Method == HttpVerb.POST)
{
using (var wb = new WebClient())
{
wb.Headers[HttpRequestHeader.ContentType] = _ContentType;
foreach (var hdr in _RequestHeader)
{
wb.Headers.Add(hdr.Key, hdr.Value);
}
try
{
var response = wb.UploadString(_RestEndPoint + (parameters ?? String.Empty), _Method.ToString(), _PayLoad);
}
catch (Exception ex)
{
throw ex;
}
}
}
So, I guess something is wrong in the network settings as #GSerg commented on Dec 4 at 10:01. But there are no proxy set up in connection tab of IE settings. What and how should i check to get rid of this problem??
HTTP errors are grouped by "type of errors"
4xx errors are "client" errors, errors that are linked to the user doing a mistake, like 404 is the client asking for something that does not exist on the server.
5xx errors are "server" errors, meaning that the server had a problem answering the request, because of internal issues.
The 502 bad gateway is usually sent from a server when he couldn't get a request from another server. In your case, it could be coming from fiddler, because you're probably still making the query to fiddler who is stopped, and thus cannot answer.
Related
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.
I'm using WinForms and accessing my Restful webservice. For some reason the code after a while breaks, by giving the timeout error while connecting to the server.
The problem might also be due to my code design.
Here's my Restful client class
public class Restful
{
public string auth = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("MyUserName:MyPassword"));
public string POST(string parameters)
{
var request = (HttpWebRequest)WebRequest.Create("http://myserverdomain.com/api/webservice/someMethod");
byte[] byteArray = Encoding.UTF8.GetBytes(parameters);
request.Method = WebRequestMethods.Http.Post;
request.Headers["Authorization"] = this.auth;
request.ContentLength = byteArray.Length;
request.ContentType = "application/x-www-form-urlencoded";
Stream postStream = null;
try
{
// ERROR IS IN THIS LINE
postStream = request.GetRequestStream();
}
catch (WebException ex)
{
// I'm kind of creating an hack here..which isn't good..
if (ex.Status.ToString() == "ConnectFailure")
{
System.Threading.Thread.Sleep(1000);
this.POST(parameters);
}
}
if (postStream == null)
return string.Empty;
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
return responseValue;
using (var responseStream = response.GetResponseStream())
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
responseValue = reader.ReadToEnd();
return responseValue;
}
}
}
I'm receiving the error (after a few successfully send items):
Unable to connect to remote server
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond MyServerIpAddress
Sometimes I send thousands of items to the server, sometimes I only send 2 or 4. So I call this POST function within a loop.
try
{
foreach (app.views.Documents doc in DocumentsView)
{
var parameters = "key=" + doc.key;
parameters += "¶m1=" + doc.param1 + "¶m2=" + doc.param2;
/*
* Validates the response of Restful service.
* The response is always in JSON format.
*/
if (response(Restful.POST(parameters)) == false)
{
MessageBox.Show("Error while sending the ID: " + doc.id.ToString());
break;
};
}
}
catch (Exception ex)
{
MessageBox.Show("Error while sending documents: " + ex.Message);
}
You can change the default timeout of your HttpWebRequest to be some thing larger than the default, for example:
request.Timeout = 120000;
I think the default is 100 seconds.
You can also check this adjusting-httpwebrequest-connection-timeout-in-c-sharp
taking the failure at face value, it says that the remote machine didnt respond. Most likely causes
wrong name or ip address
windows firewall is on on the remote machine
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
}
}
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;
}
I'm trying to create a method in C# to return a string of a web pages html content from the url. I have tried several different ways, but I am getting the error System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive.
The following works fine locally, but gets the above error when running on a remote server:
public static string WebPageRead(string url)
{
string result = String.Empty;
WebResponse response = null;
StreamReader reader = null;
try
{
if (!String.IsNullOrEmpty(url))
{
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
response = request.GetResponse();
reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
result = reader.ReadToEnd();
}
}
catch (Exception exc)
{
throw exc;
}
finally
{
if (reader != null)
{
reader.Close();
}
if (response != null)
{
response.Close();
}
}
return result;
}
This is probably not the problem, but try the following:
public static string WebPageRead(string url)
{
if (String.IsNullOrEmpty(url))
{
return null;
}
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
if (request == null)
{
return null;
}
request.Method = "GET";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader =
new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
}
I echo the earlier answer that suggests you try this with a known good URL. I'll add that you should try this with a known good HTTP 1.1 URL, commenting out the line that sets the version to 1.0. If that works, then it narrows things down considerably.
Thanks for the responses, the problem was due to a DNS issue on the remote server! Just to confirm, I went with the following code in the end:
public static string WebPageRead(string url)
{
string content = String.Empty;
if (!String.IsNullOrEmpty(url))
{
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
if (request != null)
{
request.Method = "GET";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
try
{
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
content = reader.ReadToEnd();
}
}
}
}
catch (Exception exc)
{
throw exc;
}
}
}
return content;
}
Had a problem like this before that was solved by opening the url in IE on the machine with the problem. IE then asks you whether you want to add the url to the list of secure sites. Add it and it works for that url.
This is just one of the possible causes. Seriously a lot of other problems could cause this. Besides the problem described above, the best way I've found to solve this is the just catch the exception and retry the request.