7. C# and ASP.Net

 

In this chapter, we shall explore the Web, beginning with the very first principles. So, make a new sub-directory called aaa in c:\inetpub\wwwroot, and then, create a file named a.aspx with the following contents:

 

a.aspx

Hi

Bye

 

In Internet Explorer, enter the following url: http://localhost/aaa/a.aspx.  After a slight time lag, the text "hi bye" gets displayed in the browser window. This really is no big deal! Then, you need to add one more line to the file a.aspx.

 

a.aspx

Hi

Bye

<% hi %>

 

Either re-load IE and enter the URL, or simply click on the Refresh button in the browser. This will result in the display of an error message, as shown in screen 7.1.

 

Screen 7.1

 

The same "hi" when placed within the tags <% and %>, generates the error. This substantiates the fact that, anything enclosed within the % tags, is treated in a special manner. Now, click on the link 'Show Detailed Compiler Output'. This will display the name of the program, i.e. vbc.exe, as is evident in the screen 7.2. The name vbc symbolizes the Visual Basic Compiler.

 

Screen 7.2

 

This proves that the code written in an aspx file, gets converted into code of a programming language, such as Visual Basic. Since, in this book, we have taken an oath to work only with the C# programming language, we add the following line in the file a.aspx, and click on the Refresh button yet again.

 

a.aspx

<%@ Language=C# %>

hi

bye

<% hi %>

 

We obtain the same error as before. But, when we click on the link 'Show Detailed Compiler Output', the following claptrap is hurled at us:

 

Output

C:\WINNT\system32> " c:\winnt\microsoft.net\framework\v1.0.2914\csc.exe" /t:library /utf8output /R:"c:\winnt\microsoft.net\framework\v1.0.2914\mscorlib.dll" /R:"c:\winnt\assembly\gac\system.web.services\1.0.2411.0__b03f5f7f11d50a3a\system.web.services.dll" /R:"c:\winnt\assembly\gac\system.data\1.0.2411.0__b77a5c561934e089\system.data.dll" /R:"c:\winnt\assembly\gac\system.drawing\1.0.2411.0__b03f5f7f11d50a3a\system.drawing.dll" /R:"c:\winnt\assembly\gac\system.xml\1.0.2411.0__b77a5c561934e089\system.xml.dll" /R:"c:\winnt\assembly\gac\system\1.0.2411.0__b77a5c561934e089\system.dll" /R:"c:\winnt\assembly\gac\system.web\1.0.2411.0__b03f5f7f11d50a3a\system.web.dll" /out:"C:\WINNT\Microsoft.NET\Framework\v1.0.2914\Temporary ASP.NET Files\root\fa7064c6\2014c0f1\xkut9bsl.dll " /debug- /optimize+  "C:\WINNT\Microsoft.NET\Framework\v1.0.2914\Temporary ASP.NET Files\root\fa7064c6\2014c0f1\xkut9bsl.0.cs"

 

Observe the use of csc.exe as the compiler for C# program. Let us comprehend the above output, by first creating a sub-directory named pqr1 in the root, and then, by penning-down a small program named b.cs.

 

b.cs

public class yyy

{

public void abc()

{

System.Console.WriteLine("yyy abc");

}

}

 

The class yyy has a function called abc. The WriteLine function merely prints yyy abc on the screen. Although there is hardly any content in the class, we would still implore other developers to use it. The only answer is to generate a dll, or a dynamic link library from it. A dll is similar to an exe file, except for the fact that, a dll cannot be executed. Under Windows, all the code that is to be shared, is stored in a dll. It is simply a storehouse of functions.

 

Run the compiler as follows:

 

csc /t:library b.cs

 

The /t switch which by default creates an executable, along with library asks the compiler to create a dll. The 'dir' command, when used in the directory pqr1, will illustrate a file named b.dll. Now, create a file named a.cs, which will access the code of the class yyy.

 

a.cs

class zzz {

public static void Main()

{

yyy a;

}

}

 

On running the compiler as 'csc a.cs', the following error will be displayed:

 

a.cs(5,1): error CS0246: The type or namespace name 'yyy' could not be found (are you missing a using directive or an assembly reference?)

The error exposes the ignorance on the part of C#, with respect to the class yyy. Now, call the compiler with the switch  /r, as follows:

 

csc /r:b.dll a.cs

 

The /r or reference option provides a clue to the compiler, to look in the dll file named b.dll, for the code of the classes that it cannot appreciate. By default, the compiler attends to a large number of dlls, such as, mscorlib.dll for the System namespace or System.Data.Dll; for the data bases namespace, etc.

 

Now lets go back to a.aspx and understand the program as well as the output seen in the browser. Any line beginning with the <%@ symbol, is termed as a 'directive'. A 'directive' is akin to an order or an instruction. The 'Page' directive applies to a page or the Web Form. By using the 'language' attribute, we are asking the framework to use the C# compiler for compiling the C# code, generated by the system. Visual Basic is the default language to be chosen.

 

The output clearly divulges the fact that, the csc program is being run from the directory c:\winnt\microsoft.net\framework\v1.0.2914. The /t option results in the creation of a dll file, rather than an exe file. The 'utfoutput' option emits compiler messages, using the UTF encoding, which represents an English-like coding. The /R option merely provides a reference to the other dll's, for the C# compiler to attend to. Most of the dlls have been stipulated, even though they have already been checked by default. The /out option assigns the name of xkut9bsl.dll to the dll. The 'debug' option is turned-off. It has a minus sign. Thus, no debugging information crosses over into the dll. The 'optimize' option has a plus sign, which enables the compiler to generate optimized code, i.e. code that executes swiftly. The last parameter is the name of the C# program. Move into the specified folder, and check the files that get generated.

 

Now, click on the last link, Show Complete Compilation Source:. This displays the complete C# program generated by the compiler. The code is as follows:

 

Line 1://------------------------------------------------------------------------------

Line 2:// <autogenerated>

Line 3:// This code was generated by a tool.

Line 4:// Runtime Version: 1.0.2914.16

Line 5://

Line 6:// Changes to this file may cause incorrect behavior and will be lost if

Line 7:// the code is regenerated.

Line 8:// </autogenerated>

Line 9://------------------------------------------------------------------------------

Line 10:  

