http post request crashing - c#

I'm trying to excecute some post request, I censored the site because it has some sensitive data.. Well here's the code:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.someaddress.com");
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("sdata", ""));
try {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8));
Log.d("MyTag", "works till here.");
try {
HttpResponse response = httpclient.execute(httppost);
// String responseBody = EntityUtils.toString(response.getEntity());
// Log.d("MyTag", responseBody);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
It crashes on that line:
HttpResponse response = httpclient.execute(httppost);
Here's the logcat which really says nothing to me:
http://pastebin.com/F0YAiNLD
What could be the problem? Why is it crashing?
I'm trying to translate this C# code to JAVA. The C# code works but the JAVA code isn't.
Here's the C# code:
System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
string pData = "";
byte[] sdata = encoding.GetBytes(pData);
HttpWebRequest request = new HttpWebRequest(new Uri("http://www.someaddress.com"));
request.ContentType="application/x-www-form-urlencoded";
request.ContentLength = sdata.Length;
Stream nStream=request.GetRequestStream();
nStream.Write(sdata,0,sdata.Length);
nStream.Close();
HttpWebResponse response =
(HttpWebResponse) request.GetResponse();

I'm not an Android developer but a simple Google search for "Android NetworkOnMainThreadException" shows that this exception is thrown when you attempt to do network actions on the main event thread (the name is pretty self-descriptive), and that instead you should be making these type of network calls on a background thread.
Typically in GUI apps it is a bad idea to do work in the main thread that can block (such as a network HTTP call) since it will block the main animation loop.

Related

c# App skip after reading JSON response

I been trying to use an online API that returns an a json.
I am using winform application at the moment.
So far i tried
WebClient cHttp = new WebClient();
string htmlCode = cHttp.DownloadString(path); <--------
///-----------And then this
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(path);
request.Method = WebRequestMethods.Http.Get;
request.Accept = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); <-----
Where i point the arrow to, the program doesn't crash it just hit that line and then skip all the code below it. Then my form open without running my entire code. What am i doing wrong?
Thank you
Use try-catch block, and you'll see an error:
try
{
WebClient cHttp = new WebClient();
string htmlCode = cHttp.DownloadString(path);
}
catch(Exception e)
{
Debug.WriteLine(e);
}
It jumps out of your method. You must catch the exception and return null object. or find the error.

HttpWebResponse Returns 404 Error When Page Exists

I'm trying to write a small desktop application that will monitor a website through their API. I've never really done much work with APIs or WebRequests, so I'm unsure as to how to proceed with this error. After generating a requests, I try to GET the response from the page, but this returns a 404 error, even though if I navigate to the same URL in my browser it works fine. I have no idea how to get around this, and the research I've done on people who had the same problem hasn't helped me to understand it. Could someone explain to me what is happening at a basic level? My code has been posted below:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string sURL;
sURL = #"https://habitrpg.com/api/v1/user";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sURL);
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception ex)
{
resultText.Text = "Oh no!";
}
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
string responseData = readStream.ReadToEnd();
}
You should ignore https certificate, look at this question:
How do I use WebRequest to access an SSL encrypted site using https?

Sending a http request in C# and catching network issues

I previously had a small VBScript that would test if a specific website was accessible by sending a GET request. The script itself was extremely simple and did everything I needed:
Function GETRequest(URL) 'Sends a GET http request to a specific URL
Dim objHttpRequest
Set objHttpRequest = CreateObject("MSXML2.XMLHTTP.3.0")
objHttpRequest.Open "GET", URL, False
On Error Resume Next 'Error checking in case access is denied
objHttpRequest.Send
GETRequest = objHttpRequest.Status
End Function
I now want to include this sort of functionality in an expanded C# application. However I've been unable to get the same results my previous script provided.
Using code similar to what I've posted below sort of gets me a proper result, but fails to run if my network connection has failed.
public static void GETRequest()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://url");
request.Method = "GET";
HttpStatusCode status;
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
status = response.StatusCode;
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(status);
}
catch (WebException e)
{
status = ((HttpWebResponse)e.Response).StatusCode;
Console.WriteLine(status);
}
}
But as I said, I need to know if the site is accessible, not matter the reason: the portal could be down, or the problem might reside on the side of the PC that's trying to access it. Either way: I don't care.
When I used MSXML2.XMLHTTP.3.0 in the script I was able to get values ranging from 12000 to 12156 if I was having network problems. I would like to have the same functionality in my C# app, that way I could at least write a minimum of information to a log and let the computer act accordingly. Any ideas?
A direct translation of your code would be something like this:
static void GetStatusCode(string url)
{
dynamic httpRequest = Activator.CreateInstance(Type.GetTypeFromProgID("MSXML2.XMLHTTP.3.0"));
httpRequest.Open("GET", url, false);
try { httpRequest.Send(); }
catch { }
finally { Console.WriteLine(httpRequest.Status); }
}
It's as small and simple as your VBScript script, and uses the same COM object to send the request.
This code happily gives me error code like 12029 ERROR_WINHTTP_CANNOT_CONNECT or 12007 ERROR_WINHTTP_NAME_NOT_RESOLVED etc.
If the code is failing only when you don't have an available network connection, you can use GetIsNetworkAvailable() before executing your code. This method will return a boolean indicating if a network connection is available or not. If it returns false, you could execute an early return / notify the user, and if not, continue.
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()
using the code you provided above:
public static void GETRequest()
{
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
return; //or alert the user there is no connection
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://url");
request.Method = "GET";
HttpStatusCode status;
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
status = response.StatusCode;
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(status);
}
catch (WebException e)
{
status = ((HttpWebResponse)e.Response).StatusCode;
Console.WriteLine(status);
}
}
This should work for you, i've used it many times before, cut it down a bit for your needs: -
private static string GetStatusCode(string url)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = WebRequestMethods.Http.Get;
req.ProtocolVersion = HttpVersion.Version11;
req.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
try
{
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
StringBuilder sb = new StringBuilder();
foreach (string header in response.Headers)
{
sb.AppendLine(string.Format("{0}: {1}", header, response.GetResponseHeader(header)));
}
return string.Format("Response Status Code: {0}\nServer:{1}\nProtocol: {2}\nRequest Method: {3}\n\n***Headers***\n\n{4}", response.StatusCode,response.Server, response.ProtocolVersion, response.Method, sb);
}
catch (Exception e)
{
return string.Format("Error: {0}", e.ToString());
}
}
Feel free to ignore the section that gets the headers

