< VB .NET Http Get Request Program Example | Main | C# Http Post Request Program Example >


 

Chapter 10 Part 5: HTTP with .NET

 

 

What do we have in this chapter 10 Part 5?

  1. POST

  2. C++ Http Post Request Program Example

 

POST

 

Issuing a POST request is similar to issuing an HTTP GET request. One difference is that the request stream is retrieved from the HttpWebRequest object to send the post data. The general steps for issuing a POST request are:

 

  1. Create an HttpWebRequest object with the URL to post to.
  2. Change the Method property to “POST” and the ContentType property to “application/x-www-form-urlencoded”.
  3. Retrieve the request stream from the HttpWebRequest object.
  4. Send the post data on the stream.
  5. Retrieve the HttpWebResponse object.
  6. Retrieve the response stream from HttpWebResponse and read the response.

 

The following code sample illustrates issuing a POST request and receiving the response:

 

C#

 

HttpWebRequest httpRequest;

HttpWebResponse httpResponse;

BinaryReader httpResponseStream;

 

try

{

    // Create HTTP Web request

    httpRequest = (HttpWebRequest) WebRequest.Create("http://www.microsoft.com" );

    // Change method from the default "GET" to "POST"

    httpRequest.Method = "POST";

    // Posted forms need to be encoded so change the content type

    httpRequest.ContentType = "application/x-www-form-urlencoded";

    // Data to POST

    string postData = "sl=foo&s2=bar";

    // Retrieve a byte array representation of the data

    byte [ ] postBytes = Encoding.UTF8.GetBytes(postData.ToString() );

    // Set the content length

    httpRequest.ContentLength = postBytes.Length;

    // Retrieve the request stream so we can write the POST data

    Stream httpPostStream = httpRequest.GetRequestStream();

    // Write the POST request

    httpPostStream.Write( postBytes, 0, postBytes.Length );

    httpPostStream.Close();

    // Retrieve the response

    httpResponse = (HttpWebResponse) httpRequest.GetResponse();

    // Retrieve the response stream

    httpResponseStream = new BinaryReader(httpResponse.GetResponseStream(), Encoding.UTF8);

 

    byte [ ] readData;

 

    while ( true )

    {

        readData = httpResponseStream.ReadBytes( 4096 );

        if ( readData.Length == 0 )

            break;

        // Process the response

    }

    httpResponseStream.Close();

    httpResponse.Close();

}

catch ( WebException wex )

{

    Console.WriteLine("Exception occurred: {0}", wex.ToString());

    httpResponse = (HttpWebResponse) wex.Response;

    httpResponse.Close();

}

 

Visual Basic .NET

 

Dim httpRequest As HttpWebRequest

Dim httpResponse As HttpWebResponse

Dim httpResponseStream As BinaryReader

 

Try

' Create HTTP Web request

    httpRequest = WebRequest.Create("http://www.microsoft.com/")

' Change method from the default "GET" to "POST"

    httpRequest.Method = "POST"

' Posted forms need to be encoded so change the content type

    httpRequest.ContentType = "application/x-www-form-urlencoded"

' Data to POST

Dim postData As String = "sl=foo&s2=bar"

' Retrieve a byte array representation of the data

Dim postBytes() As Byte = Encoding.UTF8.GetBytes(postData.ToString())

' Set the content length

    httpRequest.ContentLength = postBytes.Length

' Retrieve the request stream so we can write the POST data

Dim httpPostStream As Stream = httpRequest.GetRequestStream()

' Write the POST request

    httpPostStream.Write(postBytes, 0, postBytes.Length)

    httpPostStream.Close()

' Retrieve the response

    httpResponse = httpRequest.GetResponse()

' Retrieve the response stream

    httpResponseStream = New BinaryReader(httpResponse.GetResponseStream(), Encoding.UTF8())

 

Dim readData() As Byte

 

    While (True)

        readData = httpResponseStream.ReadBytes(4096)

        If readData.Length = 0 Then

            GoTo afterwhile

        End If

' Process the response

    End While

afterwhile:

 

    httpResponseStream.Close()

    httpResponse.Close()

Catch wex As WebException

    Console.WriteLine("Exception occurred: {0}", wex.ToString())

    httpResponse = wex.Response

    httpResponse.Close()

End Try

 

The following program examples illustrate posting a form to a URI and receiving the response.

 

C++ Http Post Request Program Example

 