Line 11:   namespace ASP {

Line 12:   using System;

Line 13:   using System.Collections;

Line 14:   using System.Collections.Specialized;

Line 15:   using System.Configuration;

Line 16:   using System.Text;

Line 17:   using System.Text.RegularExpressions;

Line 18:   using System.Web;

Line 19:   using System.Web.Caching;

Line 20:   using System.Web.SessionState;

Line 21:   using System.Web.Security;

Line 22:   using System.Web.UI;

Line 23:   using System.Web.UI.WebControls;

Line 24:   using System.Web.UI.HtmlControls;

Line 25:  

Line 26:  

Line 27:   public class a_aspx : System.Web.UI.Page, System.Web.SessionState.IRequiresSessionState {

Line 28:

Line 29: private static System.Web.UI.AutomaticHandlerMethodInfos __autoHandlers;

Line 30:

Line 31: private static bool __intialized = false;

Line 32:

Line 33: private static System.Collections.ArrayList __fileDependencies;

Line 34:

Line 35: public a_aspx() {

Line 36: System.Collections.ArrayList dependencies;

Line 37: if ((ASP.a_aspx.__intialized == false)) {

Line 38: dependencies = new System.Collections.ArrayList();

Line 39: dependencies.Add("c:\\inetpub\\wwwroot\\aaa\\a.aspx");

Line 40: ASP.a_aspx.__fileDependencies = dependencies;

Line 41: ASP.a_aspx.__intialized = true;

Line 42: }

Line 43: }

Line 44:

Line 45: protected override System.Web.UI.AutomaticHandlerMethodInfos AutoHandlers {

Line 46: get {

Line 47: return ASP.a_aspx.__autoHandlers;

Line 48: }

Line 49: set {

Line 50: ASP.a_aspx.__autoHandlers = value;

Line 51: }

Line 52: }

Line 53:

Line 54: protected System.Web.HttpApplication ApplicationInstance {

Line 55: get {

Line 56: return ((System.Web.HttpApplication)(this.Context.ApplicationInstance));

Line 57: }

Line 58: }

Line 59:

Line 60: public override string TemplateSourceDirectory {

Line 61: get {

Line 62: return "/aaa";

Line 63: }

Line 64: }

Line 65:

Line 66: public override void InstantiateIn (System.Web.UI.Control control) {

Line 67: this.__BuildControlTree (control);

Line 68: }

Line 69:

Line 70: private void __BuildControlTree(System.Web.UI.Control __ctrl) {

Line 71: __ctrl.SetRenderMethodDelegate (new System.Web.UI.RenderMethod (this.__Render__control1));

Line 72: }

Line 73:

Line 74: private void __Render__control1 (System.Web.UI.HtmlTextWriter __output, System.Web.UI.Control parameterContainer) {

Line 75: __output.Write("\r\nhi\r\nbye\r\n");

Line 76:

Line 77: #line 4 "c:\inetpub\wwwroot\aaa\a.aspx"

Line 78:

Line 79:   hi

Line 80:  

Line 81:

Line 82: #line default

Line 83: }

Line 84:

Line 85: protected override void FrameworkInitialize () {

Line 86: this.FileDependencies = ASP.a_aspx.__fileDependencies;

Line 87: }

Line 88:

Line 89: public override int GetTypeHashCode() {

Line 90: return 2141278421;

Line 91: }

Line 92:   }

Line 93:   }

Line 94:  

 

Let us understand this machine generated C# code, from the aspx file. The code becomes apparent only when an error is detected. Otherwise, it is deleted. The comments can easily be ignored, as they merely divulge the fact that a program has generated the code, without any human intervention, which is self-evident. However, the program name is not revealed. Then, there is a 'namespace' statement, with the namespace of ASP, which integrates the entire code.

 

The program always starts with the 'using' statements, and there are a total of 13 such statements. As a result, the classes present within these namespaces, do not require to be prefaced by the namespaces any longer. Microsoft expects you to utilize classes from these namespaces more often, than from other namespaces.

 

 

Since the name of the aspx file is 'a', the C# class is assigned the name a_aspx. This call is derived from Page, which belongs to the System.Web.UI namespace. This class represents a page, which is dispatched by the server to the browser. It also collects all the controls that are visible on the page. The class has specially been devised to handle aspx files, and it contains numerous members, which may be employed to build dynamic content. The class a_aspx, also derives from the IRequiresSessionState interface, which forms a part of System.Web.SessionState namespace. This is because, the HTTP protocol does not 'maintain state', whereas the interface does so, while working with sessions. This interface has no members at all. Hence, it is called a 'marker'.

 

There are three instance variables. All variables that are created by the system, are normally prefixed with two underscores. This is done, in order to avoid any name clashes between the system variables and the user defined variables. Therefore, follow the simple rule: 'As a user, as long as you do not create a variable name that is prefixed with two underscores, no grief awaits you.'

 

The first one is named as __autoHandlers. Presently, we are not in a position to explain the working of this instance variable, since there is no help associated with it. Microsoft, which is famous for holding back crucial information, declines to disclose these details, since it does not expect the user to touch upon, or use the above class. Or, maybe as a remote possibility, the programmers at Microsoft forgot to document it.

 

The second instance variable, __initialized, has been set to False. One clarification is in order here. Since the keyword attached to this class is 'static', it is not an instance variable. The use of this variable will be illustrated to you, in a short while.

 

The third variable, __fileDependencies, is of data type ArrayList, which stores a collection. An ArrayList is often used to store multiple values. Use of arrays simplifies handling of the multiple values, but retrieval of data can be slow, if the array is large due to the absence of search facility.

 

As usual, the constructor gets called first. There is a local variable named 'dependencies', of data type ArrayList. The difference in the handling of of local and instance veriable is, that the variable known as 'dependencies', will be discarded at the end of this function, whereas, fileDependencies, being an instance variable, shall live till the instance is alive.

 

Firstly, the value of variable __initialized is checked. Since the value is False, the 'if' statement results in True. Before the 'if' statement ends, the value of __initialized is reverted back to True. As the variable is 'static' in nature, we have to use the name of the class and the namespace, despite this being optional. Thus, the above 'if' statement shall be executed only once. After having created an instance of the ArrayList class, the Add function is called, to add a string to the ArrayList object. This string contains the full path name of the aspx file. Only one Add function is present, since we have only file to add.

 

