8 Quick steps to develop and setup C# CGI program in IIS 7

CGI or common Gateway Interface is the protocol used by classic web forms to exchange data between the user and the web server. CGI uses HTTP protocol, which is a simple text exchange protocol on top of TCP/IP. In the HTTP protocol, environment variables of the OS and input from standard input devise such as console or stdin are used by the CGI program to retrieve the data that was sent from the HTML forms.

In this post I am going to show you how to create a simple console application in C# and use it as my CGI program in IIS. I’ll show you step by step how to setup a website using IIS7, enable CGI-Exe Handler Mappings and create a C# application to handle the CGI requests when a user inputs the data into text fields of a HTML form. Both HTTP GET and POST methods will be

explained.

Step1: Creating a Web Site in IIS7

Open the IIS manager and create a new website called temp. I’ll assign port 81 and point to the physical path c:\temp folder.

II& add web site c:\temp

Click OK and you are done. Your website http://localhost:81/ is ready, running at port 81 waiting to accept HTTP sessions from any browser, either on local machine or any remote client that has access this your computer using TCP/IP based network.

Step2: Enable CGI in the above IIS website

After the web site is created, click on the “Handler Mappings”

IIS7 Handler Mappings

You will see the following window where you can see that the CGI and ISAPI is disabled.

You will see CGI and ISAPI is disabled

Click on “Edit Feature Permissions ” on the right hand sidebar. The following dialg box will show up. Click on “Execute” checkbox  and click ok.

Edit-Feature-Permissions

Now you will see that the CGI is enabled.

IIS7 Handler Mappings: Enabling CGI-Exe Handler

Step3: The Basics – Hyper link: the simplest form of a web form

I am sure all of you are familiar with the a ubiquitous hyper links on websites that you visit everyday. When you see a blue link on a web page and you click on it it takes you to another page on the same site or a page on an entirely different site. Where ever it goes, you have just seen the simplest form of a web form in action. Its called a hyper link and when you click on it it will send the variables and values coded inside the hyper link’s URL to the target page. These variables and values are hard coded into the URL of the hyperlink. The protocol used here is HTTP GET.

a simple HTTP GET URL looks like

<a href=”http://localhost:81/ConsoleApplication1.exe?variable1=value1&variable2=value2″>Click Here</a>

when you click on it, the browser will call the target script (exe in this case) called ConsoleApplication1.exe on the IIS server and pass in two variablesvariable1 with value1 and variable2 with value2

This is the simplest form of a web form. Notice that there are no user inputs. The inputs are already hardcoded. the only user input is the click.

Step4: The Basics – Simple HTML forms, GET and POST methods

So how can you involve the user a bit more and have her input the variable1 with her own value as opposed to the hard coded value value1? This can be achieve by a FORM with two input textbox fields and one submit button. In the next section I’ll show you how to create a simple website in the c:\temp folder and create simple HTML form.

Create a file called index.html with the following code it in.

<form target="localhost:81/ConsoleApplication1.exe" method="GET">
<input type="text" name="variable1">
<input type="text" name="variable2">
<input type="submit" value="Send">
</form>

Open the browser and call this html using http://localhost:81/index.html and you will see the form with two input text box fields  and a submit button. You can replace the method=”GET” with method=”POST” and the form will use POST method to ConsoleApplication1.exe program and exchange the data. This ConsoleApplication1.exe is not developed yet. You will get an error when you click on submit. We will create this ConsoleApplication1.exe in the next section.

Step5: Difference between HTTP GET and POST

Sending the GET variables

  • You can simply type the URL in the browsers window and hit enter.
  • You can create a hyperlink with the URL in a referring page and click on the link.
  • In the GET method, all the variables are sent to the server by encoding them in the URL. So more the number of variables, longer the URL.
  • In GET, all the variables and values are visible to the sender since they are part of the URL

Sending the POST variables

  • In the POST method all the variables are sent in the HTTP headers
  • CONTENT_LENGTH environment variable will indicate the CGI the length of the input stream in bytes.

Reading what was sent by GET method in side the CGI

  • If the protocol used was GET then the input variables are found in the OS environment variables

Reading what was sent by POST method in side the CGI

  • If the protocol used was POST then the input variables are found in the stdin

Sending the response back in HTML format

  • For both GET and POST, the CGI program simply sends the response back, in the pure text HTML format by writing to the Console or stdout.

Step5: Creating C# Console Application for the CGI Program

Now that we understand how the CGI, HTTP, GET and POST work, we will test it by creating a simple CGI program in C#. Open Visual C# Express 2010 and choose “Create a new console application” template and click OK.

Create New CSharp Console Application

I am going to create a simple console application with just one class and only member in that class, a static Main(). In the this Main() function, I can read the environment variables and understand what has been sent as input. I will use Console.Write() function to write text to the console.  You will notice that the text output from this program actually is in HTML format and makes up a simple web page.

