httpWebRequest using POST method - receive unexpected xml response - windows-phone-7

I need to use POST to post a string to server and get xml response, the status code is OK but the string reponse is always ="" (0 byte). Is there any thing wrong with my code? I check the server from blackberry, works fine so the problem must come from my code:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
s = NavigationContext.QueryString["parameter1"];
//string strConnectUrl = "http://www.contoso.com/example.aspx";
base.OnNavigatedTo(e);
// DoWebClient(s);
try
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(strConnectUrl);
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
// start the asynchronous operation
httpWebRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), httpWebRequest);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
// string XML_REQUEST = "<?xml version=\"1.0\"?><mybroker"><getConnections></mybroker>";
string post = "?&track=love";
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
// Convert the string into a byte array.
byte[] postBytes = Encoding.UTF8.GetBytes(post);
// Write to the request stream.
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
static Stream str;
static string st;
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
HttpStatusCode rcode = response.StatusCode;
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
//****THIS ALWAYS RETURN "" VALUE, EXPECT TO RETURN XML STRING****
string responseString = streamRead.ReadToEnd();
//Console.WriteLine(responseString);
// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
}
*EDIT**
The code work, however the server return parameter require the Ampersand(&) which is not allow in silverlight framework I think, remove the & char server response but the result wasn't correct. I will ask a new question refer this Ampersand

Have checked your call using Fiddler. The server is returning an empty body. Your code is working correctly. The problem is server side.

The post value should be "track=love".
I tried and it worked but the response is gzip encoded.

Fiddler says that the request is good, and that the response really is blank. If it's working from Blackberry and not from WP7, could the server be doing some user agent checking and not returning anything because it doesn't recognize the WP7 user agent?
Also, it looks like you're POSTing a query string ("?&track=love") which is sort of unusual. Are you sure that's the right data to be sending in your request?

Related

webRequest.GetRequestStream throws exception when calling from AP.Net Webapi