Thereafter, the instance variable __fileDependencies is initialized to a value of 'dependencies'. Apparently, there is no real need of the 'dependencies' variable, since the Add function could have been called from __fileDependencies. But, we have no business wrangling over this issue with a computer generated program.

 

The read/write property called AutoHandlers, exists in the Page class, since it contains the keyword 'override'. The term 'override' is used only when the member exists in the base class. This does not necessarily refer to Page alone, but could also refer to the classes that Page itself is derived from.

 

The standard routine is executed, i.e. the instance variable __autoHandlers is initialized to the value passed to this property, and this value is returned in the 'get' accessor. Yet again, there is no help available here!

 

The 'read only' property ApplicationInstance, of data type HttpApplication, does not belong to the Page class. However, the Page class has a Context property of datatype HttpContext, which embodies information about the current page request. The HttpContext class in turn, has a member called ApplicationInstance, of data type HttpApplication, which signifies the current Http Request. There is no need for using the cast operator anywhere, since both the sides have an object, which has directly or indirectly, been derived from HttpApplication. The read only property TemplateSourceDirectory returns the virtual directory of the web server as it contains the aspx files. We are shown the subdirectory of aaa in inetpub.

 

The function InstantiateIn, is used to build a list of controls in a Control Tree. These controls have been picked up from the aspx file. This function has been passed a parameter called 'control', of data type Control, which will eventually contain the Control Tree. Then, the function __BuildControlTree is called with the parameter 'control'.

 

The Control class holds a function called SetRenderMethodDelegate, which is passed the address of the function __Render__control1. This function would have to be called, each time the controls are to be rendered or drawn on a page. This function is assigned with the help of the delegate RenderMethod so that the system handles this activity.

 

The most important function is __Render__control1. This function is passed two parameters. The first parameter is __output, of type HtmlTextWriter, which knows how to write to the Web Server, which in turn, sends the html file over. The second parameter represents the Control.

 

The output function has a member called Write, which writes to the Web Server. Thus, the entire content i.e. the static html text, as well as, the aspx code in <%, is passed as a string to this function. Effectively, the entire aspx file is placed within this function. But, whatever is enclosed within <%, has to meet the specifications of the syntax of C# or aspx.

 

The function FrameworkInitialize is used to initialize the page. Also, the property FileDependencies of data type ArrayList is initialized, so as to contain the list of file names, which are needed by the HttpResponse object. Finally, the GetTypeHashCode function returns a number, known as the Hash Code, for this page. The hash code is an index that is stored in the lists, along with the object, in order to retrieve data faster. Earlier there were 14 files created in the above folder, but once the error vanished, the count escalated to 16.

 

The two recently introduced files are _vssbxra.dll, which is 4k large, and an XML file. None of these files mean much to us. However, what is finally revealed is that, the aspx file gets converted into C# code by the C# compiler, which is then converted into a dll, and placed in a folder. This dll is executed by the Web Server to generate an html file, as is evident in the Form Designer, and then, it is finally dispatched across the internet.

 

Create a fresh project, using File - New - Project. As was done earlier, select C# Projects in the Projects pane, and opt for ASP.Net application in the Template Pane. Change the name to 'h2', and click on OK. Ensure that the ToolBox and the Properties Windows are on display. Then, incorporate a button from the Web Forms tab. On changing the Text property to 'eeb', the label on the button will also get amended according. Thereafter, double click on the button, to get transported to the Code Painter. Note that the filename is WebForm1.aspx.cs. Within a function called button1_Click, write the following line of code:

 

Response.Write("button1");

 

Then, click on the WebForm1.aspx tab, to switch to Design Mode, and then, move on to the HTML tab in the ToolBox. From the list of controls, choose a button and drop it into the Form. Change the 'value' property of this control to HTML. Though the two buttons may look very similar, they actually possess different properties. Now, double click on the HTML button, to enable insertion of some code. On doing so, a message box pops up, as shown in screen 7.3.

 

Screen 7.3

 

It lucidly reveals that the control is an HTML control, and not a Web Control. Thus, no code can be entered into this control, unless it is converted into a Server Control.

 

Click on OK and then save all the files, by clicking on the menu option File - Save All. Move into the h2 folder, to view the code that gets generated. There are a total of 12 files. To unravel the behind-the-scene activities, we need to understand the code contained in these 12 files. The first file that we take into consideration is WebForm1.aspx.

 

WebForm1.aspx

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="h2.WebForm1" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

<HEAD>

<meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">

<meta name="CODE_LANGUAGE" Content="C#">

<meta name="vs_defaultClientScript" content="JavaScript (ECMAScript)">

<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

</HEAD>

<body MS_POSITIONING="GridLayout">

<form id="Form1" method="post" runat="server">

<asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 74px; POSITION: absolute; TOP: 245px" runat="server" Text="Web" Width="96px" Height="26px"></asp:Button>

<INPUT style="Z-INDEX: 102; LEFT: 232px; WIDTH: 82px; POSITION: absolute; TOP: 242px; HEIGHT: 30px" type="button" value="HTML">

</form>

</body>

</HTML>

 

Now, create a new directory named 'h3' in c:\inetpub\wwwroot. Copy the file WebForm1.aspx into this directory. Open the file in the h3 subdirectory, and then, delete only the first directive line. Once this is done, load IE and write the following URL:

 

http://localhost/h3/WebForm1.apsx

 

On doing so, two buttons will be displayed on the screen, as can be seen in screen 7.4.

 

Screen 7.4

 

Clicking on the buttons does not yield any outcome at all. The two buttons get converted into two separate tags. The Web Form button becomes a tag named asp:Button with an id of Button1 and text of Web.

 

The HTML Button control takes the form of a pure HTML tag input, with the type specified as Button, and with the value as HTML. Now, return to folder h2, and ensure that no files are housed in the bin folder. Then, in the browser, enter the URL as http://localhost/h2/WebForm1.aspx. Screen 7.5 shows the output.

 

Screen 7.5

 

The error that is generated comes as a bolt from the blue, since we had expected not any errors to occur, other than in WebForm1.aspx. However, the error references the file Global.asax. If this file is present in the folder, it gets displayed first.

 

The Web Server searches for a class named h2.Global, which it is unable to locate. Run the C# compiler in the h2 directory as follows: 

 

Csc /t:library /out:c:\inetpub\wwwroot\h2\bin\Webform1.dll Global.asax.cs

 

