Script Processing

Most ASP.NET pages are arranged in a common structure of common parts. As noted, there is a script block at the top of the page and an XHTML section at the bottom. The script block contains one or more subprograms and functions to respond to page and control events and to produce output either for embedding on the page or for updating files and databases. The XHTML section contains fixed text and XHTML code much like that appearing on standard Web pages. It also contains special server controls that interact with the scripts. Certain controls activate subprograms and functions coded in the script block; other controls provide user input to scripts and define areas on the page where script output appears.

ASP.NET Script Components

The code outline shown in Listing 2-7 summarizes the common components of ASP.NET pages. It serves as a model for creating and organizing the script and XHTML components on a page. The discussion that follows describes the types and uses of script components that regularly appear on ASP.NET pages; the tutorial that follows describes common server controls.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<%@ Page Language="vb" Debug="True" %>
<%@ Import Namespace="namespace" %>

<SCRIPT Runat="Server">

Sub Page_Load
  ...Visual Basic statements run each time the page loads
End Sub

Sub Subprogram_Name (argument list)
  ...Visual Basic statements run when the subprogram is called
End Sub

Function Function_Name (argument list)
  ...Visual Basic statements to return a data value
End Function

</SCRIPT>

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>Model Page</title>
</head>
<body>
<form Runat="Server">

  <asp:InputControl Runat="Server"/>
  <asp:ScriptControl OnClick="Subprogram_Name" Runat="Server"/>
  <asp:OutputControl Runat="Server"/>

    <% inline script %>

    <%= inline expression %>

</form>
</body>
</html>
Listing 2-7. Basic layout of an ASP.NET page.

Incidentally, script code can appear in upper-case, lower-case, or mixed-case characters. These tutorials use mixed-case coding for ease of reading and ease in finding misspelled words.

Directives

ASP.NET pages are compiled the first time they are accessed; subsequently, it is the compiled page that is retrieved on a page load or page post-back request. Compilation of an ASP.NET page is similar to compilation of any other type of computer program, resulting in creation of a "machine-language" or "executable" version of the page.

Pages with scripts are headed by directives to control how the page is compiled and to import any software classes from the .NET framework that may be needed to carry out its processing. Directives are enclosed inside <%@ ... %> characters and appear before the script section of the page.

A Page directive can be coded to specify the programming language used by scripts on the page. It also can direct how script errors are reported. Attributes that can appear in a Page directive are shown in Figure 2.3.

<%@ Page Language="vb|c#" Debug="True|False" %>
Figure 2-3. Page directive with Language and Debug attributes.

The default scripting language under ASP.NET is Visual Basic; its use can be optionally documented with the setting Language="vb". An alternative is to code scripts in the C# (C-Sharp) language. In this case, the directive must be explicit by coding Language="c#" in the Page directive.

Another use of directives is to import namespaces, collections of .NET software classes required by the Visual Basic code on the page. A standard set of namespaces is available by default and does not need to be explicitly imported. Others, such as those required for file or database access, need to be imported by coding <%@ Import %> directives. These special directives appear in scripts later in these tutorials and are discussed at that time.

Script Debugging

One of the handy Page directives you will wish to use on all your pages assists in debugging scripting errors. The Debug="True" attribute produces error messages about coding syntax and program execution errors, pointing you to the lines of code in error. Without this directive, it is difficult to know where errors occur in your code or what types of errors are being reported. Typically, the following page directive appears at the top of all ASP.NET pages to assist in script debugging.

<%@ Page Language="vb" Debug="True" %>
Listing 2-8. Standard Page directive for ASP.NET pages.

The web.config File

By default, the ASP.NET processor routes all script error messages to the browser running on the Web server console. This routing is done for security purposes, so that users cannot view your code in their browsers when reported with errors. Error messages displayed on the server console, though, are no help to you as a programmer trying to debug coding errors. You need error messages routed to your development PC. This rerouting is accomplished by including a special ASP.NET configuration file in your Web directory. The code for this file, named web.config, is shown below.

<!-- Web.Config Configuration File -->
<configuration>
    <system.web>
        <customErrors mode="Off"/>
    </system.web>
</configuration>
Listing 2-9. Contents of web.config file.