Returning a HttpWebResponse ASP.Net MVC

I'm using a .Net MVC application as a simplified web service.
I've got an async method that I call:
public void RunQueue()
{
QueueDelegate queue = new QueueDelegate(Queue);
AsyncCallback completedCallback = new AsyncCallback(QueueCompleteCallback);
lock (_sync)
{
if (!queueIsRunning)
{
AsyncOperation async = AsyncOperationManager.CreateOperation(null);
queue.BeginInvoke(QueueCompleteCallback, async);
queueIsRunning = true;
}
}
}
and the hope is that when I call it, it starts the queue and then lets the user continue on with their day (they'll get an email when the queue's done).
As it stands right now, everything works fine except that instead of letting the user continue on, the webpage calling the "web service" just hangs and the request eventually times out.
How do I build an HttpWebResponse and send it back to the other server so that the user can continue on?
I've tried having it return things other than "void" but that doesn't do much.
Here's the Controller that's calling it.
public ActionResult StartQueue()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:2394/Home/RunQueue/");
HttpWebResponse response;
string r = "";
try
{
response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
r = reader.ReadToEnd();
}
catch (WebException ex) // A WebException is not fatal. Record the status code.
{
response = (HttpWebResponse)ex.Response;
if (response != null) // timeout
{
r = response.StatusCode.ToString();
}
}
ViewData["message"] = r;
return View();
}
What is the QueueDelegate class? My guess would be that the request is waiting for the other thread to complete (maybe something like Thread.Join()?). I don't think sending a response is the solution you want - I'd suggest either finding a way to spawn a thread that is disconnected from the current request so that it ends naturally, or move the logic out completely into something like a Windows Service.
Hosting your long-running processes in the web context will be complicated at best :(

Canonical HTTP POST code?

I've seen so many implementations of sending an http post, and admittedly I don't fully understand the underlying details to know what's required.
What is the succinct/correct/canonical code to send an HTTP POST in C# .NET 3.5?
I want a generic method like
public string SendPost(string url, string data)
that can be added to a library and always used for posting data and will return the server response.
I believe that the simple version of this would be
var client = new WebClient();
return client.UploadString(url, data);
The System.Net.WebClient class has other useful methods that let you download or upload strings or a file, or bytes.
Unfortunately there are (quite often) situations where you have to do more work. The above for example doesn't take care of situations where you need to authenticate against a proxy server (although it will use the default proxy configuration for IE).
Also the WebClient doesn't support uploading of multiple files or setting (some specific) headers and sometimes you will have to go deeper and use the
System.Web.HttpWebRequest and System.Net.HttpWebResponse instead.
As others have said, WebClient.UploadString (or UploadData) is the way to go.
However the built-in WebClient has a major drawback : you have almost no control over the WebRequest that is used behind the scene (cookies, authentication, custom headers...). A simple way to solve that issue is to create your custom WebClient and override the GetWebRequest method. You can then customize the request before it is sent (you can do the same for the response by overridingGetWebResponse). Here is an example of a cookie-aware WebClient. It's so simple it makes me wonder why the built-in WebClient doesn't handle it out-of-the-box...
Compare:
// create a client object
using(System.Net.WebClient client = new System.Net.WebClient()) {
// performs an HTTP POST
client.UploadString(url, xml);
}
to
string HttpPost (string uri, string parameters)
{
// parameters: name1=value1&name2=value2
WebRequest webRequest = WebRequest.Create (uri);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes (parameters);
Stream os = null;
try
{ // send the Post
webRequest.ContentLength = bytes.Length; //Count bytes to send
os = webRequest.GetRequestStream();
os.Write (bytes, 0, bytes.Length); //Send it
}
catch (WebException ex)
{
MessageBox.Show ( ex.Message, "HttpPost: Request error",
MessageBoxButtons.OK, MessageBoxIcon.Error );
}
finally
{
if (os != null)
{
os.Close();
}
}
try
{ // get the response
WebResponse webResponse = webRequest.GetResponse();
if (webResponse == null)
{ return null; }
StreamReader sr = new StreamReader (webResponse.GetResponseStream());
return sr.ReadToEnd ().Trim ();
}
catch (WebException ex)
{
MessageBox.Show ( ex.Message, "HttpPost: Response error",
MessageBoxButtons.OK, MessageBoxIcon.Error );
}
return null;
} // end HttpPost
Why are people using/writing the latter?

Categories