The /out option creates a dll in the bin sub-directory. Now, click on the Refresh button in IE. This will generate another error, as shown in screen 7.6.

 

Screen 7.6

 

The error states that it is unable to locate the class named h2.WebForm1. So once again, run the compiler using the following command:

 

Csc /t:library /out:c:\inetpub\wwwroot\h2\bin\Webform1.dll Global.asax.cs WebForm1.aspx.cs

 

Now, refresh the screen, and you will be relieved to see that no more errors are visible. Clicking on the first button, shows screen 7.7 with the word 'button1' displayed on top of the window.

 

Screen 7.7

 

Let us understand as to what exactly transpires behind the screen.

 

In order to raise the veil off this mystery, open the file Global.asax in the h2 subdirectory.

 

Global.asax

<%@ Application Codebehind="Global.asax.cs" Inherits="h2.Global" %>

 

This file has a single line, containing an aspx directive. The file is also known as the ASP.Net application file, as it responds to application level events or session event handlers, raised either by the ASP.NET or by the class HttpModules. Whilst creating the dll, this file is accessed, if it exists in the root directory.

 

If you essay reading this file across the internet by entering its name in the URL, the request will get rejected. Thus, external users are not allowed to view its contents.

 

The Application directive merely raises the stake, since it pertains to an entire application, unlike the page directive, which is applicable to a single page only. The Inherits directive specifies the parent class from which the derived classes should inherit. In this case, Global is the name of the class, and h2 is the namespace. If this class is not available, an error is generated. The CodeBehind attribute refers to the file that contains the code, which in our case, is the file Global.asax.cs. At run time, the code must be available in a dll, of any name, located in the bin folder. It does not need to be named as WebForm1.dll. Now, let us look at the next file, named Global.asax.cs.

 

Global.asax.cs

using System;

using System.Collections;

using System.ComponentModel;

using System.Web;

using System.Web.SessionState;

namespace h2

{

            /// <summary>

            /// Summary description for Global.

            /// </summary>

            public class Global : System.Web.HttpApplication

            {

                        protected void Application_Start(Object sender, EventArgs e)

                        {

 

                        }

                        protected void Session_Start(Object sender, EventArgs e)

                        {

 

                        }

                        protected void Application_BeginRequest(Object sender, EventArgs e)

                        {

                        }

                        protected void Application_EndRequest(Object sender, EventArgs e)

                        {

 

                        }

                        protected void Session_End(Object sender, EventArgs e)

                        {

 

                        }

                        protected void Application_End(Object sender, EventArgs e)

                        {

 

                        }

            }

}

 

The class Global belongs to the h2 namespace, and contains exactly six functions. If we want our code to be called during the start-up of the Application, then it should be placed in the function Application_Start. In the same vein, code that is to be executed at the start of a session, ought to be placed in the function Session_Start. The difference between an Application and a Session is that, a Session starts with the invocation of a browser and ends when the browser is shut down, whereas, an Application object lives on till the end. Thus, you can write whatever code you would like to call when any of the above events occur. This single error led us onto another error, wherein the class h2.WebForm1 could not be located. This class happens to be in the file WebForm1.aspx.cs.

 

WebForm1.aspx.cs

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

namespace h2

{

            /// <summary>

            /// Summary description for WebForm1.

            /// </summary>

            public class WebForm1 : System.Web.UI.Page

            {

                        protected System.Web.UI.WebControls.Button Button1;

           

                        public WebForm1()

                        {

                                    Page.Init += new System.EventHandler(Page_Init);

                        }

                        private void Page_Load(object sender, System.EventArgs e)

                        {

                                    // Put user code to initialize the page here

                        }

                        private void Page_Init(object sender, EventArgs e)

                        {

                        //

                        // CODEGEN: This call is required by the ASP.NET Web Form Designer.

                        //

                                    InitializeComponent();

                        }

                        #region Web Form Designer generated code

                        /// <summary>

                        /// Required method for Designer support - do not modify

                        /// the contents of this method with the code editor.

                        /// </summary>

                        private void InitializeComponent()

                        {   

                                    this.Button1.Click += new System.EventHandler(this.Button1_Click);

                                    this.Load += new System.EventHandler(this.Page_Load);

 

                        }

                        #endregion

                        private void Button1_Click(object sender, System.EventArgs e)

                        {

                                    Response.Write("button1");

                        }

            }

}

 

The file starts with the usual set of 'using' statements, along with their namespaces. This is followed by the WebForm1 class, which is derived from the Page class. In the application, out of the two buttons, only the Web Forms button becomes an instance variable named Button1, whereas the HTML button does not get any reference at all. The button created in the Application belongs to the Forms class, whereas this Button originates from the WebControls class. They are as disparate as water is from oil.

 

The constructor is always the first to be called. It has the Page property, of data type Page, representing the entire aspx file. This Page class has an event called Page_Init, which gets called when the page is created. It is the first step in the lifecycle of a page. At this stage, we are not allowed to view 'state information', as it contains no values. Also, access to any other server control also is not allowed.

 

The InitializeComponent is called in the function Page_Init, wherein the Click event of the button is assigned to the function Button1_Click. The Load event is triggered off, whenever the page is to be sent across. Also, any code that is to be executed for every page, should be placed in the function Page_Load. However, there are very few restrictions that we need to abide by, when the page is to be sent across. Both the .cs programs must be compiled, for successful generation of the dll.

 

Clicking on the button leads to a display of 'button1' in the browser window. This occurs only when the function Button1_Click gets called. In this function, we use the Response object, of data type HttpResponse, which contains a function called Write. This function is aware as to how information is to be passed to the Web Server, which in turn, sends it across to the Web Client.

 

Screen 7.8

 

The significant point to be noted here is that, a Web Server can only send html files across. It is not capable of achieving anything more. Thus, when we click the button, the web server is aware of our intentions. Accordingly, it makes sure that the HTML page is regenerated. It is the web server, which keeps track of the code that must be executed while generating an html file. The web client is totally oblivious about the activities being performed at the server's end. It is totally unaware that the dll is responsible for generating the html code, and that the aspx file gets converted into a C# program.

 

Thus, you should bear in mind that, when running an application, Visual Studio.Net executes the following chores:

1)   It generates code for files such as Global.asax and Global.asax.cs.

2)   It compiles the cs files into a dll, and places it in the bin folder.