Once you have created this file, detailed error messages produced by the Debug directive appear in your personal browser to assist in debugging your scripts. Unfortunately, these messages also appear in users' browsers. So, when your Web application is finally put into production, you should remove the Debug="True" attribute from your Page directive, or change the setting to Debug="False". If future errors pop up, you want to make sure that users are not privileged to detailed information about your scripts.

The web.config file can be created with a text editor such as Notepad and must be placed in your root Web directory; that is, it appears in the top-level folder containing the Web pages for your site. This folder is also called the virtual Web directory or Web application directory.

Script Blocks

Visual Basic code is contained inside script blocks normally appearing at the top of the Web page immediately following any directives. A script block contains subprograms, functions, and other blocks of code that are run by the server prior to sending the page to the browser. A script block is surrounded by a <script> tag in the format shown in Figure 2.4.

<SCRIPT Language="vb|c#" Runat="Server">

  ...Visual Basic code

</SCRIPT>
Figure 2-4. General format for a script block.

The word "SCRIPT" does not need to be coded in upper-case letters; it is done so in these tutorials only for visual emphasis. The entry Language="vb" is optional since Visual Basic is the default language if not otherwise specified. However, both Visual Basic and C# script blocks can be intermixed on the same page, so this Language specification permits identity of these languages in different script blocks. There can be one or more script blocks on a page, although one is usually sufficient when a single scripting language is used.

It is always necessary to include the attribute Runat="Server". This specification indicates that code in the script block is run on the server. It differentiates server scripts from any browser-based JavaScripts that might appear on the page.

Subprograms

Subprograms are the primary means to carry out page processing. They are called in response to page events or in response to user actions surrounding server controls coded on the page. The general format for a Visual Basic subprogram is shown in Figure 2.5.

Sub Subprogram_Name (augument list)

  ...Visual Basic statements

End Sub
Figure 2-5. General format for Visual Basic subprogram.

(Note: These tutorials assume that you have general facility with the Visual Basic language, with its syntax and constructs. They do not "teach" the language, but only review what is assumed to be known. If you are not a Visual Basic programmer, you still may be able to learn the basics of the language by studying the examples. Programmers in other languages should easily adapt to Visual Basic syntax. Otherwise, you will need to review outside sources to come up to speed in Visual Basic.)

Subprogram Names

A subprogram must be named, and all subprogram names must be unique on the same page. These names are programmer-supplied and follow standard Visual Basic naming conventions. Names are composed of alphabetic and numeric characters along with the underscore ( _ ) character. The first character of the name must be alphabetic, and names cannot include blank spaces. Names should be suggestive of the processing functions performed by the subprograms. It is common to compose names in a verb_object format to identify a processing action taking place on a data object. For example, subprogram names such as Get_System_Date, Display_Table, Update_Database, and the like enhance understanding of the subprograms' purposes and are helpful in locating scripts when debugging or making changes to them.

Subprogram Arguments

A subprogram may be supplied with a list of arguments—a signature—contained within parentheses and following the subprogram name. Arguments are items of data or control information passed to the subprogram by the event triggering its call. For certain subprograms such as Page_Load, no argument list is needed. For other subprograms, particularly those called by server controls, an argument list is required. This argument list is used to identify

1. the object making the subprogram call, and
2. the event arguments accompanying the call.

The signature of a subprogram — its particular set of arguments — is determined by what type of control makes the call. If, for example, an <asp:Button> control is clicked to call a subprogram, then the subprogram's signature takes on the form shown in Listing 2-10.

<SCRIPT Runat="Server">

Sub Button_Click (Src As Object, Args As EventArgs)

  ...Visual Basic statements

End Sub

</SCRIPT>

<asp:Button Text="Click Me" OnClick="Button_Click" Runat="Server"/>
Listing 2-10. Subprogram signature for a button click.

The signature for this subprogram follows the format for any subprogram called on a button click. It includes two comma-separated arguments. The first argument in the list is a reference to the object that called the subprogram, in this instance, the button. This argument must be declared As Object and is assigned a name through which it can be referenced in the subprogram. Here, the reference name is Src, although any programmer-supplied name can be used. It is common to see the name "sender" used for this object: sender As Object. Throughout these tutorials the name Src (the source of the subprogram call) is used.

