HttpWebRequest not answering - c#

Im trying to use HttpWebRequest on a WP7 application, but I have a problem. I never get a response from server :/
What am I doing wrong?
Here is the faulty code peace...
Util Class
public class RequestState
{
// This class stores the State of the request.
const int BUFFER_SIZE = 1024;
public string requestData;
public byte[] Data
{
get
{
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] encodedPostData = ascii.GetBytes(this.requestData);
return encodedPostData;
}
}
public byte[] BufferRead;
public HttpWebRequest request;
public HttpWebResponse response;
public RequestState()
{
BufferRead = new byte[BUFFER_SIZE];
requestData = string.Empty;
request = null;
}
}
The method...
private static ManualResetEvent allDone = new ManualResetEvent(false);
private static string PostRequest(string service, string email, string password, string source)
{
// Prepare request.
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(clientLoginUrl);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// Create an instance of the RequestState and assign the previous myHttpWebRequest1
// object to it's request field.
RequestState myRequestState = new RequestState();
myRequestState.request = request;
myRequestState.requestData = String.Format(postData, service, email, password, source);
// Get the response that will contain the Auth token.
try
{
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequestState);
}
catch (WebException ex)
{
HttpWebResponse faultResponse = ex.Response as HttpWebResponse;
if (faultResponse != null && faultResponse.StatusCode == HttpStatusCode.Forbidden)
throw new IncorrectUsernameOrPasswordException(faultResponse.StatusCode, faultResponse.StatusDescription);
else
throw;
}
// Keep the main thread from continuing while the asynchronous
allDone.WaitOne();
if (myRequestState.response != null)
{
// Check for login failed.
if (myRequestState.response.StatusCode != HttpStatusCode.OK)
throw new LoginFailedException(myRequestState.response.StatusCode, myRequestState.response.StatusDescription);
// Read.
using (StreamReader reader = new StreamReader(myRequestState.response.GetResponseStream()))
return reader.ReadToEnd();
}
else
return string.Empty;
}
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
RequestState requestState = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest request = (HttpWebRequest)requestState.request;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
// Write to the request stream.
postStream.Write(requestState.Data, 0, requestState.requestData.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), requestState);
}
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
RequestState requestState = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest request = (HttpWebRequest)requestState.request;
// End the operation
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
requestState.response = response;
allDone.Set();
}

Have you tried do a request to several different websites without luck?
I had this problem as well, and that was because I missed some header options to the request.
Try download a plugin for etc Mozilla that can sniff your request from the browser to the website, and then add those headers from the request to your headers in the HttpWebRequest.

Related

Xamarin Forms asmx webservice multiple calls

in my Project i call a Webservice like this:
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("**********");
req.Method = "POST";
req.ContentType = "application/json";
byte[] postDataAsBytesS = Encoding.UTF8.GetBytes(mobileJSON);
Stream postStreamS = req.GetRequestStream();
postStreamS.Write(postDataAsBytesS, 0, postDataAsBytesS.Length);
postStreamS.Flush();
postStreamS.Dispose();
WebResponse resS = req.GetResponse();
postStreamS = resS.GetResponseStream();
StreamReader srS = new StreamReader(postStreamS);
string responseFromServerS = srS.ReadToEnd();
public static class ExtensionsMethods
{
public static WebResponse GetResponse(this WebRequest request)
{
ManualResetEvent evt = new ManualResetEvent(false);
WebResponse response = null;
request.BeginGetResponse((IAsyncResult ar) => {
response = request.EndGetResponse(ar);
evt.Set();
}, null);
evt.WaitOne();
return response as WebResponse;
}
public static Stream GetRequestStream(this WebRequest request)
{
ManualResetEvent evt = new ManualResetEvent(false);
Stream requestStream = null;
request.BeginGetRequestStream((IAsyncResult ar) => {
requestStream = request.EndGetRequestStream(ar);
evt.Set();
}, null);
evt.WaitOne();
return requestStream;
}
}
When i call the above Reqeust 2 times at the same time, i get an error from the webservice.
I get following error:
{"Message":"Column \u0027*****\u0027 doesn't exist in the table.","StackTrace":" in System.Data.DataRow.GetDataColumn(String columnName)\r\n in System.Data.DataRow.get_Item(String columnName)\r\n in webserviceDWA.syncAndroidDWA.GetDWAPDFkategoriezuordnung(dwamobile[] mobile)","ExceptionType":"System.ArgumentException"}
But if i do the request only for 1 time, i get no error.
Can you help me?
Thanks.
I solved the problem.
I set the setting "Maximum number of work processes" of the application pool to 100.