3)   It calls IE, and writes the URL in the IE window.

4)   IE sends the URL to the Web Server.

5)   The Web Server converts the aspx file into C# code.

6)   The C# compiler converts the C# code into a dll, and places it in some unique folder.

7)   This dll is executed, and as events occur, functions such as Page_Load get called.

8)   Using properties like Response, or parameters like __output, the Web Server collects the HTML file, and sends it to the browser.

9)   The browser can be either Netscape or IE, since only HTML is sent across.

 

Thus, a lot of activities take place backstage. Now, let us consider the other files that get generated.

 

Add the following lines at the end of the file Webform1.aspx.

 

WebForm1.aspx

<%

Hell

%>

 

Clicking on 'Show Detailed Compiler Output' reveals that the /R option refers to WebForms1.dll :

 

/R:"c:\winnt\microsoft.net\framework\v1.0.2914\temporary asp.net files\h2\c5ac8aa9\81619964\assembly\downloaded2\595519b8\00c86a68_c801c101\webform1.dll"

 

Clicking on 'Complete Compilation Source' reveals some modifications in the C# code. We shall expose you to only those specific changes.

 

Line 11:   namespace ASP {

Line 25:   using ASP;

Line 26:   using h2;

Line 29:[System.Runtime.CompilerServices. CompilerGlobalScopeAttribute()]

Line 30:   public class WebForm1_aspx : h2.WebForm1, System.Web.SessionState.IRequiresSessionState {

Line 31:

Line 32:

Line 33: #line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 34: protected System.Web.UI.HtmlControls.HtmlForm Form1;

Line 35:

Line 36: #line default

Line 37:

Line 40: private static object __stringResource;

Line 41:

Line 43:

Line 44: public WebForm1_aspx() {

Line 45: System.Collections.ArrayList dependencies;

Line 46: if ((ASP.WebForm1_aspx.__intialized == false)) {

Line 47: ASP.WebForm1_aspx.__stringResource = System.Web.UI.TemplateControl.ReadStringResource(typeof(ASP.WebForm1_aspx));

Line 52: }

Line 53: this.Server.ScriptTimeout = 30000000;

Line 54: }

Line 55:

Line 56: protected override bool SupportAutoEvents {

Line 57: get {

Line 58: return false;

Line 59: }

Line 60: }

Line 61:

Line 78: private System.Web.UI.Control __BuildControlButton1() {

Line 79: System.Web.UI.WebControls.Button __ctrl;

Line 80:

Line 81: #line 12 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 82: __ctrl = new System.Web.UI.WebControls.Button();

Line 83:

Line 84: #line default

Line 85: this.Button1 = __ctrl;

Line 86:

Line 87: #line 12 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 88: __ctrl.ID = "Button1";

Line 89:

Line 90: #line default

Line 91:

Line 92: #line 12 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 93:

((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style", "Z-INDEX: 101; LEFT: 89px; POSITION: absolute; TOP: 93px");

Line 94:

Line 95: #line default

Line 96:

Line 97: #line 12 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 98: __ctrl.Text = "web";

Line 99:

Line 100:#line default

Line 101:return __ctrl;

Line 102:}

Line 103:

Line 104:private System.Web.UI.Control __BuildControlForm1() {

Line 105:System.Web.UI.HtmlControls.HtmlForm __ctrl;

Line 106:

Line 107:#line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 108:__ctrl = new System.Web.UI.HtmlControls.HtmlForm();

Line 109:

Line 110:#line default

Line 111:this.Form1 = __ctrl;

Line 112:

Line 113:#line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 114:__ctrl.ID = "Form1";

Line 115:

Line 116:#line default

Line 117:

Line 118:#line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 119:__ctrl.Method = "post";

Line 120:

Line 121:#line default

Line 122:System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

Line 123:

Line 124:#line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 125:__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n\t\t\t"));

Line 126:

Line 127:#line default

Line 128:

Line 129:#line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 130:this.__BuildControlButton1();

Line 131:

Line 132:#line default

Line 133:

Line 134:#line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 135:__parser.AddParsedSubObject(this.Button1);

Line 136:

Line 137:#line default

Line 138:

Line 139:#line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 140:__parser.AddParsedSubObject(new System.Web.UI.LiteralControl ("\r\n\t\t\t<INPUT style=\"Z-INDEX: 102; LEFT: 216px; POSITION: absolute; TOP: 165px\" typ" +

Line 141:  "e=\"button\" value=\"html\">\r\n\t\t"));

Line 142:

Line 143:#line default

Line 144:return __ctrl;

Line 145:}

Line 146:

Line 147:private void __BuildControlTree (System.Web.UI.Control __ctrl) {

Line 148:

Line 149:#line 1 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 150:this.__BuildControlForm1 ();

Line 151:

Line 152:#line default

Line 153:System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

Line 154:

Line 155:#line 1 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 156:__parser.AddParsedSubObject(this.Form1);

Line 157:

Line 158:#line default

Line 159:__ctrl.SetRenderMethodDelegate(new System.Web.UI.RenderMethod(this.__Render__control1));

Line 160:}

Line 161:

Line 162:private void __Render__control1(System.Web.UI.HtmlTextWriter __output, System.Web.UI.Control parameterContainer) {

Line 163:this.WriteUTF8ResourceString (__output, 0, 405, true);

Line 164:

Line 165: #line 11 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 166:parameterContainer.Controls[0]. RenderControl (__output);

Line 167:

Line 168:#line default

Line 169:__output.Write("\r\n\t</body>\r\n</HTML>\r\n");

Line 170:

Line 171:#line 17 "c:\inetpub\wwwroot\h2\WebForm1.aspx"

Line 172:

Line 173:  hell;

Line 174: 

Line 175:

Line 176:#line default

Line 177:}

Line 178:

Line 179:protected override void FrameworkInitialize() {

Line 180:SetStringResourcePointer(ASP.WebForm1_aspx.__stringResource, 405);

Line 181:this.FileDependencies = ASP.WebForm1_aspx.__fileDependencies;

Line 182:}

Line 183:

Line 184: public override int GetTypeHashCode() {

Line 185:return -530771324;

Line 186:}

Line 187:  }

Line 188:  }

Line 189: 

 