The second argument in the list is a reference to any data values accompanying the subprogram call. Certain controls pass along values that are needed by the subprogram to complete its processing; these values are contained in this argument. The argument must be declared As EventArgs for a button call. It also must be assigned a reference name for use in the subprogram. Here, the reference name is Args, although, again, any programmer-supplied name can be used. It is common to see the name "e" used for this argument: e As EventArgs. These tutorials always use the name Args.

A subprogram may or may not need to explicitly reference its triggering object or its passed data values as contained in its argument list; however, an appropriate signature containing these arguments is required nonetheless. Also, different controls require different signatures. As you proceed through these tutorials, various subprogram signatures are introduced for the various server controls which call them.

Script Calls to Subprograms

For the most part, subprograms are called by page events or control events, in the latter case by event handlers coded inside the server controls. In addition, a subprogram can be called by another subprogram to perform part of its processing. When this occurs, a calling statement names the subprogram and optionally passes data items through an argument list. The general format for a script call to a subprogram is shown in Figure 2.6.

Call Subprogram_Name (argument1, argument2...)
Figure 2-6. General format for calling a subprogram from a script.

When one subprogram calls another subprogram, and no data is exchanged between them, then no argument list is necessary. Only the name of the called subprogram, optionally preceded by the keyword Call, is coded as the calling statement. In the following example, subprogram Button_Click (called by a button click and containing the appropriate signature) calls subprogram Do_Processing. No data is passed between them.

Sub Button_Click (Src As Object, Args As EventArgs)

  Do_Processing
  ...

End Sub

Sub Do_Processing

  ...processing statements

End Sub
Listing 2-11. Calling a subprogram from a subprogram.

When the internal subprogram call is made, script control passes from subprogram Button_Click to subprogram Do_Processing, which executes its statements. On completion, control returns to subprogram Button_Click, continuing with the statement following the subprogram call.

There may be occasions when an argument list is needed by an internally called subprogram. This happens when one subprogram calls another subprogram and passes along data items that are processed by the called subprogram.

Sub Button_Click (Src As Object, Args As EventArgs)

  Dim MyDataValue As String
  Do_Processing(MyDataValue)
  ...

End Sub

Sub Do_Processing (YourDataValue As String)

  ...processing statements using YourDataValue

End Sub
Listing 2-12. Passing arguments to a subprogram.

In the above example, the Button_Click subprogram declares a data item—a variable—named MyDataValue as a String data type. This data item is passed to subprogram Do_Processing as an argument in the calling statement: Do_Processing(MyDataValue). The Do_Processing subprogram receives the passed value as variable YourDataValue through its argument: Do_Processing (YourDataValue As String). The received value can then be involved in processing activities inside the called subprogram.

A calling statement can send any number of data values to a subprogram. These values are sent in a comma-separated list of variables or literal values. A subprogram receives these values through its own comma-separated list of variables. The variables in the receiving list are matched one-to-one with the values in the sending list. The receiving variables must be declared as matching data types to those in the sending list. The names appearing in the receiving list, however, need not match those in the sending list.

Global and Local Variables

Script variables are data storage areas required by processing routines to temporarily hold data values generated by scripts. All variables appearing in a Visual Basic subprogram must be declared prior to their use. Declaring a variable follows the standard Visual Basic format shown in Figure 2-7.

Dim VariableName As type
Figure 2-7. General format for variable declaration.

The keyword Dim declares and identifies a variable through a programmer-supplied variable name. The As type clause is optional as a declaration of the data type, but there are efficiencies in making the type declaration explicit. Various data types are introduced in these tutorials as needed.

Variables declared outside of subprograms are global in scope and can be referenced from all subprograms appearing in a script block. Variables declared inside a subprogram are local to that subprogram and cannot be accessed by other subprograms. A subprogram gains access to another subprogram's variable only if it is explicitly passed to it through a subprogram call containing an argument list with that variable in it.

An alternative to the explicit passing of a data value from one subprogram to another is to declare a global variable outside of both subprograms. Each subprogram then has access to the variable with no requirement for passing it.