Getting data back from an HttpWebRequest.BeginGetResponse callback

I am writing a Windows Phone 8 app that is supposed to send an GET+POST request to a server and parse the answer.
The code I am using to send the request and to get a response back is the following (it is written in a separate static class):
// server to POST to
string url = "http://myserver.com/?page=hello&param2=val2";
// HTTP web request
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
// Write the request Asynchronously
using (var stream = await Task.Factory.FromAsync<Stream>(httpWebRequest.BeginGetRequestStream,
httpWebRequest.EndGetRequestStream, null))
{
// Create the post data
string postData = "pseudo=pseudo&titre=test&texte=\"Contenu du message\"";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Write the bytes to the stream
await stream.WriteAsync(byteArray, 0, byteArray.Length);
stream.Close();
IAsyncResult ar = httpWebRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), httpWebRequest);
}
}
private static void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
{
string result = httpWebStreamReader.ReadToEnd();
//For debug: show results
System.Diagnostics.Debug.WriteLine(result);
}
My problem is : I have no idea how to get this answer (the string result) back in my behind-code in my app (or any other method in my app to be honest).
How could I do that?
You can try the following code,
string url = "http://myserver.com/?page=hello&param2=val2";
// HTTP web request
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
httpWebRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequest);
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
using (var postStream = webRequest.EndGetRequestStream(asynchronousResult))
{
//send yoour data here
}
webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);
}
void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest myrequest = (HttpWebRequest)asynchronousResult.AsyncState;
using (HttpWebResponse response = (HttpWebResponse)myrequest.EndGetResponse(asynchronousResult))
{
System.IO.Stream responseStream = response.GetResponseStream();
using (var reader = new System.IO.StreamReader(responseStream))
{
data = reader.ReadToEnd();
}
responseStream.Close();
}
}
catch (Exception e)
{
//Handle Exception
}
else
throw;
}
}
public static string GetPageAsString(Uri address)
{
string result = "";
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream(), Constants.EncodingType);
// Read the whole contents and return as a string
result = reader.ReadToEnd();
}
return result;
}
Does it have to be a static class? Because if you have a new webrequest object for each request, then each response will come back into it's own object.v
You need to put the result somewhere that you can access it from the place you want to use it.
e.g. if you put it into another public static variable member then you can read it off where you need to. But you probably need to signal the UI to action it, or bind it to the UI.
If you use a static place to store it, then you will only have one active at a time. Unless you add it to a static list of items or results that you are working with
See also: http://blogs.msdn.com/b/devfish/archive/2011/04/07/httpwebrequest-fundamentals-windows-phone-services-consumption-part-2.aspx
You can: make a global variable in App.xaml.cs:
public string result;
In code use it as
(App.Current as App).result = httpWebStreamReader.ReadToEnd();
If you will need to get notified in your current active page when the result is updated - use delegates after you get the response which will signal to your page.

Fetching Result from HTTP Response

I have the following C# class which initiates an HTTP request from a Windows Phone to a server:
public class Request
{
public string data;
public string result;
public Request()
{
}
public void doRequest(string parameters, string URL)
{
data = parameters;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
}
public void GetRequestStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
Stream postStream = myRequest.EndGetRequestStream(callbackResult);
byte[] byteArray = Encoding.UTF8.GetBytes(data);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest);
}
public void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream());
result = httpWebStreamReader.ReadToEnd();
}
Now, in my main class, I call the doRequest method to do an HTTP request from the Windows Phone:
Request req = new Request();
req.doRequest("function=LogIn&username=" + username + "&password=" + password, "http://localhost:4000/Handler.ashx");
When calling this method, how can I get the result (the result variable) from the server since it is received in the GetResponsetStreamCallback method and not in the doRequest method?
You have several possibilities. One would be to define property to make the result accessible outside. Define
public class Request
{
public string Result
{
get{
if(result != null && !string.IsNullOrEmpty(result))
return result;
return null;
}
}
...
}
You might create an event and have objects subscribe to it, so you can notice them when the asynchronous request has ended. Or make your calls synchronous, which is a little easier to do, as you don't have synchronize your calls and the requests from other objects.