Create a new CLR console application project and you might want to use HttpPostRequestCP as the project and the solution names.

 

C++ Http Post Request Program Example - creating a new CLR console application project in Visual Studio

 

Add the following codes that include HttpPostRequest class.

 

 

 

 

// HttpPostRequestCP.cpp : main project file.

//

// This sample illustrates how to issue an HttpWebRequest to POST data to a web site.

// The steps for posting data are fairly similar to the GET request. They are:

//    1. Create an HttpWebRequest object and change method to POST and content type

//       to encoded form

//    2. Retrieve the request stream

//    3. Write the post data on the request stream

//    4. Retrieve the HttpWebResponse object

//    5. Retrieve the response stream and receive the data

//

// This sample takes the URL to post to, the data string to post, and an optional

// web proxy (if required to reach the Internet). The sample then performs the steps

// listed above.

//

// usage:

//      Executable_file_name [-u URL] [-d data] [-s file] [-p proxy]

//           -u URL          URL to post data to

//           -d data         Data to post

//           -s file         File name to save response to

//           -p HTTP URL     Proxy to use for post operation

//

// sample usage:

//      Post data to http://www.microsoft.com and save to foo.html:

//          Executable_file_name -u http://www.microsoft.com -d "sl=como&s2=estas" -s foo.html

//

#include "stdafx.h"

 

using namespace System;

using namespace System;

using namespace System::Net;

using namespace System::IO;

using namespace System::Text;

using namespace System::Web;

 

/// <summary>

/// Simple class that encapsulates the HTTP post sample.

/// </summary>

public ref class HttpPostRequest

