C# Application
Now we're ready for the real test. I'll discuss the application components one by one.
Web Page
The code for search.html is very simple. It provides one text box to receive the employee ID and a button to search the details of that employee (see Listing 1):
Listing 1search.html
<html> <TITLE>CGI Program</TITLE> <form action=search.exe> <h1> <font color=blue><u><center>CGI Program</center></font></u> </h1> <center> <b>Employee ID</b> <input type=text name=emp_id> <input type=submit value="Search Details"> </center> </form> </html>
Database
For this example, our XML database is very simple, with only five fields (see Figure 5):
- Employee ID (ID)
- First name (FirstName)
- Last name (LastName)
- Department (Department)
- Year of hire (YearOfJoining)
Figure 5 The simple database for this example.
C# Source Code
Now comes the real logic on the server side: searching the employee details in the employees.xml database.
Before moving into the details of C# source code, let's take a look at the QUERY_STRING environment variable. QUERY_STRING indicates where the query (the information for the search) from the client side is stored by the web serverin our case, IIS. The query contains all the values of the variables declared in the HTML form. In our application, the user will click the Search Details button after specifying the employee ID. The query is displayed in the address bar of the browser (following the ? symbol), containing the name-value pair of the variables in the HTML form. The HTML code of search.html contains only one searchable variable, emp_id, between the <form></form> tags. If we're searching for employee ID 000000, for example, the query contains the expression "emp_id=000000" after the ? symbol, which represents the query string and will be stored in the QUERY_STRING variable on the web server.
Whenever we use the server-side programming to perform business logic, we specify some filename in the <form> tag of the HTML code as the action attribute. In our application this is the following:
<form action = search.exe>
When we submit the data from the client side by clicking the submit button (called Search Details in our application), the file specified as the action attribute in the <form> tag runs on the server and the output is sent back to the client.
To answer the request from the client, an EXE component is specified in the <form> tag as an action attribute (in our example, search.exe). This application runs on the server, and the output produced by the EXE is sent back to the client. The output (response) sent back to the client must be in valid HTML format; therefore, the EXE producing the output must take care of this formatting. However, when the web server in our case launches the EXE, output produced by the EXE doesn't appear on the standard output (computer screen). Instead, it's packaged and sent back to the client. So we don't need to worry, because the web server is intelligent enough to do its job cleanly. We have the freedom to use the Write() and WriteLine() methods from the Console class to output the HTML code or the response to send back to the client.
Now we'll start to explore the C# code of search.cs. We can make this file anywhere, but after compilation the EXE must be placed in the virtual directory (CGI in our example).
The code starts as usual by including the required namespaces:
using System ; using System.Data ; using System.Xml ; class CGISearch { public static void Main() {
First we want to get the data sent by the client to process (in our example, the value of emp_id, to search the details of the specified employee). So we get the value of the QUERY_STRING environment variable:
string query = System.Environment.GetEnvironmentVariable("QUERY_STRING") ;
Now we'll break the value of the query variable on the basis of split characters. Split characters are the characters used to split the string, in this case the equal sign (=). If there are number of variables, they're separated with ampersands (&), so this will also be a split character. By using the Split method on the string, we get the name-value pairs one by one, stored in the result array of strings. For example, for the variable emp_id, the name of the variable will be stored first and then the value will be stored.
char[] SplitChars = new char[]{'='} ; string[] result = query.Split(SplitChars) ;
Before we can start with the presentation to be sent back to the client, we have to tell the web server about the type of the contents being sent across the network:
Console.WriteLine("Content-Type:text/html\n") ;
This must be the first line output by the EXE, so that the browser can display the query results properly.
The following code outputs all the HTML code in search.html. After getting the details of the employee, the user can search more records from the same page.
Console.WriteLine("<html>") ; Console.WriteLine("<TITLE>CGI Program</TITLE>") ; Console.WriteLine("<form action=search.exe>") ; Console.WriteLine("<h1> <font color=blue><u><center>CGI Program </center></font></u></h1>") ;
Next, we initialize the text box with the value of the employee ID submitted:
Console.WriteLine("<center><b>Employee ID <input type=text name=emp_id value="+result[1]+">") ; Console.WriteLine("<input type=submit value=\"Search Details\">") ;
Now we create a new data set and read the XML data into it, and then output the heading "Employee Details" and create a table to show the results:
bool RecordFound = false ; // To check if the record exists. DataSet ds = new DataSet() ; // Creating a new DataSet to hold the XML Data. ds.ReadXml("employees.xml") ; // Getting the XML Data into the DataSet created. Console.WriteLine("<h2><center><u> <font color=blue>Employee Details</u><br><br>") ; Console.WriteLine("<table width=100% border=2 >") ;
The following code presents the results (if any) in the HTML table. If no such record exists, the user gets a nonexistence message.
foreach(DataRow dr in ds.Tables[0].Rows) { // Checking if ID exists. if(result[1].Equals(dr["ID"])) { Console.WriteLine("<tr>") ; // Displaying Header Console.WriteLine("<td><b>Employee ID</td><td> <b>Employee Name</td><td><b>Joining Year</td><td> <b>Department</td></tr>") ; Console.WriteLine("<tr></tr>") ; Console.WriteLine("<h4><font color =black>") ; Console.WriteLine("<tr>") ; Console.Write("<td>"+dr["ID"]+"</td> <td>"+dr["FirstName"]+" "+dr["LastName"]) ; Console.WriteLine("</td><td>"+dr["YearOfJoining"]+" </td><td>"+dr["Department"]+"</td>") ; Console.WriteLine("</tr>") ; RecordFound = true ; // Record Found break ; // No more search. } } Console.WriteLine("</table>") ; // Closing the table. if(!RecordFound) Console.WriteLine("<center><b>Record Does Not Exist !!!") ; } }
Listing 2 shows the whole program.
Listing 2search.cs
using System ; using System.Data ; using System.Xml ; class Search { public static void Main() { string query = System.Environment.GetEnvironmentVariable("QUERY_STRING") ; char[] SplitChars = new char[]{'='} ; string[] result = query.Split(SplitChars) ; Console.WriteLine("Content-Type:text/html\n") ; Console.WriteLine("<html>") ; Console.WriteLine("<TITLE>CGI Program</TITLE>") ; Console.WriteLine("<form action=search.exe>") ; Console.WriteLine("<h1> <font color=blue><u> <center>CGI Program</center></font></u></h1>") ; Console.WriteLine("<center><b>Employee ID <input type=text name=emp_id value="+result[1]+">") ; Console.WriteLine("<input type=submit value=\"Search Details\">") ; bool RecordFound = false ; // To check if the record exists. DataSet ds = new DataSet() ; // Creating a new DataSet to hold the XML Data. ds.ReadXml("employees.xml") ; // Getting the XML Data into the DataSet created. Console.WriteLine("<h2><center><u> <font color=blue>Employee Details</u><br><br>") ; Console.WriteLine("<table width=100% border=2 >") ; foreach(DataRow dr in ds.Tables[0].Rows) { // Checking if ID exists. if(result[1].Equals(dr["ID"])) { Console.WriteLine("<tr>") ; // Displaying Header Console.WriteLine("<td><b>Employee ID</td><td> <b>Employee Name</td><td><b>Joining Year</td> <td><b>Department</td></tr>") ; Console.WriteLine("<tr></tr>") ; Console.WriteLine("<h4><font color =black>") ; Console.WriteLine("<tr>") ; Console.Write("<td>"+dr["ID"]+"</td> <td>"+dr["FirstName"]+" "+dr["LastName"]) ; Console.WriteLine("</td><td>"+dr["YearOfJoining"]+" </td><td>"+dr["Department"]+"</td>") ; Console.WriteLine("</tr>") ; RecordFound = true ; // Record Found break ; // No more search. } } Console.WriteLine("</table>") ; // Closing the table. if(!RecordFound) Console.WriteLine("<center><b>Record Does Not Exist !!!") ; } }
After compiling this program and copying the EXE (search.exe) to the virtual directory (CGI), we're ready to launch the application. Remember to copy the XML database (employees.xml) into the same directory.
To start the application, we open the search.html in the web browser as http://localhost/cgi/search.html, if we're running it on the same machine where the host IIS is functioning, or replace localhost with the server name (see Figure 6).
Figure 6 Running the application.
If I search for employee ID 000001, I get the results shown in Figure 7.
Figure 7 The details for employee 000001.
Throughout the application development, we used the HTML code (presentation logic) in Console.WriteLine. This shows the win-win situation for companies already working with CGI: They can port their code very easily to .NET by using almost all of their existing presentation logic.