1
votes

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.

8
Use webRequest.GetRequestStream() and write your xml to that stream.L.B
there is no function GetRequestStream() associated with the object webRequest.Mayank
Try to narrow down your question...Liel
@Mayank: Are you using the Framework 4.5?glautrou

8 Answers

4
votes

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";
2
votes

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
votes

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 :)

2
votes

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.

1
votes

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

1
votes

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());
}     
0
votes

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

-1
votes
//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();
            }

}