Two more 'using' statements with ASP and h2 have been appended This is because the files Global.asax and Webform1.aspx.cs contain code within the namespace h2. An attribute of CompilerGlobalScopeAttribute has been added to the WebForm1_aspx class to render it a global scope. The class is used mainly to communicate with debugging tools. Hence, it should be implemented only when a program that behaves like a compiler is being built.

 

The class originates from the namespace System.Runtime.CompilerServices. Line 30 shows that the class WebForm1_aspx is derived from WebForm1, in the h2 namespace. This explains the functioning of the 'inherits' directive. The class h2, in turn, is derived from the class Page. The directive #line accepts two parameters, viz. the current line number and the name of the file. Due to this, on the occurrence of an error, Line 33 is renumbered as Line 11.

 

The name of the source file is also included while displaying error messages or warnings. This directive is to be used only when the default values chosen by the compiler, are to be overridden. The default value for the name of the file is the source file. The directive #line with the word 'default' resets the line number to the original.

 

Henceforth, we shall ignore all the #line directives, as they are only an aid to the compiler, in displaying the line where an error takes place. On line 34, there is an instance variable named Form1, which is of data type HtmlForm. This variable acts as a container for all the Server Controls on a web page. All server controls that post back data to the server, must be placed between the open and closed tags of a HtmlForm object. This variable also provides a programmer access to the HTML tag on the server. On line 40, there exists an instance variable named __stringResource, of type object. The class object is the mother of all classes. Therefore, all classes are derived from it. It has very basic functionality. In cases where the data type is unknown, the use of a class object puts the issue to rest.

 

In the constructor, additional code has been provided. The keyword 'typeof' returns a string containing the type of the expression. It can return only one of the following values: string, boolean, object, function, and undefined. Lest we forget, the name of our class, WebForm1_aspx also qualifies as an object. Help for the function ReadStringResource does not exist. So, we shall sidestep it, for the time being.

 

The Page class has a property named Server, of data type HttpServerUtility . The datatype, in turn, has a property named ScriptTimeout, which allows the server to determine the duration in seconds, subsequent to which, the script times out, because the server does not have too much time to spend in executing an aspx file. However, the number used is too large, therefore defeating the purpose of this function.

 

The value assigned to property SupportAutoEvents determines whether Auto Events are supported or not. The value of False evidently indicates that Auto Events are not supported. The function __BuildControlButton1 performs an assortment of tasks. First of all, a local variable __ctrl of type Button is created, and then, initialized to a new instance. Thereafter, the instance variable Button1 is equated to the local variable __ctrl. We have already stated the futility of arguing with a computer program that generates such code. The Button control has a large number of attributes, which are set using the SetAttribute function. The Text property is also amended to 'Web', in order to alter the label of the button.

 

In the function __BuildControlForm1, a similar local variable called __ctrl is created, and initialized to a new instance. The Form1 property is then initialized to this HtmlForm object. The id or name is shown as the string Form1. A local variable named __parser, of data type IParserAccessor, is then created. Any name that begins with the capital letter I, is an 'interface'. Hence, IParserAccessor is an interface, which allows access to the parser, for a control. Only two classes implement this interface, viz. Control and ListItem. As __ctrl is derived from HtmlForm, it is indirectly derived from IParserAccessor. For those of you who have a penchant for statistics, it would be interesting to know that this interface has only one function named AddParsedSubObject.

An instance of LiteralControl is passed to this function, so that it can be added to the HtmlForm object, or to the parent object. This LiteralControl, in this case, is the Html button. This control represents all Html widgets such as textboxes, buttons et al., for which the server does not have to spend processing time. The server stores the value of the Text property, in order to 'maintain state'.

 

A control that does not require a 'runat' server attribute, gets converted to a LiteralControl. The constructor is provided the entire HTML text, which represents the control. The function __BuildControlTree calls __BuildControlForm1. Once again, the parser in the local variable __parser, is accessed from the __ctrl parameter that is passed. The Form1 object is then added as a child, to the Control class object __ctrl.

 

Using the function __Render__control1, the page is rendered. In the render function, the function WriteUTF8ResourceString is used. The RenderControl requires an HtmlTextWriter object, as a parameter. Thus, the contents of the server control, i.e. the button, are written to the text writer. The button Controls[0] signifies the first Button, and not the HTML button. Thus, working with server controls, is indeed much more time consuming. The Html controls have a lower overhead. This explanation has covered enough ground, to help you understand the code that is generated by the system.

 

Let us now unveil the code that gets generated while displaying data in a table, using a data grid. So, as always, start with a new project of type Visual C# Project and a template of ASP.Net Application. Name the application o1, and then, click on OK. The ToolBox and Properties Window must be visible.

 

Choose the Data tab in the Toolbox, and drag-and-drop an OleDbDataAdapter control into the form. In the familiar Wizard, click on the Next button, and from amongst the previously created connections, select the connection to the pubs database, VMUKHI.pubs.db2. Then, click on the Next button. Let the radio button of SQL statement remain selected. Now, click again on the Next button, and enter the SQL statement as follows:

 

Select * from authors

 

Finally, click on the Finish button.

 

Now, double click on the form, to arrive at the file WebForm1.aspx.cs. All the C# code gets added to this file, when the OleDbDataAdapter is added. The code remains the same, when the OleDbDataAdapter is added in the Windows Application. The only variation lies in the output file. In a Windows Application, the file Form1.cs becomes an exe file, whereas, in an ASP.Net application, the Web Server converts the code into a dll file. The other files, which the main dll file requires, are placed in the bin folder. The rules pertaining to a data grid apply here too.

 

Double clicking on the Form, displays a function called Page_Load. This function gets executed, each time the page is sent over. It is here that the Dataset object is filled up, using the Fill function. Thus, the workings of the data tab control remain the same for Web Applications and Web Forms. Once these workings are well understood, delete the OleDbDataAdapter and the other objects.

 

Now, to understand the Validator control, bring in a TextBox and a Button control. Then, scroll down the toolbox and initiate the RequiredFieldValidator control. In the Properties Window, click on the drop down listbox of property ControlToValidate, and select the only available control of TextBox1. The Text property is given a value of *.

 

On running the web application and clicking on the button, the * sign is displayed. Next in IE, on clicking the menu option of View - Source, the html file that is generated, is displayed. We have only displayed the relevant portions of the html file below.

 

<HTML>

<form name="Form1" method="post" action="WebForm1.aspx" language="javascript" onsubmit="ValidatorOnSubmit();" id="Form1">