{

/// <summary>

/// Displays simple usage information.

/// </summary>

public:

    static void usage()

    {

          Console::WriteLine("Executable_file_name [-u URL] [-d data] [-s file] [-p proxy]");

          Console::WriteLine("Available options:");

          Console::WriteLine("     -u URL          URL to post data to");

          Console::WriteLine("     -d data         Data to post");

          Console::WriteLine("     -s file         File name to save response to");

          Console::WriteLine("     -p HTTP URL     Proxy to use for post operation");

          Console::WriteLine();

    }

 

    /// <summary>

    /// This routine validates the data being posted to the web page. It parses

    /// the string for reserved characters '?', '=', and '&'. The individual

    /// validated parts are returned via a StringBuilder object.

    /// </summary>

    /// <param name="postData">Data to validate</param>

    /// <returns>StringBuilder object representing the parsed elements</returns>

public:

    static StringBuilder^ ValidatePostData(String^ postData)

    {

        StringBuilder^ encodedPostData = gcnew StringBuilder();

        // These chars should be more...e.g. custom

        array<Char>^ reservedChars = { '?', '=', '&' };

        int pos, offset;

        // Validate the data to be posted

        Console::WriteLine("Validating the data to be posted...");

        offset = 0;

        while (offset < postData->Length)

        {

            pos = postData->IndexOfAny(reservedChars, offset);

            if (pos == -1)

            {

                // UrlEncode() replaces all character codes except for letters, numbers

                // and the following punctuation characters:

                // - (minus sign)

                // _ (underscore)

                // . (period)

                // ! (exclamation point)

                // ~ (tilde)

                // ' (single quotation mark)

                // ( and ) (opening and closing parentheses)

                // # (number sign)

                // The UrlDecode() method reverses the encoding

                // Append the remaining part of the string

                Console::WriteLine("Appending the remaining part of the string...");

                encodedPostData->Append(HttpUtility::UrlEncode(postData->Substring(offset, postData->Length - offset)));

                break;

            }

            // Found a special character so append up to the special character

            Console::WriteLine("Found a special character so append up to the special character...");

            encodedPostData->Append(HttpUtility::UrlEncode(postData->Substring(offset, pos - offset)));

            encodedPostData->Append(postData->Substring(pos, 1));

            offset = pos + 1;

        }

        return encodedPostData;

    }

 

    /// <summary>

    /// This method creates an HttpWebRequest object, sets the method to "POST",

    /// and builds the data to post. Once the HttpWebRequest object is created,

    /// the request stream is obtained and the post data is sent and the

    /// request stream closed. The response is then retrieved.

    /// </summary>

    /// <param name="postUrl">URL to post data to</param>

    /// <param name="postData">Data to post</param>

    /// <param name="proxyServer">Proxy server to use</param>

    /// <param name="saveFile">Filename to save response to</param>

public:

    static void HttpMethodPost(String^ postUrl, String^ postData, IWebProxy^ proxyServer, String^ saveFile)

    {

        HttpWebRequest^ httpRequest = nullptr;

        HttpWebResponse^ httpResponse = nullptr;

        Stream^ httpPostStream = nullptr;

        BinaryReader^ httpResponseStream = nullptr;

        FileStream^ localFile = nullptr;

 

        try

        {

            StringBuilder^ encodedPostData;

            array<Byte>^ postBytes = nullptr;

 

            // Create HTTP web request

            Console::WriteLine("Creating HTTP web request...");

            httpRequest = (HttpWebRequest^)WebRequest::Create(postUrl);

            // Change method from the default "GET" to "POST"

            Console::WriteLine("Changing method from the default \"GET\" to \"POST\"...");

            httpRequest->Method = "POST";

            // Posted forms need to be encoded so change the content type

            Console::WriteLine("Changing the content type...");

            httpRequest->ContentType = "application/x-www-form-urlencoded";

            // Set the proxy

            Console::WriteLine("Setting the proxy...");

            httpRequest->Proxy = proxyServer;

            // Validate and encode the data to POST

            Console::WriteLine("Validating and encode the data to POST...");

            encodedPostData = ValidatePostData(postData);

            Console::WriteLine("Encoded POST string: '{0}'", encodedPostData->ToString());

            // Retrieve a byte array representation of the data

            Console::WriteLine("Retrieving a byte array representation of the data...");

            postBytes = Encoding::UTF8->GetBytes(encodedPostData->ToString());

            // Set the content length (the number of bytes in the POST request)

            Console::WriteLine("Setting the content length - the number of bytes in the POST request...");

            httpRequest->ContentLength = postBytes->Length;

            // Retrieve the request stream so we can write the POST data

            Console::WriteLine("Retrieving the request stream so we can write the POST data...");

            httpPostStream = httpRequest->GetRequestStream();

            // Write the POST request

            Console::WriteLine("Writing the POST request...");

            httpPostStream->Write(postBytes, 0, postBytes->Length);

            httpPostStream->Close();

            httpPostStream = nullptr;

            // Retrieve the response

            Console::WriteLine("Retrieving the response...");

            httpResponse = (HttpWebResponse^)httpRequest->GetResponse();

            // Retrieve the response stream

            Console::WriteLine("Retrieving the response stream...");

            httpResponseStream = gcnew BinaryReader(httpResponse->GetResponseStream(), Encoding::UTF8);

 

            array<Byte>^ readData;

 

            // Open the file to save the response to

            Console::WriteLine("Opening the file to save the response to...");

            localFile = File::Open(saveFile, FileMode::Create, FileAccess::Write, FileShare::None);

            Console::WriteLine("Saving response to: {0}", localFile->Name);

            Console::Write("Receiving response stream until the end...\n");

            // Receive the response stream until the end

            int count = 0;

            long percent;

 

            while (true)

            {

                readData = httpResponseStream->ReadBytes(4096);

                if (readData->Length == 0)

                    break;

                localFile->Write(readData, 0, readData->Length);

                // Calculate the progress and display to the console

                Console::Write(" ...Calculating the progress and display to the console...\n");

                count += readData->Length;

                percent = (count * 100) / (long)httpResponse->ContentLength;

                Console::Write("\b\b\b");

                Console::Write("{0}%", percent.ToString()->PadLeft(2));

            }

            Console::WriteLine();

        }

        catch (WebException^ wex)

        {

            Console::WriteLine("HttpMethodPost() - Exception occurred: {0}", wex->Message);

            httpResponse = (HttpWebResponse^)wex->Response;

        }

        finally

        {

            // Close any remaining resources

            Console::Write("Closing any remaining resources...\n");

            if (httpResponse != nullptr)

            {

                httpResponse->Close();

            }

            if (localFile != nullptr)

            {

                localFile->Close();

            }

        }

    }

};

 

/// <summary>

/// This is the main routine that parses the command line and calls routines to

/// issue the POST request and receive the response.

/// </summary>

/// <param name="args">Command line arguments</param>

int main(array<System::String ^> ^args)

