Windows Systems Programming: Spring 2004

[ Home | Syllabus | Course Notes | Assignments | Search]


ASP.NET

With ASP.NET we enter the world of distributed processing using standard internet protocols

Accessing the class .NET server

 

About the Web.

<html>
<body>
Hello, world
</body>
</html>

If stored on a web server it can be accessed used its URL (e.g. http://www.cs.odu.edu/~wild/cs477/spring04/simple.html

GET ~wild/cs477/spring04/simple.html HTTP/1.1
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
If-Modified-Since: Wed, 24 Oct 2001 14:12:36 GMT
If-None-Match: "50b0d3ee955cc11:a78"
User-Agent: Mozilla/4.0.(compatible; MSIE.6.0; Windows NT 5.1)
Host: www.cs.odu.edu
Connection: Keep-Alive
[blank line]
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 24 Oct 2001 14:12:37 GMT
Content-Type: text/html
Accept-Ranges: bytes
Last-Modified: Wed, 24 Oct 2001 14:00:53 GMT
ETag: "d02acf81975cc11:a78"
Content-Length: 46
[blank line]
<html>
<body>
Hello, world
</body>
</html>

Dynamic HTML pages

<html>
  <body>
    <form>
      <input type="text" name="op1" />
      +
      <input type="text" name="op2" />
      <input type="submit" value="  =  " />
    </form>
  </body>
</html>

http://www.cs.odu.edu/~wild/cs477/spring03/Examples/Book1/Chap05/Calc/Calc.html?op1=3&op2=4

 

ISAPI Host for DLLs

Here is an example in C++ for the calculator program

#include <windows.h>
#include <httpext.h>
#include <string.h>
#include <stdlib.h>
int GetParameter (LPSTR pszQueryString, LPSTR pszParameterName);

BOOL WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason,
    LPVOID lpvReserved)
{
    return (TRUE);
}