<SCRIPT Runat="Server">

Dim MyDataValue As String   '-- declare a global variable

Sub Button_Click(Src As Object, Args As EventArgs)

  ...process MyDataValue
  Call Do_Processing

End Sub

Sub Do_Processing

  ...process MyDataValue

End Sub

</SCRIPT>
Listing 2-13. Use of global variables.

In the above example, both subprograms have access to variable MyDataValue because is has been declared as a global variable outside of both subprograms. It is not necessary to pass this variable as an argument between subprograms as is required in the previous example where the variable is declared locally in the Button_Click subprogram. In general, practice should be to declare variables locally and pass them explicitly from one subprogram to another. However, practicalities often dictate the use of global variables for sharing data values among subprograms.

Functions

Besides subprograms, Visual Basic functions can be coded inside script blocks and called upon to perform processing. The difference is that functions return a data value to the calling statement. There are two general formats for declaring a function as shown in Figure 2-8.

Function Function_Name (argument1 As type, argument2 As type ...) As type
	
  ...Visual Basic statements
	
  Exit Function
End Function

or

Function Function_Name (argument1 As type, argument2 As type ...)
	
  ...Visual Basic statements
	
  Return value
End Function
Figure 2-8. General formats for a Visual Basic function.

A Function_Name is a programmer-supplied name to identify the function. Visual Basic statements are enclosed inside the function to carry out its processing and to return its produced value. A function may or may not require an argument list representing data items sent to the function.

Returning Values from a Function

There are two ways to set up a function to return a value. The function itself can be declared as a data type, in which case a value is assigned to the Function_Name and an Exit Function statement returns the assigned value to the calling statement. This setup is illustrated in the code below which assumes no arguments are passed to the function and which returns the value 10 to the calling statement.

Function Get_Value() As Integer
  Get_Value = 10
  Exit Function
End Function
Listing 2-14. Returning a value to a function call.

The second way to set up a function is to use a Return statement to explicitly pass an identified value back to the calling statement. This technique is used in the following function which returns the same value as the previous function.

Function Get_Value()
  Dim CurrentValue As Integer = 10
  Return CurrentValue
End Function
Listing 2-15. Alternative to returning a value to a function call.

Calling a Function

A function is called by a statement in the following general format.

Call Function_Name (argument1, argument2 ...)
Figure 2-9. General format for calling a function.

The optional keyword Call is followed by the function name, followed by an argument list (if needed), separated by commas and contained inside a set of parentheses. If no arguments are supplied, the parentheses are not required. As in the case of subprograms, these arguments are names and associated data types through which data items are passed to the function for use in its processing.

The following partial script shows a function call from subprogram Page_Load to function Format_Date(). The function call passes the current date taken from the system clock (DateString). The function receives this date through argument TheDate, which is a Date data type. The function applies the Visual Basic Format() method to the received date and stores it in local variable FormattedDate. This variable's value is then returned to the calling statement, which stores the resulting string in local variable CurrentDate.

Sub Page_Load
  Dim CurrentDate As String
  CurrentDate = Format_Date(DateString)
End Sub

Function Format_Date (TheDate As Date)
  Dim FormattedDate As String = Format(TheDate, "Long Date")
  Return FormattedDate
End Function
Listing 2-16. Calling a function with a passed argument.

In this example, as in all function calls, the function call itself represents the value returned by the function. The call to Format_Date(DataString) can be assigned to variable CurrentDate because the call itself is a proxy for the returned value.

Script Comments

Comments are non-executable lines of text added to a script in order to document or to explain to the reader the purpose and use of the code. The appreciative reader is often the programmer who wrote the code in the first place, but has forgotten its purpose or the logic employed.