{

    // Example: http://search.live.com/results.aspx?q=tenouk&go=&form=QBLH

    //          http://search.msdn.microsoft.com/Default.aspx?query=web&brand=msdn&locale=en-us&refinement=

    IWebProxy^ proxyServer;

    String^ uriToPost = "http://search.live.com/";

    String^ proxyName = nullptr;

    String^ postData = "results.aspx?q=tenouk&go=&form";

    String^ fileName = nullptr;

 

    // Parse the command line

            if(args->Length != 0)

            {

                        for (int i = 0; i < args->Length; i++)

                        {

                                    try

                                    {

                                                if ((args[i][0] == '-') || (args[i][0] == '/'))

                                                {

                                                            switch (Char::ToLower(args[i][1]))

                                                            {

                                                                case 'u':

                                                                        // URI to post to

                                                                        uriToPost = args[++i];

                                                                        break;

                                                                case 'p':

                                                                        // Name of proxy server to use

                                                                        proxyName = args[++i];

                                                                        break;

                                                                case 'd':

                                                                        // Retrieve all referenced images and text on the same host

                                                                        postData = args[++i];

                                                                        break;

                                                                case 's':

                                                                        // Local save path to append to retrieved resources

                                                                        fileName = args[++i];

                                                                        break;

                                                                        default:

                                                                        HttpPostRequest::usage();

                        return 0;

                }

            }

        }

        catch(Exception^ err)

        {

            Console::WriteLine("Error: " + err->Message);

            HttpPostRequest::usage();

            return 0;

        }

    }

  }

  else

  {

        HttpPostRequest::usage();

        return 0;

   }

 

    try

    {

        // Set the proxy if supplied or use the default IE static proxy

        Console::Write("Setting the proxy if supplied or use the default IE static proxy...\n");

        if (proxyName == nullptr)

        {

            proxyServer = WebRequest::DefaultWebProxy;

        }

        else

        {

            proxyServer = gcnew WebProxy(proxyName);

        }

 

        // Post the request and write the response to the file

        Console::Write("Posting the request and write the response to the file...\n");

        HttpPostRequest::HttpMethodPost(uriToPost, postData, proxyServer, fileName);

    }

    catch (Exception^ ex)

    {

        Console::WriteLine("Main() - Exception occurred: {0}", ex->Message);

    }

    return 0;

}

 

 

 

Build and run the project. Well, there is an error as shown below stating that 'HttpUtility' is undeclared identifier. It seems that the System.Web cannot resolve the reference. To solve this, let add a reference to the Web.dll manually.

 

1>.\HttpPostRequestCP.cpp(68) : error C2065: 'HttpUtility' : undeclared identifier

1>.\HttpPostRequestCP.cpp(68) : error C2227: left of '->UrlEncode' must point to class/struct/union/generic type

1>        type is ''unknown-type''

1>.\HttpPostRequestCP.cpp(73) : error C2065: 'HttpUtility' : undeclared identifier

1>.\HttpPostRequestCP.cpp(73) : error C2227: left of '->UrlEncode' must point to class/struct/union/generic type

1>        type is ''unknown-type''

 

We can test this issue by adding the scope operator at the end of the System::Web namespace as shown below. There is no HttpUtility from the intellisense context menu.

 

C++ Http Post Request Program Example - the HttpUtility class cannot be found through the use of the using directive

 

So, let add the System::Web manually. Select the project folder > Right click mouse > Select References context menu.

 

C++ Http Post Request Program Example -invoking the References page

 

There is no System.Web under the Name: column of the References:. Click the Add New Reference button.

 

C++ Http Post Request Program Example - confirmed that the System.Web was not included in the references

 

Find the System.Web (Web.dll) in the .NET tab and click OK.

 

C++ Http Post Request Program Example - selecting the System.Web(Web.dll)

 

 

 

 

You can see the System.Web namespace was added in the Reference: field. Click the OK button.

 

C++ Http Post Request Program Example - the System.Web reference can be seen in the References field

 

Now, let re-test the System::Web using directive as shown below. This time, you should see the HttpUtility.

 

C++ Http Post Request Program Example - testing the available classes through the using directive

 

Build and run the project. The following is the sample output.

 

C++ Http Post Request Program Example - a sample output without any argument value

 

The following sample output is based on the following arguments:

C:\>httppostrequestcs -u http://search.msdn.microsoft.com/ -d Default.aspx?Query=web.dll -s test.htm

C++ Http Post Request Program Example - a sample output with the supplied argument values

 


< VB .NET Http Get Request Program Example | Main | C# Http Post Request Program Example >