1

I a newbie at windows 8 phone development. I want to send an aync HTTP POST Request to a PHP web service with some headers and XML in the request body.

Also, I want to read the response sent back by the PHP web service.

Please guide me, how can I achieve the above two stated things.


what I have tried until now i am giving below

// Main begins program execution. public static void SendRequest() { HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://mytestserver.com/Test.php"); webRequest.Method = "POST"; webRequest.ContentType = "text/xml"; webRequest.Headers["SOURCE"] = "WinApp"; var response = await httpRequest(webRequest); } public static async Task<string> httpRequest(HttpWebRequest request) { string received; using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null))) { using (var responseStream = response.GetResponseStream()) { using (var sr = new StreamReader(responseStream)) { received = await sr.ReadToEndAsync(); MessageBox.Show(received.ToString()); } } } return received; } 

I am able to send the request using the above code. I just need to know that how I can send the XML in the request body to my web service.

4
  • Use webRequest.GetRequestStream() and write your xml to that stream. Commented Aug 20, 2013 at 9:03
  • 1
    there is no function GetRequestStream() associated with the object webRequest. Commented Aug 20, 2013 at 10:38
  • Try to narrow down your question... Commented Aug 20, 2013 at 15:07
  • @Mayank: Are you using the Framework 4.5? Commented Aug 21, 2013 at 21:53

8 Answers 8

4
+50

For Set a file, and receive a server Response, I use that for sending .csv files:

First I initialize a POST Request:

/// <summary> /// Initialize the POST HTTP request. /// </summary> public void SentPostReport() { string url = "http://MyUrlPerso.com/"; Uri uri = new Uri(url); // Create a boundary for HTTP request. Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x"); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); request.ContentType = "multipart/form-data; boundary=" + Boundary; request.Method = "POST"; request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), est); allDone.WaitOne(); } 

After initialized Request, I send the differents parts of my files (headers + content + footer).

/// <summary> /// Send a File with initialized request. /// </summary> private void GetRequestStreamCallback(IAsyncResult asynchronousResult) { string contentType = "binary"; string myFileContent = "one;two;three;four;five;"; // CSV content. HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; Stream memStream = request.EndGetRequestStream(asynchronousResult); byte[] boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + Boundary + "\r\n"); memStream.Write(boundarybytes, 0, boundarybytes.Length); // Send headers. string headerTemplate = "Content-Disposition: form-data; "; headerTemplate += "name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: " + contentType + "\r\n\r\n"; string fileName = "MyFileName.csv"; string header = string.Format(headerTemplate, "file", fileName); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); memStream.Write(headerbytes, 0, headerbytes.Length); byte[] contentbytes = System.Text.Encoding.UTF8.GetBytes(myFileContent); // send the content of the file. memStream.Write(contentbytes, 0, contentbytes.Length); // Send last boudary of the file ( the footer) for specify post request is finish. byte[] boundarybytesend = System.Text.Encoding.UTF8.GetBytes("\r\n--" + Boundary + "--\r\n"); memStream.Write(boundarybytesend, 0, boundarybytesend.Length); memStream.Flush(); memStream.Close(); allDone.Set(); // Start the asynchronous operation to get the response request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request); } 

And, Finnaly, I get The response server response, indicate the file is transmetted.

/// <summary> /// Get the Response server. /// </summary> private static void GetResponseCallback(IAsyncResult asynchronousResult) { HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; try { HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); Stream streamResponse = response.GetResponseStream(); StreamReader streamRead = new StreamReader(streamResponse); string responseString = streamRead.ReadToEnd(); // this is a response server. // Close the stream object streamResponse.Close(); streamRead.Close(); // Release the HttpWebResponse response.Close(); } catch (Exception ex) { // error. } } 

This sample works on Windows Phone 7 and Windows Phone 8. This is for send a .csv content. You can adapt this code for send Xml content. Replace just

string myFileContent = "one;two;three;four;five;"; // CSV content. string fileName = "MyFileName.csv"; 

by your XML

string myFileContent = "<xml><xmlnode></xmlnode></xml>"; // XML content. string fileName = "MyFileName.xml"; 
Sign up to request clarification or add additional context in comments.

1 Comment

I am sorry to dig this up, but I fail to understand, where the 'est' and the 'allDone' Objects come from in the 'SentPostReport()' Function. I am close to start another XML HTTPS Thread, because there is not example which is a) simple or b) not using depricated Dot Net Functions.
3

You can use the HTTP Client libraries in Windows Phone 8 and use the client in the same way that Windows 8.

First, get the HTTP Client Libraries from Nuget. And now, to perform a POST call

HttpClient client = new HttpClient(); HttpContent httpContent = new StringContent("my content: xml, json or whatever"); httpContent.Headers.Add("name", "value"); HttpResponseMessage response = await client.PostAsync("uri", httpContent); if (response.IsSuccessStatusCode) { // DO SOMETHING } 

i hope this helps you :)

Comments

2

If all you're looking to do is take XML you've already generated and add it to your existing request as content, you'll need to be able to write to the request stream. I don't particularly care for the stock model of getting the request stream, so I'd recommend the following extension to make your life a little easier:

public static class Extensions { public static System.Threading.Tasks.Task<System.IO.Stream> GetRequestStreamAsync(this System.Net.HttpWebRequest wr) { if (wr.ContentLength < 0) { throw new InvalidOperationException("The ContentLength property of the HttpWebRequest must first be set to the length of the content to be written to the stream."); } var tcs = new System.Threading.Tasks.TaskCompletionSource<System.IO.Stream>(); wr.BeginGetRequestStream((result) => { var source = (System.Net.HttpWebRequest)result.AsyncState; tcs.TrySetResult(source.EndGetRequestStream(result)); }, wr); return tcs.Task; } } 