using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1 {
    class ConsoleApplication1  {
        [STAThread] // uses single threaded apartment model (STA)
        static void Main(string[] args) {
            Console.Write("Content-Type: text/html\n\n");
            Console.Write("<html><head><title>IIS7 CGI using C#</title></head><body><h1>CGI Environment</h1>");
            Console.Write("The Common Gateway Interface version (env: GATEWAY_INTERFACE): " + System.Environment.GetEnvironmentVariable("GATEWAY_INTERFACE"));
            Console.Write("<br/>The name and version of the protocol (env SERVER_PROTOCOL): " + System.Environment.GetEnvironmentVariable("SERVER_PROTOCOL"));
            Console.Write("<br/>The request method used (env: REQUEST_METHOD): " + System.Environment.GetEnvironmentVariable("REQUEST_METHOD"));
            Console.Write("<br/>Extra path information passed to the CGI program (env: PATH_INFO): " + System.Environment.GetEnvironmentVariable("PATH_INFO"));
            Console.Write("<br/>The translated version of the path (env: PATH_TRANSLATED): " + System.Environment.GetEnvironmentVariable("PATH_TRANSLATED"));
            Console.Write("<br/>The GET Query String (env: QUERY_STRING): " + System.Environment.GetEnvironmentVariable("QUERY_STRING")); 
            Console.Write("</body></html>");
        }
     }
}

If I run this program ConsoleApplication1.exe from command line, the output is simply written to the command line as shown below:

CGI Progam Output running at Command Line

But in CGI, we will actually run this program ConsoleApplication1.exe, by calling it from the browser. When called from browser running on a remote computer, the ConsoleApplication1.exe will be run by the IIS. Since there is no user looking at the output of this ConsoleApplication1.exe, the IIS simply takes the output and sends back to the calling browser using the HTTP protocol.

Step6: Assigning this EXE as a CGI Extension in IIS

In the IIS Manager, click on the server name on the left panel and choose “ISAPI and CGI Restrictions”

Set ISAPI CGI Restrictions in IIS7

in the next screen, click on “add” to “Add new ISAPI or CGI restriction”. Input the full path of the program and check the “Allow extension path to execute” and click OK to save.

Add ISAPI CGI Restriction in IIS7

ISAPI-CGI-Restrictions-in-IIS7

Step7: Calling the CGI from browser

Run the CGI Program by typing http://localhost:81/ConsoleApplication1.exe?x=1&y=2 in the browser. Notice the ?x=1&y=2 at the end of the URL after the name of the CGI program. This is called GET query string. You will be able to pass variables and values to the CGI program using this format.

You will see the following output:

CGI Program Output

Step8: Modify our CGI Program to accept variables using POST Protocol

A POST will send the user’s input to the CGI program, as if it were typed by the keyboard, using the standard input device, stdin or console. If POST is used, then an environment variable CONTENT_LENGTH indicates how much data will follow.

Create index.html file with the following HTML in it. Notice that the form ACTION  is the exe name and method is POST. The two variables being sent are fname and lname.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
<title>Test CGI in IIS7 using C#</title>
</head>
<body>
<h1>Simple Form - Test CGI Application using POST</h1>
<form action="ConsoleApplication1.exe" method="POST">
Enter your First Name: <INPUT TYPE="text" NAME="fname" SIZE="30" />
<br />Enter your Last  Name: <INPUT TYPE="text" NAME="lname" SIZE="30" /><br />
<input type="submit" value="Submit" /></form></body></html>

The C# program will look like:

using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1 {
    class ConsoleApplication1  {
        [STAThread] // uses single threaded apartment model (STA)
        static void Main(string[] args) {
            Console.Write("Content-Type: text/html\n\n");
            Console.Write("<html><head><title>IIS7 CGI using C#</title></head><body><h1>CGI Environment</h1>");
            Console.Write("The Common Gateway Interface version (env: GATEWAY_INTERFACE): " + System.Environment.GetEnvironmentVariable("GATEWAY_INTERFACE"));
            Console.Write("<br/>The name and version of the protocol (env SERVER_PROTOCOL): " + System.Environment.GetEnvironmentVariable("SERVER_PROTOCOL"));
            Console.Write("<br/>The request method used (env: REQUEST_METHOD): " + System.Environment.GetEnvironmentVariable("REQUEST_METHOD"));
            Console.Write("<br/>Extra path information passed to the CGI program (env: PATH_INFO): " + System.Environment.GetEnvironmentVariable("PATH_INFO"));
            Console.Write("<br/>The translated version of the path (env: PATH_TRANSLATED): " + System.Environment.GetEnvironmentVariable("PATH_TRANSLATED"));
            if (System.Environment.GetEnvironmentVariable("REQUEST_METHOD").Equals("POST")) {
                string PostedData = "";
                int PostedDataLength = Convert.ToInt32(System.Environment.GetEnvironmentVariable("CONTENT_LENGTH"));
                if (PostedDataLength > 2048) PostedDataLength = 2048;   // Max length for POST data
                for (int i = 0; i < PostedDataLength; i++)
                    PostedData += Convert.ToChar(Console.Read()).ToString();
                Console.Write("<br/>Post Data length: " + PostedDataLength.ToString() + " Post data: " + PostedData);
            }
            else {
                Console.Write("<br/>The GET Query String (env: QUERY_STRING): " + System.Environment.GetEnvironmentVariable("QUERY_STRING"));
            }            
            Console.Write("</body></html>");
        }
     }
}

Output of the CGI POST

output of post form

CGI POST output

Conclusion

You can develop classic CGI applications in C# using Visual C# 2010 Express, and use them to accept GET or POST variables. You will return the HTML to the calling browser by simply writing to the console or stdout.

This entry was posted in IIS, Web Development Fundamentals and tagged , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

3 Trackbacks

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>