BOOL WINAPI GetExtensionVersion (HSE_VERSION_INFO* pVer)
{
    pVer->dwExtensionVersion = 
        MAKELONG (HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
    lstrcpy (pVer->lpszExtensionDesc, "Calc ISAPI Extension");
    return (TRUE);
}

DWORD WINAPI HttpExtensionProc (EXTENSION_CONTROL_BLOCK* pECB)
{
    static char* szPrePostbackMessage = 
        "<html>\r\n"                                    \
        "<body>\r\n"                                    \
        "<form>\r\n"                                    \
        "<input type=\"text\" name=\"op1\" />\r\n"      \
        "+\r\n"                                         \
        "<input type=\"text\" name=\"op2\" />\r\n"      \
        "<input type=\"submit\" value=\"  =  \" />\r\n" \
        "</form>\r\n"                                   \
        "</body>\r\n"                                   \
        "</html>";

    static char* szPostPostbackMessage = 
        "<html>\r\n"                                            \
        "<body>\r\n"                                            \
        "<form>\r\n"                                            \
        "<input type=\"text\" name=\"op1\" value=\"%d\" />\r\n" \
        "+\r\n"                                                 \
        "<input type=\"text\" name=\"op2\" value=\"%d\" />\r\n" \
        "<input type=\"submit\" value=\"  =  \" />\r\n"         \
        "%d\r\n"                                                \
        "</form>\r\n"                                           \
        "</body>\r\n"                                           \
        "</html>";

    //
    // Build the response message body.
    //
    char szMessage[512];

    if (lstrlen (pECB->lpszQueryString) == 0) {
        // If the query string is empty, return a page that shows
        // an empty calculator.
        lstrcpy (szMessage, szPrePostbackMessage);
    }
    else {
        // If the query string is not empty, extract the user input,
        // process it, and return a page that shows inputs and outputs.
        int a = GetParameter (pECB->lpszQueryString, "op1");
        int b = GetParameter (pECB->lpszQueryString, "op2");
        wsprintf (szMessage, szPostPostbackMessage, a, b, a + b);
    }

    //
    // Build the response message header.
    //
    char szHeader[128];
    DWORD dwCount = lstrlen (szMessage);

    wsprintf (szHeader, "Content-type: text/html\r\n" \
        "Content-Length: %lu\r\n\r\n", dwCount);

    //
    // Output the response message header.
    //
    HSE_SEND_HEADER_EX_INFO shei;
    shei.pszStatus = "200 OK";
    shei.pszHeader = szHeader;
    shei.cchStatus = lstrlen (shei.pszStatus);
    shei.cchHeader = lstrlen (shei.pszHeader);
    shei.fKeepConn = FALSE;
	
    pECB->ServerSupportFunction (pECB->ConnID,
        HSE_REQ_SEND_RESPONSE_HEADER_EX, &shei, NULL, NULL);  

    //
    // Output the response message body.
    //
    pECB->WriteClient (pECB->ConnID, szMessage, &dwCount, 0); 

    //
    // Indicate that the request was processed successfully.
    //
    return HSE_STATUS_SUCCESS;
}

int GetParameter (LPSTR pszQueryString, LPSTR pszParameterName)
{
    char* p = strstr (pszQueryString, pszParameterName);

    if (p != NULL) {
        p += strlen (pszParameterName) + 1;
        for (char* tmp = p; *tmp != '&' && *tmp != 0; tmp++)
            ; //// skip front part of URL
        int len = tmp - p;
        char* buffer = new char[len + 1];
        strncpy (buffer, p, len);
        int val = atoi (buffer);
        delete buffer;
        return val;
    }
    return 0;
}

ASP (Active Server Page)

<%@ Language="VBScript" %> 

<html>
  <body>
    <form>
      <input type="text" name="op1" value="<%= Request("op1") %>"/>
      +
      <input type="text" name="op2" value="<%= Request ("op2") %>" />
      <input type="submit" value="  =  " />
      <%
        If Request ("op1") <> "" And Request ("op2") <> "" Then
            a = CInt (Request ("op1"))
            b = CInt (Request ("op2"))
            Response.Write (CStr (a + b))
        End If
      %>
    </form>
  </body>
</html>

ASP.NET

Similar in design philosophy with JSP (Java Server Pages) - Compiles into program which is more efficient to execute and which can run in an existing process for additional speed.

Uses .NET libraries

Example

<html>
  <body>
    <form runat="server">
      <asp:TextBox ID="op1" RunAt="server" /> 
      +
      <asp:TextBox ID="op2" RunAt="server" />
      <asp:Button Text="  =  " OnClick="OnAdd" RunAt="server" /> 
      <asp:Label ID="Sum" RunAt="server" />
    </form>
  </body>
</html>

<script language="C#" runat="server">
  void OnAdd (Object sender, EventArgs e)// regular C# code
  {
      int a = Convert.ToInt32 (op1.Text);
      int b = Convert.ToInt32 (op2.Text);
      Sum.Text = (a + b).ToString ();
  }
</script>
 

Here is the the HTML generated the first time displayed
(notice - there is no .NET stuff here)

<html>
  <body>
    <form name="_ctl0" method="post" action="calc.aspx" id="_ctl0">
      <input type="hidden"  name="__VIEWSTATE" value="dDwxOTE0NDY4ODE2Ozs+" />

      <input name="op1" type="text" id="op1" />
      +
      <input name="op2" type="text" id="op2" />
      <input type="submit" name="_ctl1" value="  =  " />
      <span id="Sum"></span>
    </form>
  </body>
</html>
 

Error Handling

This form expects numbers are input - if not will cause an exception to be thrown - here is how to catch it

void OnAdd (Object sender, EventArgs e)
{
    try {
        int a = Convert.ToInt32 (op1.Text);
        int b = Convert.ToInt32 (op2.Text);
        Sum.Text = (a + b).ToString ();
    }
    catch (FormatException) {
        Sum.Text = "Error";
    }
}
 

    


 

 

Translates into .NET program which can be compiled


Web Controls

Defined in "System.Web.UI.WebControls"

Some controls include client side "scripts"

Web Controls 

Class Name

Description

AdRotator

Displays rotating banners in Web forms

Button

Generates submit buttons

Calendar

Displays calendars with selectable dates

CheckBox

Displays a check box in a Web form

CheckBoxList

Displays a group of check boxes

CompareValidator

Validates user input by comparing it to another value

CustomValidator

Validates user input using the algorithm of your choice

DataGrid

Displays data in tabular format

DataList

Displays items in single-column or multicolumn lists using HTML templates

DropDownList

Generates HTML drop-down lists

HyperLink

Generates hyperlinks

Image

Displays images in Web forms

ImageButton

Displays graphical push buttons

Label

Generates programmable text fields

LinkButton

Generates hyperlinks that post back to the server

ListBox

Generates HTML list boxes

Literal

Generates literal text in a Web form

Panel

Groups other controls

RadioButton

Displays a radio button in a Web form

RadioButtonList

Displays a group of check boxes

RangeValidator

Verifies that user input falls within a specified range

RegularExpressionValidator

Validates user input using regular expressions

Repeater

Displays items using HTML templates

RequiredFieldValidator

Verifies that an input field isn’t empty

Table

Generates HTML tables

TextBox

Generates text input fields

ValidationSummary

Displays a summary of validation errors

Xml

Displays XML documents and optionally formats them using XSLT

HTML Controls

HTML Controls

Tag

Corresponding HTML Control

<a runat=“server”>

HtmlAnchor

<button runat=“server”>

HtmlButton

<form runat=“server”>

HtmlForm

<img runat=“server”>

HtmlImage

<input type=“button” runat=“server”>

HtmlInputButton

<input type=“reset” runat=“server”>

HtmlInputButton

<input type=“submit” runat=“server”>

HtmlInputButton

<input type=“checkbox” runat=“server”>

HtmlInputCheckBox

<input type=“file” runat=“server”>

HtmlInputFile

<input type=“hidden” runat=“server”>

HtmlInputHidden

<input type=“image” runat=“server”>

HtmlInputImage

<input type=“radio” runat=“server”>

HtmlInputRadioButton

<input type=“password” runat=“server”>

HtmlInputText

<input type=“text” runat=“server”>

HtmlInputText

<select runat=“server”>

HtmlSelect

<table runat=“server”>

HtmlTable

<td runat=“server”>

HtmlTableCell

<th runat=“server”>

HtmlTableCell

<tr runat=“server”>

HtmlTableRow

<textarea runat=“server”>

HtmlTextArea

Any other tag with runat=“server”

HtmlGenericControl

 


    Page Level Events

How ASP.NET processes an .ASPX page

  1. It creates a temporary file containing a class derived from System.Web.UI.Page. The Page class is one of the most important classes in ASP.NET; it represents ASP.NET Web pages.

  2. ASP.NET copies the code in the ASPX file, as well as some code of its own, to the Page-derived class. A method named OnAdd in a <script> block in an ASPX file becomes a member method of the derived class.

  3. ASP.NET compiles the derived class and places the resulting DLL in a system folder. The DLL is cached so that steps 1 and 2 won’t have to be repeated unless the contents of the ASPX file change.

  4. ASP.NET instantiates the derived class and “executes” it by calling a series of methods on it. It is during this execution phase that the Page object instantiates any controls declared inside it and solicits their output.

Page Level Events can be used to execute event handlers. For example. Suppose you wanted today's date and the next four dates in a drop down list - you can statically initialize like this

<asp:DropDownList ID="MyList" RunAt="server">
  <asp:ListItem Text="February 21, 2003" RunAt="server" />
  <asp:ListItem Text="February 22, 2003" RunAt="server" />
  <asp:ListItem Text="February 23, 2003" RunAt="server" />
  <asp:ListItem Text="February 24, 2003" RunAt="server" />
  <asp:ListItem Text="February 25, 2003" RunAt="server" />
</asp:DropDownList>
But this is only good for one day - to generate list as needed
<asp:DropDownList ID="MyList" RunAt="server" />
  .
  .
  .
<script language="C#" runat="server">
  void Page_Load (Object sender, EventArgs e)
  {
      if (!IsPostBack) {
          for (int i=0; i<5; i++) {
              DateTime date =
                  DateTime.Today + new TimeSpan (i, 0, 0, 0);
              MyList.Items.Add (date.ToString ("MMMM dd, yyyy"));
          }
      }
  }
</script>

Page-Level Directives

ASP.NET @ Directives 

Directive

Description

@ Page

Defines general attributes and compilation settings for ASPX files

@ Control

Defines general attributes and compilation settings for ASCX files

@ Import

Imports a namespace

@ Assembly

Enables linkage to assemblies not linked to by default

@ Register

Registers user controls and custom controls for use in a Web form

@ OutputCache

Exerts declarative control over page caching and fragment caching

@ Reference

Adds a reference to an external ASPX or ASCX file

@ Implements

Identifies an interface implemented by a Web page

 


Currency Converter: An Example

<%@ Import Namespace=System.Data %> 

<html>
  <body>
    <h1>Currency Converter</h1>
    <hr>
    <form runat="server">
      Target Currency<br>
      <asp:ListBox ID="Currencies" Width="256" RunAt="server" /><br>
      <br>
      Amount in U.S. Dollars<br>
      <asp:TextBox ID="USD" Width="256" RunAt="server" /><br>
      <br>
      <asp:Button Text="Convert" ID="ConvertButton" Width="256"
        RunAt="server" /><br>
      <br>
      <asp:Label ID="Output" RunAt="server" />
    </form>
  </body>
</html>

<script language="C#" runat="server">
  void Page_Init (Object sender, EventArgs e)
  {
      // Wire the Convert button to OnConvert
      ConvertButton.Click += new EventHandler (OnConvert);
  }

  void Page_Load (Object sender, EventArgs e)
  {
      // If this isn't a postback, initialize the ListBox
      if (!IsPostBack) {
          DataSet ds = new DataSet ();
          ds.ReadXml (Server.MapPath ("Rates.xml"));
          foreach (DataRow row in ds.Tables[0].Rows) 
              Currencies.Items.Add (row["Currency"].ToString ());
          Currencies.SelectedIndex = 0;
      }
  }

  void OnConvert (Object sender, EventArgs e)
  {
      // Perform the conversion and display the results
      try {
          decimal dollars = Convert.ToDecimal (USD.Text);
          DataSet ds = new DataSet ();
          ds.ReadXml (Server.MapPath ("Rates.xml"));
          DataRow[] rows = ds.Tables[0].Select ("Currency = '" +
              Currencies.SelectedItem.Text + "'");
          decimal rate = Convert.ToDecimal (rows[0]["Exchange"]);
          decimal amount = dollars * rate;
          Output.Text = amount.ToString ("f2");
      }
       catch (FormatException) {
          Output.Text = "Error";
      }
  }
</script>
 

Look at the XML file

<?xml version="1.0"?>
<Rates>
  <Rate>
    <Currency>British Pound</Currency>
    <Exchange>0.698544</Exchange>
  </Rate>
  <Rate>
    <Currency>Canadian Dollar</Currency>
    <Exchange>1.57315</Exchange>
  </Rate>
  <Rate>
    <Currency>French Franc</Currency>
    <Exchange>7.32593</Exchange>
  </Rate>
  <Rate>
    <Currency>German Mark</Currency>
    <Exchange>2.18433</Exchange>
  </Rate>
  <Rate>
    <Currency>Italian Lira</Currency>
    <Exchange>2162.67</Exchange>
  </Rate>
  <Rate>
    <Currency>Japanese Yen</Currency>
    <Exchange>122.742</Exchange>
  </Rate>
  <Rate>
    <Currency>Mexican Peso</Currency>
    <Exchange>9.22841</Exchange>
  </Rate>
  <Rate>
    <Currency>Swiss Franc</Currency>
    <Exchange>1.64716</Exchange>
  </Rate>
</Rates>
 

Copyright chris wild 1999-2004.
For problems or questions regarding this web contact [Dr. Wild].
Last updated: February 05, 2004.