From here, augment your SendRequest method:

public static void SendRequest(string myXml) { HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://mytestserver.com/Test.php"); webRequest.Method = "POST"; webRequest.Headers["SOURCE"] = "WinApp"; // Might not hurt to specify encoding here webRequest.ContentType = "text/xml; charset=utf-8"; // ContentLength must be set before a stream may be acquired byte[] content = System.Text.Encoding.UTF8.GetBytes(myXml); webRequest.ContentLength = content.Length; var reqStream = await webRequest.GetRequestStreamAsync(); reqStream.Write(content, 0, content.Length); var response = await httpRequest(webRequest); } 

If the service you're trying to reach is a SOAP service, you could simplify this a bit more by having the IDE generate a client class for you. For more information on how to do that, check out this MSDN article. However, if the service does not have a Web Service Definition Language (WSDL) document, this approach will not be able to assist you.

2 Comments

Hi, I am not able to understand the purpose of class Extensions
@Mayank It's a common compiler extension. It allows you to define your own custom methods on a class that you didn't create. You can read more about them here. It would be no different if you called the extension as var reqStream = await Extensions.GetRequestStreamAsync(webRequest);, similar to the way you call your httpRequest method. Defining it as an extension is just another way of accessing that method and is completely optional. Regardless, the code will give you a Stream using the async/await pattern.
2

I have solved the problem in some other way..

 class HTTPReqRes { private static HttpWebRequest webRequest; public static void SendRequest() { webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("https://www.mydomain.com"); webRequest.Method = "PUT"; webRequest.ContentType = "text/xml; charset=utf-8"; webRequest.Headers["Header1"] = "Header1Value"; String myXml = "<Roottag><info>test</info></Roottag>"; // Convert the string into a byte array. byte[] byteArray = Encoding.UTF8.GetBytes(myXml); webRequest.ContentLength = byteArray.Length; // start the asynchronous operation webRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequest); //webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest); } private static void GetRequestStreamCallback(IAsyncResult asynchronousResult) { HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; // End the operation Stream postStream = request.EndGetRequestStream(asynchronousResult); String myXml = <Roottag><info>test</info></Roottag>"; // Convert the string into a byte array. byte[] byteArray = Encoding.UTF8.GetBytes(myXml); // 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 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(); System.Diagnostics.Debug.WriteLine(responseString); // Close the stream object streamResponse.Close(); streamRead.Close(); // Release the HttpWebResponse response.Close(); } } 

This perfectly solves my problem, send an XML within the HTTP Request and in Response receive the XML from the web service.

Comments

1

I recommend using the RestSharp library. You can find a sample request here.

2 Comments

does MS not provide any such APIs to send POST HTTP Requests?
@Igor Kulman: Look at the HttpClient class and you will see there is better and no need for third party libraries.
1

This is what I used. It's really simple, add WindowsPhonePostClient.dll to your References (if you can't, try unblock the file first by properties->unblock), then use this code:

private void Post(string YourUsername, string Password) { Dictionary<string, object> parameters = new Dictionary<string, object>(); parameters.Add("User", YourUsername); parameters.Add("Password", Password); PostClient proxy = new PostClient(parameters); proxy.DownloadStringCompleted += proxy_UploadDownloadStringCompleted; proxy.DownloadStringAsync(new Uri("http://mytestserver.com/Test.php",UriKind.Absolute)); } private void proxy_UploadDownloadStringCompleted(object sender,WindowsPhonePostClient.DownloadStringCompletedEventArgs e) { if (e.Error == null) MessageBox.Show(e.Result.ToString()); } 

Comments

0

You need to create a reference to the webservice wsdl or you could try to do it manually as detailed here: https://stackoverflow.com/a/1609427/2638872

Comments

-1
//The below code worked for me. I receive xml response back. private void SendDataUsingHttps() { WebRequest req = null; WebResponse rsp = null; string fileName = @"C:\Test\WPC\InvoiceXMLs\123File.xml"; string uri = "https://service.XYZ.com/service/transaction/cxml.asp"; try { if ((!string.IsNullOrEmpty(uri)) && (!string.IsNullOrEmpty(fileName))) { req = WebRequest.Create(uri); //req.Proxy = WebProxy.GetDefaultProxy(); // Enable if using proxy req.Method = "POST"; // Post method req.ContentType = "text/xml"; // content type // Wrap the request stream with a text-based writer StreamWriter writer = new StreamWriter(req.GetRequestStream()); // Write the XML text into the stream StreamReader reader = new StreamReader(file); string ret = reader.ReadToEnd(); reader.Close(); writer.WriteLine(ret); writer.Close(); // Send the data to the webserver rsp = req.GetResponse(); HttpWebResponse hwrsp = (HttpWebResponse)rsp; Stream streamResponse = hwrsp.GetResponseStream(); StreamReader streamRead = new StreamReader(streamResponse); string responseString = streamRead.ReadToEnd(); rsp.Close(); } } catch (WebException webEx) { } catch (Exception ex) { } finally { if (req != null) req.GetRequestStream().Close(); if (rsp != null) rsp.GetResponseStream().Close(); } } 

1 Comment

i don't code in C# but where is the async request that the question expects? from a quick look it seems you should use stuff like await on Tasks etc...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.