WebRequest on windows phone 7

I have the following class (I take it from an example on the net, the only thing I've modified is that I use an IP address and port instead of a domain name):
public class ConnectionManager
{
private static ManualResetEvent allDone = new ManualResetEvent(false);
private string message = "foobar";
public Action MessageSent;
public Action<string> MessageReceived;
public void SendMessage()
{
// Create a new HttpWebRequest object.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://10.1.91.48:3330/");
request.ContentType = "application/json; charset=utf-8";
request.Accept = "application/json";
// Set the Method property to 'POST' to post data to the URI.
request.Method = "POST";
// start the asynchronous operation
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
MessageSent();
// Keep the main thread from continuing while the asynchronous
// operation completes. A real world application
// could do something useful such as updating its user interface.
allDone.WaitOne();
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(message);
// Write to the request stream.
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
Console.WriteLine(responseString);
// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
allDone.Set();
MessageReceived(responseString);
}
}
The code above fails to send the message. If I step, when I'm inside GetRequestStreamCallback I can see inside IAsyncResult the following error:
AsyncWaitHandle = 'asynchronousResult.AsyncWaitHandle' threw an
exception of type 'System.NotSupportedException'
What am I doing wrong? How can I fix this code?
While it's probably not the solution to your problem, you need to get into the habit of placing your IDisposable objects into using blocks, to ensure they get cleaned up even if exceptions happen:
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
using (Stream postStream = request.EndGetRequestStream(asynchronousResult))
{
byte[] byteArray = Encoding.UTF8.GetBytes(message);
// Write to the request stream.
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
}
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
string responseString;
using (HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(asynchronousResult))
{
using (Stream streamResponse = response.GetResponseStream())
{
using (StreamReader streamRead = new StreamReader(streamResponse))
{
responseString = streamRead.ReadToEnd();
Console.WriteLine(responseString);
}
}
}
allDone.Set();
MessageReceived(responseString);
}
As an alternative you could be using RestSharp.
http://restsharp.org/
It makes this sort of thing a lot more trivial. You have to make some slight changes to get it to work on the Windows Phone though:
http://www.tonicodes.net/blog/async-and-restsharp-for-windows-phone-7/
Nothing too crazy.
I ended up using WebClient:
WebClient wc = new WebClient();
wc.DownloadStringCompleted += ReadServerResponse;
wc.DownloadStringAsync(new Uri(url));

Create HTTP post request and receive response using C# console application