<script language="javascript" src="/aspnet_client/system_web/1_0_2914_16/WebUIValidation.js ">

</script>

<input name="TextBox1" type="text" id="TextBox1" style="Z-INDEX: 101; LEFT: 112px; POSITION: absolute; TOP: 73px" />

<span id="RequiredFieldValidator1" controltovalidate="TextBox1" errormessage="RequiredFieldValidator" evaluationfunction =" RequiredFieldValidatorEvaluateIsValid " initialvalue="" style="color:Red;Z-INDEX:102;LEFT:162px;POSITION:absolute;TOP:167px;visibility:hidden;">*</span>

<input type="submit" name="Button1" value="Button" onclick="if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="Button1" style="Z-INDEX: 103; LEFT: 141px; POSITION: absolute; TOP: 248px" />

<script language="javascript">

<!--

var Page_Validators =  new Array(document.all["RequiredFieldValidator1"]);

// -->

</script>

<script language="javascript">

<!--

var Page_ValidationActive = false;

if (typeof(clientInformation) != "undefined" && clientInformation.appName.indexOf("Explorer") != -1) {

if (typeof(Page_ValidationVer) == "undefined")

alert("Unable to find script library '/aspnet_client/system_web/1_0_2914_16/WebUIValidation.js'. Try placing this file manually, or reinstall by running ' aspnet_regiis -c'.");

else if (Page_ValidationVer != "121")

alert("This page uses an incorrect version of WebUIValidation.js. The page expects version 121. The script library is " + Page_ValidationVer + ".");

else

ValidatorOnLoad ();

}

function ValidatorOnSubmit () {

if (Page_ValidationActive) {

ValidatorCommonOnSubmit();

}

}// -->

</script>

</form>

</body>

</HTML>

 

Before embarking upon an explanation of the above code, ensure that the RequiredFieldValidator is chosen in Visual Studio.Net and change the value of the property EnableClientScript, from True to False. This will lead to the addition of the attribute of EnableClientScript=false. Run the application, and then in IE click on the menu option of View - Source, to see the following HTML file, which is smaller in size.

 

<HTML>

<form name="Form1" method="post" action="WebForm1.aspx" id="Form1">

<input name="TextBox1" type="text" id="TextBox1" style="Z-INDEX: 101; LEFT: 112px; POSITION: absolute; TOP: 73px" />

<span id="RequiredFieldValidator1" style="color:Red;Z-INDEX: 102; LEFT: 162px; POSITION: absolute; TOP: 167px">*</span>

<input type="submit" name="Button1" value="Button" onclick="if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="Button1" style="Z-INDEX: 103; LEFT: 141px; POSITION: absolute; TOP: 248px" />

</form>

</body>

</HTML>

 

Unlike the earlier HTML file, the code is much smaller, as there is no Java Script code to be called. This is because it is the server that performs the error checks, and not the browser. The web server has stored the information that the TextBox should not be left blank. If you click on the HTML tab at the bottom, this fact will become evident to you. Since we brought-in the control, RequiredFieldValidator, an object RequiredFieldValidator1, of data type RequiredFieldValidator, has been created as an instance variable. Thus, when any control is brought into a Form, it creates an object or an instance variable of a datatype, similar to that of the control.

 

protected System.Web.UI.WebControls.TextBox TextBox1;

protected System.Web.UI.WebControls.Button Button1;

protected System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator1;

 

Since the RequiredFieldValidator1 object is not being utilized presently, we can safely comment it out. The variable is created, so that its members can be accessed at run time, and its default behavior can be amended.

 

 

Let us now study the Java Script code present in the html file. The form tag has an attribute named 'onsubmit', which specifies the name of a function to be called, before data is transmitted to the server. Thus, each time we click on a button of type 'submit', function ValidatorOnSubmit will be called. If it returns True due to an error, the submission of data to the server will be cancelled. The html file contains the word 'function', followed by the name of the function ValidatorOnSubmit. A function in Java Script is created in this manner. Java Script is called a scripting language, and it is easier to learn than C#. It embodies almost all the features of a language like C#, but it is a typeless language, i.e. its variables do not have any types at all.

 

The code in Java Script has to be placed within the tags of 'script' and '/script'. To create a variable, the word 'var' must be placed in front of a name. At times, even the word 'var' is optional. The variable Page_ValidationActive has been assigned a value of False, and then, it is changed to True, thereby, calling the function ValidatorCommonOnSubmit. So, whenever some data is to be sent to the server, the function gets called, depending upon the 'if' statement and the value of the boolean variable Page_ValidationActive. The file WebUIValidation.js is located on our hard disk. So, if you search for it, you would find it dwelling in a large number of locations. It contains about four hundred lines of code. Each time the button is clicked, the code associated with the event 'onclick' gets called.

 

First of all, we wish to check whether Page_ClientValidate is a function or not. Hence, we verify the return value of 'typeof' with a string function, since in Java Script, the keyword 'typeof' discloses the entity that has been passed to it in the form of a string. In case the 'if' statement returns True, the function Page_ClientValidate is called.

 

Go to the folder

 

c:\inetpub\wwwroot\aspnet_client\system_web\1_0_2914_16

 

Instead of displaying the entire file WebUIValidation.js, we will show you only the relevant functions. In the Java Script code, all code within the script and /script tags, gets executed first. This rule does not apply to functions, since they get created, and not called. The variable Page_Validators becomes an array and then the 'new' keyword, adopted by all languages, is utilized to initialize it. The html page is represented by a large number of free objects. For example, the 'document' object gives us access to the entire document. Thus, the array is made up of the string member called RequiredFieldValidator1, which is the name or id of 'span'. 'Span' contains attributes of the control to validate, and the Error Message. In other words, the 'span' tag represents the Validator.

 

There is one more Error Check statement mentioned a little later in a file, which checks if the data type of an item 'clientinformation', is undefined; i.e. whether it exists as a valid object, and whether or not, and whether the appName field is Explorer. If the condition is True, then and only then, it searches for the presence of a variable Page_ValidationVer.

 

 

 