Single-line comments are indicated with an apostrophe (') preceding the comment. A single-line comment can appear on a line by itself or can be placed at the end of a line containing a Visual Basic statement. Multiple-line comments are made by including lines between <%-- and --%> symbols. Multiple-line comments also can be written as any number of single-line comments appearing on contiguous lines. It is often useful to enclose executable code inside comments to render it null in the course of debugging scripts.

' A single-line comment

Visual Basic statement...        ' A single-line comment

' Multiple
' comment
' lines

<%--
Multiple
comment
lines
--%>
Figure 2-10. General formats for script comments.

A variety of comment formats are shown in the script block below.

<SCRIPT Runat="Server">

'----------------- PAGE SCRIPT -------------------
' The following subprogram is called by a button
' click and produces output displayed on the page.

Sub Button_Click (Src As Object, Args As EventArgs)
  Dim DataValue As Integer = 10   'Declare variable
  Process_Data(DataValue)         'Call subprogram
End Sub

<%-- 
Incomplete subprogram
Sub Process_Data (PassedData)

End Sub
--%>

</SCRIPT>
Listing 2-17. Various script comments.

Statement Continuation

The underscore character ( _ ) is used as a line-continuation symbol when coding statements across two or more lines. The reason for doing this is to make the code more readable in the text editor by avoiding excessively long lines of code.

TextString = "This is a very long string of text that if coded on a single line produces a very long statement that can require scrolling to view it in the script editor."

TextString = "This is a very long string of text that is " & _
             "composed of several separate text strings" & _
             "that are concatenated to keep from coding " & _
             "a very long single statement."
Listing 2-18. Example of script line continuation.

In the above example, the second Visual Basic statement spans four lines of code. The first three lines include a continuation character at the end of the line to indicate continuation of this single statement to the next line. Note that a single blank space must appear before the line-continuation symbol.

The previous example shows a concatenation of shorter strings to compose a lengthy string assigned to a variable. For this reason the line-continuation symbol is preceded by the concatenation operator "&". Do not mistakenly think that line continuations always use the combination "& _". It occurs above only because strings are being continued. In fact, the concatenation operator could just as well have been coded at the beginning of the continued lines.

TextString = "This is a very long string of text that is " _
           & "composed of several separate text strings" _
           & "that are concatenated to keep from coding " _
           & "a very long single statement."
Listing 2-19. Alternate example of script line continuation.

The following example shows continuation of a formula containing variable names. Here it is clear that only the line-continuation character preceded by a blank space ends the line.

TotalPay = GrossPay + BonusPay + TravelPay + OvertimePay _
           - FICATax - WithHoldingTax - StateTax - CountyTax _
           - CityTax - SpecialTax - TaxToSupportEverybodyElse
Listing 2-20. Another example of script line continuation.

Code Render Blocks

In addition to appearing within script blocks as subprograms and functions, Visual Basic code can appear as inline scripts within the body of the XHTML document. These "embedded" scripts, also called code render blocks, are surrounded by <% %> characters to identify them as server scripts and to set them off from the surrounding XHTML.

<SCRIPT Runat="Server">
  Dim Message As String
</SCRIPT>

<body>
<form Runat="Server">

<% Message = "My Message" %>                                  

<p>Here is HTML code that displays <b><%= Message %></b>.</p>

</form>
</body>
Listing 2-21. Scripting with code render blocks.

In the above example, variable Message is declared in the script block at the top of the page. Since it is not defined inside a subprogram, it is globally accessible by other scripts on the page. Within the <body> of the page, an inline script assigns the string "My Message" to global variable Message: <% Message = "My Message" %>.

Inline expressions appear inside <%= %> symbols within the <body> of the page to display the value of a single variable or computational expression. The equal sign (=) indicates that the script is to display the value generated by the enclosed script. In the above example, the inline expression <%= Message %> displays the value of variable Message that is assigned in the previous inline script. Page output produced by this inline expression is shown below.

Here is HTML code that displays My Message.
Figure 2-11. Displaying an in-line expression.

Script variables appearing in inline code and inline expressions must be declared as global variables and not be hidden inside subprograms as local variables. Inline scripts and inline expressions have their place in ASP.NET, but not to the extent that they were used in classical ASP. Current practice is to include scripts only inside separate script blocks, not in the XHTML section of the page.


The above summary describes the various scripting components that are pulled together to create on-page scripts to carry out the processing activities of ASP.NET pages. It is not meant as full coverage of subprogram and function coding. It serves only as reminders of practices you need to bring to the task. To succeed in ASP.NET page development, you need prior understanding of Visual Basic programming. The purpose here is not to teach Visual Basic, but to describe its application to Web programming.