I need to post data to a URL (https://somesite.com) to download file in responseStrem based on the parameters I posted.
How can I do that using a C# console application?
Parameters:
filename,
userid,
password,
type
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace WebserverInteractionClassLibrary
{
public class RequestManager
{
public string LastResponse { protected set; get; }
CookieContainer cookies = new CookieContainer();
internal string GetCookieValue(Uri SiteUri,string name)
{
Cookie cookie = cookies.GetCookies(SiteUri)[name];
return (cookie == null) ? null : cookie.Value;
}
public string GetResponseContent(HttpWebResponse response)
{
if (response == null)
{
throw new ArgumentNullException("response");
}
Stream dataStream = null;
StreamReader reader = null;
string responseFromServer = null;
try
{
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
reader = new StreamReader(dataStream);
// Read the content.
responseFromServer = reader.ReadToEnd();
// Cleanup the streams and the response.
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (reader != null)
{
reader.Close();
}
if (dataStream != null)
{
dataStream.Close();
}
response.Close();
}
LastResponse = responseFromServer;
return responseFromServer;
}
public HttpWebResponse SendPOSTRequest(string uri, string content, string login, string password, bool allowAutoRedirect)
{
HttpWebRequest request = GeneratePOSTRequest(uri, content, login, password, allowAutoRedirect);
return GetResponse(request);
}
public HttpWebResponse SendGETRequest(string uri, string login, string password, bool allowAutoRedirect)
{
HttpWebRequest request = GenerateGETRequest(uri, login, password, allowAutoRedirect);
return GetResponse(request);
}
public HttpWebResponse SendRequest(string uri, string content, string method, string login, string password, bool allowAutoRedirect)
{
HttpWebRequest request = GenerateRequest(uri, content, method, login, password, allowAutoRedirect);
return GetResponse(request);
}
public HttpWebRequest GenerateGETRequest(string uri, string login, string password, bool allowAutoRedirect)
{
return GenerateRequest(uri, null, "GET", null, null, allowAutoRedirect);
}
public HttpWebRequest GeneratePOSTRequest(string uri, string content, string login, string password, bool allowAutoRedirect)
{
return GenerateRequest(uri, content, "POST", null, null, allowAutoRedirect);
}
internal HttpWebRequest GenerateRequest(string uri, string content, string method, string login, string password, bool allowAutoRedirect)
{
if (uri == null)
{
throw new ArgumentNullException("uri");
}
// Create a request using a URL that can receive a post.
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
// Set the Method property of the request to POST.
request.Method = method;
// Set cookie container to maintain cookies
request.CookieContainer = cookies;
request.AllowAutoRedirect = allowAutoRedirect;
// If login is empty use defaul credentials
if (string.IsNullOrEmpty(login))
{
request.Credentials = CredentialCache.DefaultNetworkCredentials;
}
else
{
request.Credentials = new NetworkCredential(login, password);
}
if (method == "POST")
{
// Convert POST data to a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(content);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
}
return request;
}
internal HttpWebResponse GetResponse(HttpWebRequest request)
{
if (request == null)
{
throw new ArgumentNullException("request");
}
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
cookies.Add(response.Cookies);
// Print the properties of each cookie.
Console.WriteLine("\nCookies: ");
foreach (Cookie cook in cookies.GetCookies(request.RequestUri))
{
Console.WriteLine("Domain: {0}, String: {1}", cook.Domain, cook.ToString());
}
}
catch (WebException ex)
{
Console.WriteLine("Web exception occurred. Status code: {0}", ex.Status);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return response;
}
}
}
Take a look at the System.Net.WebClient class, it can be used to issue requests and handle their responses, as well as to download files:
http://www.hanselman.com/blog/HTTPPOSTsAndHTTPGETsWithWebClientAndCAndFakingAPostBack.aspx
http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.90).aspx
For this you can simply use the "HttpWebRequest" and "HttpWebResponse" classes in .net.
Below is a sample console app I wrote to demonstrate how easy this is.
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
namespace Test
{
class Program
{
static void Main(string[] args)
{
string url = "www.somewhere.com";
string fileName = #"C:\output.file";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 5000;
try
{
using (WebResponse response = (HttpWebResponse)request.GetResponse())
{
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
byte[] bytes = ReadFully(response.GetResponseStream());
stream.Write(bytes, 0, bytes.Length);
}
}
}
catch (WebException)
{
Console.WriteLine("Error Occured");
}
}
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}
}
Enjoy!
HttpWebRequest request =(HttpWebRequest)WebRequest.Create("some url");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)";
request.Accept = "/";
request.UseDefaultCredentials = true;
request.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
doc.Save(request.GetRequestStream());
HttpWebResponse resp = request.GetResponse() as HttpWebResponse;
Hope it helps
Insted of using System.Net.WebClient I would recommend to have a look on System.Net.Http.HttpClient which was introduced with net 4.5 and makes your life much easier.
Also microsoft recommends to use the HttpClient on this article
http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.90).aspx
An example could look like this:
var client = new HttpClient();
var content = new MultipartFormDataContent
{
{ new StringContent("myUserId"), "userid"},
{ new StringContent("myFileName"), "filename"},
{ new StringContent("myPassword"), "password"},
{ new StringContent("myType"), "type"}
};
var responseMessage = await client.PostAsync("some url", content);
var stream = await responseMessage.Content.ReadAsStreamAsync();

Categories

Resources