The Page_ValidationVer is a variable, created in the js file, and is assigned a value of 121. The absence of this variable would make the type as 'undefined', and thus, display a message box, as a result of the alert function. The main problem, which emanates from working with different programming languages is, having to learn from experience that the functions 'alert' and 'Show' achieve one and the same thing. The version number that is to be used must be 121. Therefore, a check is performed for this purpose. Any other version does not help. Thus, the 'else if' clause is used. Finally, if none of the above is True, i.e. the version number shows 121, function ValidatorOnLoad is called.

 

function ValidatorOnLoad () {

if (typeof(Page_Validators) == "undefined")

return;

 

var i, val;

for (i = 0; i < Page_Validators.length; i++) {

val = Page_Validators[i];

if (typeof(val.evaluationfunction) == "string") {

eval("val.evaluationfunction = " + val.evaluationfunction + ";");

}

if (typeof(val.isvalid) == "string") {

if (val.isvalid == "False") {

val.isvalid = false;

Page_IsValid = false;

}

else {

val.isvalid = true;

}

} else {

val.isvalid = true;

}

if (typeof(val.enabled) == "string") {

val.enabled = (val.enabled != "False");

}

if (typeof(val.controltovalidate) == "string") {

ValidatorHookupControl(document.all[val.controltovalidate], val);

}

if (typeof(val.controlhookup) == "string") {

ValidatorHookupControl(document.all[val.controlhookup], val);

}

 

}

Page_ValidationActive = true;

}

 

In this function, we merely check for the existence of the variable Page_Validators. If not found, typeof returns the value of 'undefined', thereby, quitting the function with the 'return' statement. Two variables named 'i' and 'val' are created. Every array has a member called 'length', which contains the number of elements contained in the array. In our case, its value will be 1, as we have only one string in the array variable Page_Validators.

 

The 'for' statement starts execution with the value of i as 0. The condition of the 'for' statement is True, because the value of 0 is less than 1. Thus, 'val' is initialized to the string 'RequiredFieldValidator1', contained in the 0th index of the array. Then, the value of the various members is changed as follows:

   The variable val is assigned the value of evaluationfunction.

   The variable isvalid is Enabled.

   The value of Page_IsValid is set to True.

   The value of Page_ValidationActive is set to True.

 

This 'for' loop is executed only once.

 

function Page_ClientValidate () {

var i;

for (i = 0; i < Page_Validators.length; i++) {

ValidatorValidate(Page_Validators[i]);

}

ValidatorUpdateIsValid();

ValidationSummaryOnSubmit();

Page_BlockSubmit = !Page_IsValid;

return Page_IsValid;

}

 

The string RequiredFieldValidator1 is passed to the function ValidatorValidate.

 

function ValidatorValidate(val) {

val.isvalid = true;

if (val.enabled != false) {

if (typeof(val.evaluationfunction) == "function") {

val.isvalid = val.evaluationfunction(val);

}

}

ValidatorUpdateDisplay (val);

}

 

This function first sets the member isvalid to True, and then verifies whether the element which represents a span element, which in this case is named RequiredFieldValidator1, is enabled or not. Then, the evaluationfunction member is checked to confirm if it is of type 'function'. If so, the function that is associated with the attribute of the scan evaluationfunction, is called. In the html file, the function incidentally has a very long name, i.e. RequiredFieldValidatorEvaluateIsValid. The code of this function contained in the js file, is displayed below.

 

 

 

function RequiredFieldValidatorEvaluateIsValid(val)

{

return (ValidatorTrim (ValidatorGetValue(val.controltovalidate)) != ValidatorTrim(val.initialvalue))

}

 

The member ControltoValidate has a textbox named TextBox1. The function ValidatorGetValue returns the text typed in to this textbox. There may be leading or trailing spaces, but they are not taken into consideration, as the function ValidatorTrim eliminates all of them. Every control has an initial value, which is stored in the member initialvalue. The value in the control should be at variance with the initial value.  Thus, if the 'return' keyword returns False, and if the control value has not changed, the isvalid member is assigned the value of False. Otherwise, it is assigned the value of True. The next function to be called is the function ValidatorUpdateDisplay, with the id of the 'span' as the parameter.

 

function ValidatorUpdateDisplay(val) {

if (typeof(val.display) == "string") {

if (val.display == "None") {

return;

}

if (val.display == "Dynamic") {

val.style.display = val.isvalid ? "none" : "inline";

return;

}

}

val.style.visibility = val.isvalid ? "hidden" : "visible";

}

 

This function merely checks if the 'type' of the display members is a 'string'. If its value is 'None', then the function quits out without achieving anything. However, If its value is 'Dynamic', then the display member style, is changed to 'none' or 'inline', depending again upon the value of the isvalid property. This member will be checked once again, to determine whether the error message is to be displayed in front of the control or not. In the function Page_ClientValidate, the above code is repeated for each control that is to be validated. The next function to be called is named ValidatorUpdateIsValid.

 

function ValidatorUpdateIsValid() {

var i;

for (i = 0; i < Page_Validators.length; i++) {

if (!Page_Validators[i].isvalid) {

Page_IsValid = false;

return;

}

}

Page_IsValid = true;

}

This simple function iterates through the entire array of controls, which are to be validated, and ascertains if the isvalid member is True for any of them, implying that the validation failed. If the 'if' statement is True, the variable Page_IsValid is assigned a value of False, and then, the function returns. Thus, even if a single control fails, the data cannot be posted back to the server. Only when the 'for' statement quits out gracefully, can it be inferred that all controls are valid. Thereafter, the variable Page_IsValid is set to True. The last function to be called is ValidationSummaryOnSubmit. This is quite a mammoth function, which deals with the Summary Display. Since there are no summary messages, we will not delve any deeper into this function.

 

Finally, the function ValidatorCommonOnSubmit gets called at the time of 'submit'. It does not achieve anything noteworthy.

 

function ValidatorCommonOnSubmit () {

event.returnValue = !Page_BlockSubmit;

Page_BlockSubmit = false;

}

 

The aim of this entire exercise is to demonstrate that learning a new language is not a very arduous task. It is advisable to build in certain error checks, which should be executed at the client, since this results in a faster response. These checks are also carried out at the server end, in any case. As an exercise, rebuild all the validation projects that we have worked with earlier, and have a look at the code.

 

We could have continued endlessly, explaining the C# code behind every application, but we realized that there has to be an end somewhere. So we have decided to conclude here, since we are sure that by now, you must be reasonably comfortable in working with Visual Studio.Net, and in building Visual C# projects.