I need to call a third party legacy service with XML payload as a POST request from Asp.net Web API but I get an exception, it works fine from Console program. Any idea how to achieve this will be greatly appreciated.
Exception on execution of code line
Stream dataStream = webRequest.GetRequestStream() in the SubmitRequest():
The underlying connection was closed: An unexpected error occurred on a send.
Inner Exception: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
To test this I just called the SubmitRequest() private method from Home\Index action with a valid url on line WebRequest.Create.
I have put a fake url (https://test.legacy3rdparty.com/API/API.aspx) instead of real one here in the question. But it is "https" url.
private static void SubmitRequest(string request)
{
byte[] dataToSend = Encoding.UTF8.GetBytes(request);
// Change the following URL to point to production instead of integration
WebRequest webRequest = WebRequest.Create("https://test.legacy3rdparty.com/API/API.aspx");
webRequest.Method = "POST";
webRequest.ContentLength = dataToSend.Length;
webRequest.ContentType = "text/xml";
try
{
Stream dataStream = webRequest.GetRequestStream(); //THIS LINE CAUSES THE EXCEPTION
dataStream.Write(dataToSend, 0, dataToSend.Length);
dataStream.Close();
string response = string.Empty;
try
{
WebResponse apiResponse = webRequest.GetResponse();
using (StreamReader sr = new StreamReader(apiResponse.GetResponseStream()))
{
response += sr.ReadToEnd();
}
}
catch (WebException wex)
{
HttpWebResponse httpResponse = wex.Response as HttpWebResponse;
using (Stream responseStream = httpResponse.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
response = reader.ReadToEnd();
}
}
}
catch (Exception ex)
{
throw;
}
// Call Parse Function for the XML response
//ParseResponse(response);
}
This had to do with TLS handshaking. So when I updated the .net run time target framework in the in Web.config file to 4.6 it worked.
<system.web>
<httpRuntime targetFramework="4.6" />
</system.web>

Loading issue in WebBrowser control for httpwebresponse in WP7 & 8

I am trying to load web browser with the html code from the httpwebresponse by storing it in a string variable.
I created a httpwebrequest for a URL by setting cookies in it and getting a html page in a httpwebResponse.
I am trying to display it in a web browser control by saving the code in a string variable. And navigating the browser("browse.NavigateToString(string)").
But here page is not loaded properly.It is not displaying any css or images and displaying a message"You need to turn on java script in order to display the contents".
I made the web browser property (IsScriptEnabled ) true before navigation. But it is still showing the message and contents are not loaded properly.
Cookies are also not injected in to the web browser controls(session is not maintained through out the app).
Is there any solution or work around for this ??
Please refer to the below code :
To log cookies from login service :
private void PostLoginRequest()
{
string AuthServiceUri = "Service URL";
HttpWebRequest AuthReq = HttpWebRequest.Create(AuthServiceUri) as HttpWebRequest;
AuthReq.CookieContainer = new CookieContainer();
AuthReq.ContentType = "application/x-www-form-urlencoded";
AuthReq.Method = "POST";
AuthReq.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), AuthReq);
}
void GetRequestStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest Request = (HttpWebRequest)callbackResult.AsyncState;
Stream postStream = Request.EndGetRequestStream(callbackResult);
string postData = "Postdata parameters";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), Request);
}
void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
try
{
HttpWebRequest callBackRequest = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
CookieCollection cookiecollec = new CookieCollection();
cookiecollec = response.Cookies;
App.cookieCollection = cookiecollec; //global varaiable
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Another httpwebrequest with logged cookies :
private void ResponsivePostURL(string PageName, string PostURL, string PostDatas)
{
Uri ServiceUri = new Uri(PostURL); //Service URL
HttpWebRequest requestURL = HttpWebRequest.CreateServiceUri as HttpWebRequest;
requestURL.ContentType = "application/x-www-form-urlencoded";
requestURL.Method = "POST";
requestURL.CookieContainer = new CookieContainer();
requestURL.CookieContainer.Add(ServiceUri, App.cookieCollection);
requestURL.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), requestURL);
}
void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
// MessageBox.Show(response.Cookies.ToString());
string responseString = "<html><head></head><body>";
Stream streamResponse = response.GetResponseStream();
StreamReader reader = new StreamReader(streamResponse);
responseString = responseString + reader.ReadToEnd() + "</body></html>";
streamResponse.Close();
reader.Close();
response.Close();
this.Dispatcher.BeginInvoke(() =>
{
webBrowser.IsScriptEnabled = true;
webBrowser.NavigateToString(responseString);
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
When you navigate to the site and save the document, you are not getting the script, css nor image files (and any other resource for that matter) but only the static/generated HTML document as-is, which probably refer to those files using relative paths. If paths are not absolute, scripts/css/images/other resources are not found.
If you want to make it work, you need to replace relative paths with absolute paths within the HTML file.
So if you have
<script src="/scripts/cool.js"></script>
You'd replace it with
<script src="http://www.thesite.com/scripts/cool.js"></script>
(Note that this is just my best guess, not something I have actually tried out :)

How to send data using webrequest class method?

In my application I send data to a PHP server. I got code from the msdn website.
void SendPost()
{
var url = "http://www.nuatransmedia.com/ncampaign/mailserver/mail1.php";
// Create the web request object
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
// Start the request
webRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequest);
}
void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
// End the stream request operation
Stream postStream = webRequest.EndGetRequestStream(asynchronousResult);
// Create the post data
// Demo POST data
string postData = "Hello";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the web request
webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);
}
void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response;
// End the get response operation
response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamReader = new StreamReader(streamResponse);
var Response = streamReader.ReadToEnd();
streamResponse.Close();
streamReader.Close();
response.Close();
}
catch (WebException e)
{
// Error treatment
// ...
}
}` void SendPost()
{
var url = "http://www.nuatransmedia.com/ncampaign/mailserver/mail1.php";
// Create the web request object
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
// Start the request
webRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequest);
}
void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
// End the stream request operation
Stream postStream = webRequest.EndGetRequestStream(asynchronousResult);
// Create the post data
// Demo POST data
string postData = "Hello";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the web request
webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);
}
void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response;
// End the get response operation
response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamReader = new StreamReader(streamResponse);
var Response = streamReader.ReadToEnd();
streamResponse.Close();
streamReader.Close();
response.Close();
}
catch (WebException e)
{
// Error treatment
// ...
}
}
I got mail. But the body messages not show in my mail. Where did I make a mistake? In my PHP code I use postData variable to get my message.
For simpler HTTP usage the classes at http://mytoolkit.codeplex.com/wikipage?title=Http might help you...
These classes help to HTTP POST files (access via $_FILES["..."]). Also there is a RawData property (byte[]) to set the data directly.
(also GZIP, own timeout, and more is supported)

how to make HTTP POST using reactive extension on windows phone 7

I found an example about HTTP POST in msdn, but I am wondering how can I make use of reactive extensions here.
using System;
using System.Net;
using System.IO;
using System.Text; using System.Threading;
class HttpWebRequestBeginGetRequest
{
private static ManualResetEvent allDone = new ManualResetEvent(false);
public static void Main(string[] args)
{
// Create a new HttpWebRequest object.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/example.aspx");
request.ContentType = "application/x-www-form-urlencoded";
// 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);
// 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 static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
Console.WriteLine("Please enter the input data to be posted:");
string postData = Console.ReadLine();
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Write to the request stream.
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private static 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();
}
}
I am trying to use the following code, but it does not work. Can anyone help me out on this?
Thanks in advance -Peng
return (from request in
Observable.Return((HttpWebRequest)WebRequest.Create(new Uri(postUrl))).Catch(Observable.Empty<HttpWebRequest>())
.Do(req =>
{
// Set up the request properties
req.Method = "POST";
req.ContentType = contentType;
req.UserAgent = userAgent;
req.CookieContainer = new CookieContainer();
Observable.FromAsyncPattern<Stream>(req.BeginGetRequestStream, req.EndGetRequestStream)()
.ObserveOnDispatcher()
.Subscribe(stream =>
{
stream.Write(formData, 0,
formData.Length);
stream.Close();
})
;
})
from response in
Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)().Catch(Observable.Empty<WebResponse>())
from item in GetPostResponse(response.GetResponseStream()).ToObservable().Catch(Observable.Empty<string>())
select item).ObserveOnDispatcher();
Edit: To make it clear, I want to use the rx to implement the same logic in MSDN example.
in the MSDN example, it seems it first makes async call to write RequestStream, and then in the GetRequestStreamCallback, fires another async call to get the response.
Using Rx, I am able to create 2 observables
1. Observable.FromAsyncPattern(request.BeginGetRequestStream, request.EndGetRequestStream)()
2. Observable.FromAsyncPattern(request.BeginGetResponse, request.EndGetResponse)()
The problem is the second observable depends on the first one's result, so how can I do this in Rx?
In the first observable's subcribe method to create the seond observable? is it the good way?
This is how I am doing it. I configure the two Async patters up front, then use SelectMany to chain them together.
I have cut out the error handling etc from this code to keep it simple and show only the bare minimum to get it working. You should append a .Catch() similar to your own code, and if you want to get more than just a string out (say the response code) then you'll need to create a class/struct to hold all the bits of data you need and return that instead.
public IObservable<string> BeginPost(Uri uri, string postData) {
var request = HttpWebRequest.CreateHttp(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var fetchRequestStream = Observable.FromAsyncPattern<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream);
var fetchResponse = Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse);
return fetchRequestStream().SelectMany(stream => {
using (var writer = new StreamWriter(stream)) writer.Write(postData);
return fetchResponse();
}).Select(result => {
var response = (HttpWebResponse)result;
string s = "";
if (response.StatusCode == HttpStatusCode.OK) {
using (var reader = new StreamReader(response.GetResponseStream())) s = reader.ReadToEnd();
}
return s;
});
}
Your problem is your use of Do() here, you need to move the GetRequestStream into your SelectMany (into your "from bla in, from bla in"...), since it only makes sense to get the response stream after you've written the full request. Right now, you're trying to do both concurrently.

How to get async result in main thread

I'm making a login page on Windows Phone 7 app. I'd like to get login error status code on the login page when login error message return from server on async thread.
So my question is :
In bellow code sample, please let me know how do you get "responseString(string)" in Main method?
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetrequeststream.aspx
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Threading;
class HttpWebRequestBeginGetRequest
{
private static ManualResetEvent allDone = new ManualResetEvent(false);
public static void Main(string[] args)
{
// Create a new HttpWebRequest object.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/example.aspx");
request.ContentType = "application/x-www-form-urlencoded";
// 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);
// 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();
/* I'd like to get "responseString" here. */
}
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
Console.WriteLine("Please enter the input data to be posted:");
string postData = Console.ReadLine();
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Write to the request stream.
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private static 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(); /* I'd like to get this responseString in Main method. */
Console.WriteLine(responseString);
// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
allDone.Set();
}
}
You could just define responseString as a class-level variable instead of defining it within the GetResponseCallback method. That way, it can be accessed from anywhere in the class, rather than just the method scope.
To navigate to another page from a background thread, you can use a Dispatcher.
//Method to move to next page. Can be called from GetResponseCallBack
private void NavigateToNextPage()
{
Dispatcher.BeginInvoke(() =>
{
NavigationService.Navigate(new Uri("Page2.xaml", UriKind.Relative"));
});
}

Resources