ASPNET Workbook.pdf by yan198555

VIEWS: 98 PAGES: 161

									ASP.NET Workbook
Hands-On Exercises for the Beginner




Heng Ngee Mok




1st Edition (with minor corrections made)
Version 1.1 (Feb 2004)

The 1st edition of this book has been published by Prentice Hall
Publishing (Pearson Education) (Singapore) in December 2003



         You can download the latest edition of this book at
              http://www.mokhengngee.per.sg/book
ii



Acknowledgements
I would like to acknowledge my colleagues whose keen spirit of sharing has
helped me in my foray into ASP.NET. They are, in no particular order of merit,
Law Chee Yong and Ouyang Yin Ming, the real ASP.NET experts here at the
School of IT. Special thanks must be given to Daniel Wee, who has been a truly
nice boss. I must also mention Serena Goh, Sarah Chong and Adrian Png,
without whom, my lunch hours would have been plain and uneducational
experiences.



Errata
Readers can view the latest erratum list at www.mokhengngee.per.sg/book.
Additional exercises which could not make it in time for this edition shall also
be posted there.




www.mokhengngee.per.sg/book
                                                                                iii



Preface
In the spirit of communal sharing, I have decided to make the text of this
workbook available to all developers in Singapore and around the world.
Readers are free to download the PDF format of this text, and use for non-profit
educational purposes. Readers are obliged to acknowledge the source (i.e. this
book/author) where appropriate. Please do not modify the contents of this
document, or re-distribute it in any form. Instead, please direct your friends to
the ‘official’ download Web site. The latest corrected version of this book can
always be found at http://www.mokhengngee.per.sg/book. ‘Book bug’ reports
are also always appreciated at mok@ieee.org.

I wish you a pleasant adventure with ASP.NET :)

H.N. Mok
February 2004
Singapore




Preface to the Original Edition
This book has been prepared to support the curriculum of the IT1202 (Web
Application Development) module, which year 1 Diploma in IT students are
required to complete at Nanyang Polytechnic. This guide for practical exercises
is not meant to be a stand-alone manual, but to be complimented with
lecture/tutorial materials and reference books on ASP.NET.

This being a workbook for my students at the School of IT, I would like to
dedicate this book, and (hopefully) all the knowledge that they could gain from
it, to all my wonderful students. May they have a memorable experience at
NYP, and may the spirit of learning be forever with them!

Please do send any comments or (constructive) criticisms on the lab exercises
presented here to mok@ieee.org.

H.N. Mok
December 2003
Singapore



                                                                 ASP.NET Workbook
iv



Prerequisites
This book assumes that the following software requirements have been met by
your PC:

     Operating system: Windows XP Professional, Windows 2000 Professional
     (SP3 or later required), Windows 2000 Server (SP3 or later required) or
     Windows Server 2003.

            Windows Me and XP Home won’t do: You can install VS.NET on
        Windows XP Home edition, but you cannot create ASP.NET or Web
        service applications. And if you are still running on Windows 9x, it’s
        high time to upgrade!

     Visual Studio .NET 2003
        You can also follow the exercises using Visual Studio .NET 2002.
        However there might be minor differences in the user interface and steps
        to be taken.

           Backward compatibility: Note that VS.NET 2003 is not ‘backward
        compatible’ with VS.NET 2002; a project or solution created using
        VS.NET 2002 can be opened in VS.NET 2003, but thereafter cannot be
        opened using VS.NET 2002 again.

        The reason is because VS.NET 2003 uses the newer .NET Framework
        version 1.1 compared to VS.NET 2002, which uses .NET Framework 1.0.
        When a VS.NET 2002 project is opened in VS.NET 2003, the project
        will be automatically converted to consume classes from the newer .NET
        Framework. A VS.NET 2003 project or solution thus cannot be opened in
        VS.NET 2002. Be wary of this limitation if you have different versions of
        VS.NET installed at home or in your lab.


     Microsoft Access XP (2002) or 2003
       For the ADO.NET exercises, you will need to create an Access database.

     Windows Administrator rights
       o If VS.NET is not yet installed on your PC, you will need administrator
          rights to do so.



www.mokhengngee.per.sg/book
                                                                        v


o You will also need enough rights to execute the IIS Manager (see
  figure 0-1). You should be able to see the IIS Manager icon by
  selecting the ‘Administrative Tools’ icon in the Control Panel.




Figure 0-1: You should be able to execute IIS Manager in order to try out
the exercises.




                                                         ASP.NET Workbook
vi



Contents
1: Hosting Web Pages on IIS................................................................................1
   Ex 1.1: Writing a Simple Web Page & Hosting it on IIS.................................1
   Ex 1.2: Creating a Virtual Directory with IIS ..................................................5
   Ex 1.3: Hosting a Simple ASP.NET Web Page on IIS.....................................9
   Ex 1.4: IIS Access Right Settings (optional) ..................................................15
2: ASP.NET Web Forms ....................................................................................21
   Ex 2.1: Introducing the VS.NET IDE.............................................................21
   Ex 2.2: Writing a Simple Web Page and Understanding Event Handlers .....35
   Ex 2.3: Understanding Code-Behind Pages....................................................46
   Ex 2.4: Creating a More Complex Web Form with Other Server Controls...49
3: Validator Controls ..........................................................................................55
   Ex 3.1: Simple Validator Controls..................................................................55
   Ex 3.2: Other Validator Controls....................................................................62
4: State Management ..........................................................................................69
   Ex 4.1: State Management Using the Session and Application Objects ........70
   Ex 4.2: Using Cookies ....................................................................................81
   Ex 4.3: Using Global.asax.......................................................................87
   Ex 4.4: Extracting Parameters from Web.config Programmatically.........91
   Ex 4.5: Tracing your Web Application ..........................................................93
5: ADO.NET .......................................................................................................96
   Ex 5.1: Using the DataTable Class ............................................................96
   Ex 5.2: Reading from the Database and Using the DataReader Class ....100
   Ex 5.3: Performing Simple CRUD Operations ............................................112
6: Web Services ................................................................................................122
   Ex 6.1: Creating a Web Service Provider.....................................................122
   Ex 6.2: Creating a Web Service Consumer ..................................................129
   Ex 6.3: Consuming Web Services from Google (optional)..........................138
   Ex 6.4: Consuming Web Services from Amazon (optional) ........................139
7: Site Security..................................................................................................141
   Ex 7.1: Web Form Authentication using Web.config .............................141




www.mokhengngee.per.sg/book
1: Hosting Web Pages on IIS
In this chapter, you will be hosting simple static HTML and dynamic ASP.NET Web
pages on IIS without using Visual Studio.NET.

There are 4 exercises in this chapter:
   • Exercise 1.1: Writing a Simple Web Page & Hosting it on IIS
   • Exercise 1.2: Creating a Virtual Directory with IIS
   • Exercise 1.3: Hosting a Simple ASP.NET Web Page on IIS
   • Exercise 1.4: IIS Access Right Settings (optional)


Introducing IIS

Microsoft has 2 primary Web servers for hosting Web applications: Personal Web Server
(PWS) and Internet Information Server (IIS). PWS is a lightweight Web server for non-
industrial usage, and comes with the old Windows NT Workstation 4.0. IIS 6.0 is the
latest industrial-strength Web server.

Windows XP Professional comes with IIS 5.1, while XP Home doesn’t come with any
Web server. If you are running on Windows Server 2003, IIS 6.0 shall be installed.

IIS 6 boasts of an improved architecture, and is a great improvement over previous
versions, though most of the changes are not really visible to the user. For this course, we
shall be using either IIS 5.1 or 6.0.


Exercise 1.1

Writing a Simple Web Page & Hosting it on IIS
Welcome to the world of ASP.NET! In this very first exercise, you will write a simple
static HTML file, and host it on the IIS Web server. There’s nothing dynamic or
mysterious – but this exercise shall serve as a good hand-warmer.

Objective:
   • To host a simple Web page on IIS (and appreciate how easy it is to do so!)

Instructions:

1. Ensure that IIS has been properly installed and working.
2


    Open up Internet Explorer and type the following URL in the Address field:
      http://localhost
    You should be able to see IIS’s default Web page (figure 1-2):




    Figure 1-2: Default page of IIS 5.1 running on Windows XP Professional

    If you see a 404 error instead (figure 1-3), it is likely that IIS hasn’t been properly
    installed or the IIS process isn’t running, or that it is listening on another port instead
    of port 80. You may want to seek assistance.




    Figure 1-3: 404 error probably indicating that IIS isn’t installed or running, or
    listening at another port instead of port 80.

2. Create the HTML file.

    Create a new text file (using Notepad or any other text editor) called
    MyFirstPage.html. Type in the following lines and save it in
    c:\inetpub\wwwroot.

       <HTML>
       <BODY>

www.mokhengngee.per.sg/book
                                                                                          3


      Hello ASP.NET!
      </BODY>
      </HTML>

   That’s it! We have hosted a static Web page called MyFirstPage.html on your
   machine.


3. Try to access the hosted Web page from your local machine.

   Typing the following URL in the Address field of IE:
      http://localhost/MyFirstPage.html
   You should be able to see the following page (figure 1-4).




   Figure 1-4: Viola! Your first static Web page hosted on IIS.

      What is localhost? localhost is the ‘common name’ for the ‘loopback
   address’, or the reserved IP address 127.0.0.1. Basically it represents your own PC.
   You are trying to access a Web page called MyFirstPage.html hosted on your
   local PC. Instead of http://localhost/MyFirstPage.html, you could’ve
   typed http://127.0.0.1/MyFirstPage.html; they would have meant the
   same thing.

      URL case sensitivity: Instead of http://localhost/MyFirstPage.html,
   try http://localhost/myfirstpage.html. You will realise that IIS does
   not generally bother about casing as far as URLs are concerned, unlike many Java
   Web servers which are very particular about the correct casing in URLs.

      wwwroot: c:\inetpub\wwwroot is the folder where IIS finds Web pages to
   serve out to clients.




                                                                       ASP.NET Workbook
4


4. Test out your Web page from a remote client machine.

    In an actual scenario, a user will be trying to access your Web page from a remote
    client using a web browser. Get your PC’s IP address by typing ipconfig at the
    DOS command prompt (figure 1-5).




    Figure 1-5: You can use command line tool ipconfig.exe to check your IP
    address.

    Figure 1-5 shows that the current PC’s IP address is 172.20.46.45 (it will be a unique
    number for each PC on the network).

    Go to your friend’s PC and type the following URL in IE:
       http://<yourIPaddress>/MyFirstPage.html
    (Replace <yourIPaddress> with your own Web server’s IP address). You should
    be able to see the same Web page on your friend’s PC.




www.mokhengngee.per.sg/book
                                                                                          5




5. Create a new physical folder in wwwroot

   Create a folder called colors in c:\inetpub\wwwroot. In colors, create a
   few static HTML files which prints out some statement (suggestion: you can have
   yellow.html, blue.html etc)

6. Access these static pages using a browser

   Access these static Web pages from IE using the correct URL such as:
     http://localhost/colors/yellow.html or
     http://localhost/colors/blue.html

      You will realise that you need to specify the folder structure all the way to the
   HTML file’s name. If you want to view deep.html which is in
   c:\inetpub\wwwroot\colors\water\masterpiece\myworks\, then
   the URL shall be
   http://localhost/colors/water/materpiece/myworks/deep.htm
   l.




Exercise 1.2

Creating a Virtual Directory with IIS
The previous exercise shows how you can host your Web pages by placing them in a
folder in c:\inetpub\wwwroot. It is not always necessary to have to place all the
Web pages you want to host in this special folder, and in this exercise, you will learn
how to host Web pages placed in any other physical folder by using a virtual directory
mapping.

Objective:
   • To understand what is a virtual directory and how it works

Instructions:




                                                                        ASP.NET Workbook
6



1. Create a physical folder

    Create a folder called temp in c:\. In temp, create a few static HTML files which
    prints out some statement (suggestion: you can have page1.html, page2.html
    etc)


2. Create a virtual directory to map to the c:\temp folder.

    Start IIS Manager (Start button administrative tools Internet Information
    Server). Open up the (local computer) icon by double-clicking on it. Open up ‘Web
    sites’, and you should be able to see the ‘Default Web site’ icon.

    Right click on the ‘Default Web site’ icon and select ‘New’, followed by ‘Virtual
    Directory’ (figure 1-6).




    Figure 1-6: Create a virtual directory from IIS Manager

3. Run the Virtual Directory Creation Wizard

    The Virtual Directory Creation Wizard will run. Click on ‘Next’ as instructed. When
    you are asked to enter your virtual directory alias, key in a name and click ‘Next’. For
    this example, ‘somepage’ is used as the virtual directory alias (figure 1-7).

       Spaces in aliases: It is possible to select a name containing spaces for your alias,
    although this is seldom done. This will mean that the URL specified to access your
    Web page will also contain spaces.

www.mokhengngee.per.sg/book
                                                                                         7




   Figure 1-7: Select a name for your virtual directory.

4. Enter the physical path to the location of your Web pages.

   The wizard will ask for the physical path to the folder which contains your Web
   pages. Enter c:\temp or click on ‘Browse’ and select the temp folder. Click on
   ‘Next’ (figure 1-8).




   Figure 1-8: Enter the path to the folder which contains your Web pages.


5. Keep the default access permission settings for your virtual directory

   The wizard will ask you to set the access permissions for this virtual directory. For
   now, just accept the default settings (i.e. with only ‘Read’ and ‘Run scripts’ checked)
   and click ‘Next’. More about access permissions will be covered soon (figure 1-9).

                                                                         ASP.NET Workbook
8




    Figure 1-9: Accept the default access permissions.

    The wizard then shows a message to inform that you have successfully completed the
    Virtual Directory Creation Wizard. Click on ‘Finish’.

       What is a virtual directory? To understand what we have done so far, we need to
    understand what is a virtual directory. A virtual directory is basically a ‘mapping’
    between a physical folder and an alias. Instead of copying over the temp folder into
    c:\inetpub\wwwroot (we could have done that too), we can create a ‘mapping’
    of an alias (‘somepages’ in this example) to a physical folder (c:\temp). Hence
    there is no need for all your Web page files to be placed in
    c:\inetpub\wwwroot. All you need to do is to create a virtual directory
    mapping and remember the alias you have selected.

    In the next step, we shall see how to access the Web pages stored physically in
    c:\temp using a browser using this alias.

       Why virtual directories? Let’s consider the advantages of using virtual directories
    rather than to store your Web pages in c:\inetpub\wwwroot. By using virtual
    directories,
    • The user viewing your page cannot determine the actual physical structure of your
        folder and its sub-folders by looking at the URL. There are security implications
        here; the lesser an external party knows about the folders and its structure, the
        better.
    • For Web pages which are buried into a deep folder hierarchy, virtual directories
        provide a short and more direct URL to access these pages.



www.mokhengngee.per.sg/book
                                                                                          9


       The Virtual Directory Creation Wizard will not allow you to map a virtual
       directory to a remote folder (i.e. a path that points to somewhere besides your
       local hard disk such as a remote shared storage area on another machine), nor a
       removable disk (such as a zip drive or CDROM drive).


7. Access your Web pages using your virtual directory alias

   Open up IE and type in the following URL:
     http://localhost/somepages/page1.html
   Your Web page should appear.



Exercise 1.3

Hosting a Simple ASP.NET Web Page on IIS
So far, the Web pages you have hosted on IIS are (boring) static HTML pages. In this
exercise, you will write you very first dynamic ASP.NET page and host it.

Objective:
   • To write (and understand) your first ASP.NET page, and host it on IIS

Instructions

1. Create a script file using Notepad

   Create a new text file called luckyno.aspx using Notepad with the following
   contents, and save it in c:\inetpub\wwwroot. Note that the label’s ID is lb1 –
   not lbl – and it stands for Label Number 1 (for lack of a better name) in this short
   demo.

   <!-- luckyno.aspx -->
   <SCRIPT runat="server" language="VB">
   Sub Page_Load
     Dim r As Random
     r = new Random()
     lb1.Text = "Your lucky number today is " + _
       Convert.ToString(r.Next(100))
   End Sub
   </SCRIPT>

   <HTML>
   <BODY>

                                                                        ASP.NET Workbook
10


       <FORM runat="server">
       <asp:label id="lb1" runat="server" />
       </FORM>
     </BODY>
     </HTML>


        Applying virtual directories: Instead of placing luckyno.aspx in
     c:\inetpub\wwwroot, you may want to save it anywhere on your hard disk, and
     create a virtual directory to point to that location.

        aspx? All ASP.NET Web pages end with a .aspx extension. This will tell the IIS
     Web server engine that this is a file containing ASP.NET codes, and to process it
     accordingly. In contrast, ASP 3.0 (“classic ASP”) Web page files end with a .asp
     extension (without the x).


2. Test your Web page

     Check out the aspx Web page which you have just hosted by opening IE and typing
     the following URL:
         http://localhost/luckyno.aspx
     or if you are using a virtual directory,
         http://localhost/<virtual_directory_alias>/luckyno.aspx

     You should be able to see something like figure 1-10. (Of course the random number
     may be different.)




     Figure 1-10: The Web page shows your lucky number between 0 and 99 (inclusive)

     Try refreshing the page by pressing F5 a few times, or clicking the ‘Go’ button beside
     the Address field of IE. (What you are trying to do is to visit the same aspx Web page
     again and again.) You should see a new random number each time you hit the page.



www.mokhengngee.per.sg/book
                                                                                         11



     First time longer: If you are observant, you might have noticed that the first time
  you tried to access luckyno.aspx, it took a significantly longer time before the
  Web page appeared in your browser. Subsequent visits to the same aspx file (when
  you refreshed the page) were relatively fast. The reason for this is that the first time a
  visitor (client browser) hits a particular aspx page, IIS kicks in its engine to process
  the aspx file, convert into a class, create an instance of this class to form an object
  which then responds to your browser request. On the second and subsequent times the
  same aspx file is ‘hit’, this cached object is used to respond to your browser request
  instead. This explains why the first hit to an aspx page always takes more time.


3. Examine the code

  Now that we have successfully written and hosted our first ASP.NET page, let’s take
  some time to understand what the code actually does.

  We can break up luckyno.aspx into 2 parts, the <SCRIPT> part (lines 1-9) & the
  <HTML> part (lines 10-16).

  01 <!-- luckyno.aspx -->

  Line 1 is simply an HTML comment. HTML comments are enclosed within <!--
  and -->, and are ignored by the .NET engine processing the ASP.NET file. You can
  insert comments in your code where appropriate.

     HTML comments vs. ASP.NET comments: HTML comments are sent to the
  client browser and are visible at the client side (by selecting View Source on the IE
  menu). Be aware of this, because you won’t want irrelevant or even confidential
  comments (which give clues as to how your ASP.NET page works) to be viewable by
  the client! For these, you might want to use ASP.NET comments instead of HTML
  comments. ASP.NET comments are enclosed within <%-- and --%>. So, line 01
  could’ve been replaced by
      01 <%-- luckyno.aspx --%>
  The difference will be that this comment will not be sent back to the client browser,
  and is thus not visible to the client user.

  02 <SCRIPT runat="server" language="VB">
     ...
  09 </SCRIPT>

  The <SCRIPT> element is found from lines 2-9. The runat="server"
  attribute/value pair tells IIS that the contents of this <SCRIPT> element (i.e. lines 3-
  8) are to be processed at the server-side, and not sent back to the client browser
  whole-sale. It is important to understand the difference between server-side script
                                                                         ASP.NET Workbook
12


     (such as this one) and client-side script (such as JavaScript, or client-side VBScript)
     which is supposed to be understood by and processed at the client browser.

         1 possible value for the runat attribute: If you omit the runat="server"
     attribute/value pair in the <SCRIPT> element start tag, this element will be treated as
     a client-side script, and will be sent back to the client without further processing. The
     only possible value for the runat attribute is "server", you cannot specify
     runat="client".

     Another attribute of the <SCRIPT> element is language. In my example, I have
     specified the programming language used in the contents of <SCRIPT> to be Visual
     Basic.NET (VB). You can use any other supported .NET language in your
     <SCRIPT> element such as J# (language="JS") or C# (language="C#", or
     language="CS").



         VB.NET is the default scripting language: By default, if no language
     attribute/value pair is specified in the <SCRIPT> element, VB.NET will be used as
     the default language. Hence, in the example in this exercise, it is all right to omit
     language="VB" on line 2; it will still work. However, this default language setting
     can be changed via IIS Manager.

     As an example, you can replace lines 2-9 with the following lines:

          <SCRIPT runat="server" language="C#">
            public void Page_Load(){
              Random r = new Random();
              lb1.Text = "Your lucky number today is " +
                Convert.ToString(r.Next(100));
            }
          </SCRIPT>

     In this case, the language used in the <SCRIPT> element is C# instead of VB.NET.
     Both codes accomplish the same task.

     Let’s look at the code contents of this server-side <SCRIPT> element:

     02   <SCRIPT runat="server" language="VB">
     03   Sub Page_Load
     04     Dim r As Random
     05     r = new Random()
     06     lb1.Text = "Your lucky number today is " + _
     07       Convert.ToString(r.Next(100))
     08   End Sub
     09   </SCRIPT>
www.mokhengngee.per.sg/book
                                                                                          13



The <SCRIPT> element encloses the Page_Load method (or subroutine, as
traditionally indicated by the Sub keyword in VB).

Page_Load is a special predefined method that will automatically be executed by
the IIS engine every time this Web page is loaded up (i.e. when a client browser hits
it). This is the place to place any initialization code.

Line 4 declares a new variable called r of type Random, and line 5 actually creates
an instance of that class.

The Random class is one of the frequently used classes in the .NET core library. This
method contains the Next method which takes in an integer, and returns a pseudo-
random integer between 0 and that input parameter (including 0, but excluding the
input parameter). So the expression r.Next(100)on line 7 returns a pseudo-
random integer between 0 and 99 inclusive.

The Convert.ToString() method takes in an integer as input parameter, and
returns the string form of that integer (i.e. if the integer 91 is passed in, the whole
expression will return "91" as a string). Hence the whole expression on line 7
(Convert.ToString(r.Next(100))) returns a pseudo-random number
(between 0 and 99 inclusive) as a string.

This string value is then concatenated with "Your lucky number today is
" to get something like "Your lucky number today is 91", and assigned
to lb1.Text on line 6.

    Concatenation operator in VB.NET: In VB.NET, we can use either + or & as the
string concatenation operator. & is peculiar to the VB language; other common
programming languages such as Java, C# or C++ uses the + for string concatenation.

lb1 is the variable that represents a server-side ASP.NET Label control which is
declared on line 13 which we shall be discussing soon.

Let’s consider the <HTML> portion:

10   <HTML>
11   <BODY>
12     <FORM runat="server">
13       <asp:label id="lb1" runat="server" />
14     </FORM>
15   </BODY>
16   </HTML>


                                                                        ASP.NET Workbook
14


     Lines 10 and 11, 15 and 16 are the HTML and BODY tags, and will be ignored by
     the IIS engine, and sent over to the client browser unchanged.

     Lines 12-14 represent a server-side HTML form. Note the runat="server"
     attribute/value pair of the <FORM> element (that’s why it’s a ‘server-side’ form).
     This tells the IIS engine to process lines 12-14, and replace them with some relevant
     client-side HTML codes before sending them over to the client browser.

     Line 13 declares an ASP.NET server-side web control called a Label. Each ASP.NET
     control can have an ID, much like a variable name, so that it can be identified. In my
     example, this Label object has an ID lb1.

     When luckyno.aspx loads, the IIS engine will execute the Page_Load method
     in the <SCRIPT> section first, and set our Label control lb1’s Text attribute to a
     string that may read "Your lucky number today is 91". Lines 12-14 will
     be processed by the IIS engine at the server and replaced by a line "Your lucky
     number today is 91", which is then sent back to the client browser within the
     <HTML> and <BODY> elements.


4. Understand what gets sent back to the client

     Open up IE and view luckyno.aspx again. Select View Source from IE’s menu
     to take a look at the HTML codes that were actually returned from IIS. You should
     see something like this:

     <!-- luckyno.aspx -->

     <HTML>
     <BODY>
       <form name="_ctl0" method="post"
        action="luckyno.aspx" id="_ctl0">

     <input type="hidden" name="__VIEWSTATE"
     value="dDw4MDE0NzI0MDA7dDw7bDxpPDI+Oz47bDx0PDtsPGk8MT47PjtsPHQ
     8cDxwPGw8VGV4dDs+O2w8WW91ciBsdWNreSBudW1iZXIgdG9kYXkgaXMgNDg7P
     j47Pjs7Pjs+Pjs+Pjs+sFphy5fXRFGvzAcMZe8pIUwBq1w=" />

       <span id="lb1">Your lucky number today is 48</span>
       </form>
     </BODY>
     </HTML>

     Ignore the <INPUT> element first (this will be discussed when we deal with states), and you
     can see that what actually got sent back from the server was simply a plain HTML file which
     looks like this:

www.mokhengngee.per.sg/book
                                                                                            15



   <!-- luckyno.aspx -->

   <HTML>
   <BODY>
     <form name="_ctl0" method="post"
      action="luckyno.aspx" id="_ctl0">
     <span id="lb1">Your lucky number today is 48</span>
     </form>
   </BODY>
   </HTML>

   You should realise that all server-side codes (the <SCRIPT>, <FORM> and
   <asp:label>) in the original aspx file had been processed by the IIS server
   engine, and replaced with relevant HTML codes that the client browser can
   understand.



Exercise 1.4 (optional)

IIS Access Right Settings
In this exercise, you will be introduced to how you can control the accessibility of your
Web pages hosted on IIS. It is important to understand to understand this exercise
because given users more access than is required may lead to security problems.

Objective:
• Understanding basic IIS access rights settings to control the accessibility of your Web
   pages.

Instructions:

1. Prepare for the exercise

   You need to have understood how to create a virtual directory (see exercise 1.2)
   before proceeding.

   Run the Virtual Directory Creation Wizard to create a virtual directory mapping to a
   folder on your hard drive (such as c:\temp). For this example, somepages has
   been selected as the virtual directory alias.

   In your physical drive which is mapped to the alias (such as c:\temp), create a
   static HTML file which displays a simple message (such as myfirstpage.html)
   and an ASP.NET Web page (such as luckyno.aspx) which contains some
   ASP.NET scripts.
                                                                         ASP.NET Workbook
16




2. View properties of the virtual directory

     Recall that in step 5 of exercise 1.2 (Creating a Virtual Directory with IIS), the
     Virtual Directory Creation Wizard provided you with options to set the accessibility
     of your Web pages (see figure 1-9), but all you did was to accept the default options
     (i.e. only ‘read’ and ‘run scripts’ enabled). You will learn the implications of
     selecting each option in this exercise.

     You can still modify the accessibility options of a particular directory after it has been
     created. Fire up IIS Manager (Start Administrative Tools Internet Information
     Server). On the left panel, double click on the ‘local computer’ icon, ‘Web sites’ icon
     and the ‘default Web site’ icon. You should be able to see an icon representing your
     virtual directory. (See figure 1-11: in this example, the virtual directory alias had
     been set as ‘somepages’.) Right click on ‘somepages’ or your alias icon and
     select ‘Properties’.




     Figure 1-11: Viewing the properties of a virtual directory

     You should see the Properties pop-up window (figure 1-12). Here is where you can
     adjust the accessibility settings of your virtual directory. The access permissions you
     set here controls the type of access for the given directory and permissions allowed
     on files in that directory.




www.mokhengngee.per.sg/book
                                                                                            17




   Figure 1-12: Properties of a directory where you can change access permissions

3. Understand the various access options

   Figure 1-13 summarizes the possible script access options: ‘Script source access’,
   ‘Read’, ‘Write’ and ‘Directory browsing’.

                                              Script source access: If this is
                                              checked, client users can access the
                                              source code of an .aspx file. This
                                              option is available only if ‘read’ or
                                              ‘write’ is checked.
                                       Read: If this is checked, client users can
                                       read/download files in the directory. If
                                       unchecked, HTML files cannot be read, but
                                       .aspx files can still be processed and read.
                                               Write: If this is checked, client
                                               users can create/modify files in
                                               the directory.
                                                 Directory browsing: If this is
                                                 checked, client users can view
                                                 the contents of the directory.



   Figure 1-13: The various script access options.




                                                                              ASP.NET Workbook
18




                                                 None: Client users can only access
                                                 static files only (html, jpegs etc), but
                                                 not ASP.NET pages.


                                                 Scripts only: Client users can access
                                                 script-based pages (i.e. ASP.NET
                                                 pages)


                                                 Scripts & Executables: Client users
                                                 can execute any type of file in the
                                                 directory including .exes




     Figure 1-14: Execute Permissions

     Figure 1-14 summarizes the possible options for the ‘Execute Permissions’ field.

4. Experiment with Access Permissions

     Set access permissions to ‘Read’ and ‘Directory browsing’, and Execute Permissions
     to ‘None’, and click on ‘OK’. By studying the descriptions of the various access
     permissions, do you think a client user can view the HTML file, and/or the ASP.NET
     file?

     To check if you are correct, open up IE and try to view the HTML file:
        http://localhost/somepages/myfirstpage.html
     You should be able to see the HTML file.

     Next, try to view the ASP.NET file:
        http://localhost/somepages/luckyno.aspx
     A 403 error appears with the problem description. (See figure 1-15 :the ‘Background’
     section describes exactly how we have configured in the properties pop-up box.)




www.mokhengngee.per.sg/book
                                                                                        19




Figure 1-15: HTTP 403.1 error due to denied access permissions.

Now, try specifying only the alias name:
   http://localhost/somepages/
You should be able to see the contents of the physical folder. This is because
‘Directory browsing’ has been enabled. (See figure 1-16)

   Switch off directory browsing unless necessary: Setting ‘Directory browsing’
rights might be useful if you intend to set up a site for users to download files (similar
to an FTP site). Otherwise it is generally bad practice to allow users to view the
contents of your folder (with security implications).




                                                                        ASP.NET Workbook
20




     Figure 1-16: viewing the directory contents of your physical folder


         As Web server administrator, you should always give as little access permissions
     as possible to your users. Unless there is a special requirement, you should use the
     default configurations (i.e. only enable ‘Read’ and set Execute Permissions to ‘Script
     only’).




www.mokhengngee.per.sg/book
2: ASP.NET Web Forms
In this chapter, you will get familiar with Visual Studio.NET’s development
environment, and create ASP.NET Web applications using VS.NET.

There are 4 exercises in this chapter:
   • Exercise 2.1: Getting familiar with the VS.NET IDE
   • Exercise 2.2: Writing a Simple Web page and Understanding Event Handlers
   • Exercise 2.3: Understanding Code-Behind Pages
   • Exercise 2.4: Creating a More Complex Web Form with other Server Controls


Exercise 2.1

Introducing the VS.NET IDE
Objective:
   • To be familiar with VS.NET’s Integrated Development Environment.

Instructions:

1. Start up VS.NET and create a new project

   Click on Start All Programs Microsoft Visual Studio.NET 2003          VS.NET. The
   IDE will appear after the splash screen disappears.

      What components have been installed? The VS.NET splash screen will show the
   installed languages and modules with VS.NET on your machine. In this example,
   figure 2-1 shows 3 .NET languages (VB.NET, C# and J#, but not C++.NET) have
   been installed on this particular machine. If you intend to use a particular.NET
   language which is not available on your PC, you will need to install it first
   (administrator rights to your local PC required).
22


     Figure 2-1: Splash screen showing the installed products.

     The ‘start page’ which contains shortcut ‘links’ to the last few opened projects (if
     any) appears. Notice the Toolbox pane on the left, Solution Explorer pane on the right
     and the Task List pane at the bottom. For now, they are quite empty because you are
     not yet working on any project.




     Figure 2-2: VS.NET IDE

        Hiding panes: You can hide or show the Toolbox or Solution Explorer pane (and
     any other panes) by selecting View Toolbox, or View Solution Explorer on
     VS.NET’s menu. Conversely, if you do not see the Toolbox and Solution Explorer
     upon startup, that probably implies that the computer user before you might have
     hidden them.

     Open a new project by selecting File New Project… from the menu. The New
     Project dialog appears (figure 2-3). For this exercise, we are going to create a new
     Web Application project.




www.mokhengngee.per.sg/book
                                                                                       23




Figure 2-3: Creating a new VS.NET project

Select ‘Visual Basic Projects’ for ‘Project Types’ and ‘ASP.NET Web Application’
for ‘Templates’. In the ‘Location’ field, type in:
    http://localhost/TestWebApp

When you click on ‘OK’, VS.NET will communicate with IIS to create a folder in
c:\inetpub\wwwroot (see figure 2-4). For this example, since TestWebApp
has been entered in the ‘Location’ field (figure 2-3), VS.NET will create the folder
TestWebApp in c:\inetpub\wwwroot and place within it several other files
created automatically as part of the project.




Figure 2-4: A new folder is created in wwwroot when you create a new Web
application project.



                                                                     ASP.NET Workbook
24


     Using Windows Explorer, take a look at that folder to determine what files have been
     created for you for the new project. You will also be able to see these files in the
     Solution Explorer pane in the VS.NET IDE.

        If you see the error ‘Web Access Failed’ in figure 2-5 when you try to create a
     new project, you may not have the proper permissions to create this project. Check
     with your system administrator that your account is a member of the ‘VS Developer’
     group on your local machine (This group is created when VS.NET was installed.)




     Figure 2-5: Web access failure may be due to insufficient privileges.



         Anatomy of a VS.NET Solution: In VS.NET, one or more ‘projects’ make up a
     ‘solution’. A solution is a group of projects that are loaded into VS.NET at the same
     time for the purpose of development, debugging and building. If you take a look at
     the c:\inetpub\wwwroot\<project_name> folder, you will see your project
     files (something.vbproj for VB.NET projects, something.vjsproj for J#
     projects, and something.csproj for C# projects). ASP.NET Web application
     project files are usually placed there. On the other hand, if you are writing a .NET
     Windows application, you can place your project files in any location.

     The solution file (something.sln) may or may not be placed together with your
     project files; to find out where your .sln file is stored, select the solution file in
     Solution Explorer (it’s the top-most one in Solution Explorer) and look at the
     Properties pane. The value of its ‘Path’ property indicates the location to the .sln
     file. The .sln file is simply a text file (that you can open using Notepad) which
     contains information about the various projects in this solution.


     Every time when you select New Project from the VS.NET menu, you will have an
     option to include this new project as part of an existing solution, or to create a new
     solution to contain only this project.

        Transferring your Web application to another machine: A simple way to copy
     out a VS.NET solution from one development machine (from home) to another (say,

www.mokhengngee.per.sg/book
                                                                                       25


   in school) is to copy the .sln file and the whole project folder from
   c:\inetpub\wwwroot.
   • Place the project folder in the wwwroot folder of the target machine
   • Open IIS Manager and expand the directory tree on the left until the ‘Default Web
       site’ icon is shown.
   • You should be able to see your new folder represented as a normal folder icon
       (instead of a Web application icon).
   • Right-click on this icon and select ‘Properties’.
   • In the ‘directory’ tab of the ‘Properties’ window, click on the Create button to
       make this a Web application. This is an important step – otherwise, you may be
       able to open your .sln or project files in VS.NET, but won’t be able to view the
       Web pages in a browser.
   • You can then double-click on the .sln or project file to open it up in VS.NET.


2. Explore the Toolbar

   After these files are created in c:\inetpub\wwwroot, your IDE will display
   WebForm1.aspx right in the middle, and you are ready to start working on your
   WebForm1.aspx file (figure 2-6). You should also have noticed that the Toolbox
   and Solution Explorer panes are filled with useful ‘goodies’ relevant to your Web
   application.




   Figure 2-6: Checking out the various parts of the IDE

   The Toolbox pane is where you will drag server-side controls to your aspx file from.
   Figure 2-7 shows the Toolbox. Notice that there is a thumb pin icon (circled in figure
   2-7). Click on it to ‘auto-hide’ your Toolbox pane. You can also do this for all other


                                                                        ASP.NET Workbook
26


     panes (Solution Explorer etc). It is advisable to auto-hide some panes so that you
     have more space for your main document.

     You can also dock the Toolbar (or any other panes) at other locations by dragging the
     title bar of the pane (circled in figure 2-7) to any location in the IDE.




     Figure 2-7: The Toolbox pane: your chest of ‘goodies’ controls.

     The Toolbox contains the following sub-sections: Data, Web Forms, Components,
     HTML, Clipboard Ring, and General. You will be dragging quite a few controls from
     the ‘Web Forms’, ‘HTML’ and ‘Data’ sections of the Toolbox for your subsequent
     exercises.

     The Toolbox’s ‘Web Forms’ section contains useful controls such as Textboxes,
     Labels, Buttons etc. Click on the up/down arrows (circled in figure 2-7) if necessary
     to view the complete list of controls available in that section.

     Click on the ‘HTML’ section to reveal the available controls there. The Toolbox’s
     ‘HTML’ section contains somewhat similar controls such as Labels, Buttons and
     TextFields too. You will learn the difference between controls ‘pulled out’ from the
     ‘Web Forms’ and the ‘HTML’ sections soon.


3. Explore the Solution Explorer pane

     Take a look at the Solution Explorer pane on the right. The Solution Explorer is
     where you can view all the files and references used in your project. You will realise
     that several other files such as Global.asax and Web.config have been

www.mokhengngee.per.sg/book
                                                                                       27


generated and included in the project for you. You can double click on the file names
to open them. (More will be covered about Global.asax and Web.config
later.)

Not all files in your project are visible though. Click on the ‘Show All Files’ icon
(figure 2-8) to view all the files associated with your project. Then expand on
WebForm1.aspx by clicking on the plus sign beside WebFrom1.aspx. You
should be able to see that there are 2 other files associated with WebFrom1.aspx
called WebForm1.aspx.vb and WebForm1.aspx.resx.

WebForm1.aspx is the default aspx file which is generated when you selected to
create a Web application project. You can rename it by right clicking on
WebForm1.aspx in Solution Explorer, and selecting the ‘rename’ option. If you do
so, you will notice that the corresponding WebForm1.aspx.vb and
WebForm1.aspx.resx files will also be renamed accordingly.

For this exercise, the original name (i.e. WebForm1.aspx) will be retained, but you
may wish to give it a more appropriate name.

   resx file? We don’t have to bother too much about the .resx file. It’s just a
resource file associated with our Web page.

   Code-behind files: WebForm1.aspx.vb is a VB.NET file. If you had selected
to create a C# Web application project instead of a VB.NET Web application project,
the file will be WebForm1.aspx.cs instead of WebForm1.aspx.vb. This .vb
or .cs file is also known as the ‘code-behind’ file of WebForm1.aspx. The
purpose of a ‘code-behind’ file will be explained later, but for now, it is enough to
know that WebForm1.aspx.vb will contain VB.NET source codes which
‘support’ the WebForm1.aspx Web page. Every Web form you create in VS.NET
will come with its own ‘code-behind’ file.




                                                                     ASP.NET Workbook
28


     Figure 2-8: Show all files in Solution Explorer


4. Explore the main document area

     You can open any file by clicking on the file name in Solution Explorer (or selecting
     File Open File… from the menu). Figure 2-9 shows the editing area with 4 files
     currently open. Also notice from figure 2-9 that WebForm1.aspx has an * beside
     its name indicating that changes have made to this file, and it hasn’t been saved yet.
     You can use Ctrl-S or select File Save to save the current file.

     If you hover your mouse pointer over the file name, the actual physical location
     where the file is stored pops up too (figure 2-9).




     Figure 2-9: Edit your documents here


     Try dragging a Button control from the Toolbox’s ‘Web Forms’ section to the editing
     area of WebForm1.aspx. Also drag a Button control from the Toolbox’s ‘HTML’
     section to the same area (below the first button).

     You should see something like figure 2-9. What you have just done is create a Web
     form containing 2 Button controls.

        Runat Server Controls: Notice that one of the 2 Button controls has a tiny green
     arrow (the button which was dragged from the Toolbox’s ‘Web Forms’ section) when
     viewed in the Design View. The other button (the one which was dragged from the
     Toolbox’s ‘HTML’ section) doesn’t (figure 2-9). This green arrow ‘attached’ to a
     control indicates that it is a server-side control, or, in other words, this control has a
     runat="server" attribute/value pair, and will be processed at the IIS server
     rather than just returned to the client browser.

     Right click on the button which runs at the client (the one without the green arrow)
     and select ‘Run as Server Control’. You will notice that the green arrow now appears.
www.mokhengngee.per.sg/book
                                                                                    29


If you check out the HTML codes, the runat="server" attribute/value pair
would have been inserted into the <INPUT> (HTML button) element. Set it back to
run as a client control by right clicking on that button and selecting ‘Run as Server
Control’ again.


Each aspx Web form can be represented in 2 ways: the Design View and the HTML
View.

You are currently viewing the Design View of WebForm1.aspx. The Design View
represents a visual way for manipulating the Web form. While you are dragging and
dropping controls from the Toolbox pane to your WebForm1.aspx in Design
View, VS.NET is busily creating HTML codes in the background for you.

Click on the ‘HTML’ tab (circled in figure 2-9) to switch over to the HTML View of
WebForm1.aspx. You will see what VS.NET has generated for you when you
dragged the Button controls over:
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb"
Inherits="TestWebApp.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>
  <HEAD>
    <title>WebForm1</title>
    <meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.1">
    <meta name="CODE_LANGUAGE" content="Visual Basic.NET 7.1">
    <meta name="vs_defaultClientScript" content="JavaScript">
    <meta name="vs_targetSchema" content="...">
  </HEAD>

  <body MS_POSITIONING="GridLayout" bgColor="#ffffff">
    <form id="Form1" method="post" runat="server">

      <asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 128px;
         POSITION: absolute; TOP: 88px" runat="server"
         Text="Button"></asp:Button>

      <INPUT style="Z-INDEX: 102; LEFT: 128px; POSITION: absolute;
         TOP: 136px" type="button" value="Button"
         id="Button2" name="Button2">
    </form>
  </body>
</HTML>


The code statements in bold above were inserted by VS.NET when you dragged the
button controls over in Design View.




                                                                     ASP.NET Workbook
30


5. Understand button codes

     Let’s examine the 2 code fragments in greater detail.

     The following fragment represents a ‘normal’ HTML INPUT button which was the
     Button control that was dragged from the HTML section of your Toolbox pane:
       <INPUT style="Z-INDEX: 102; LEFT: 128px; POSITION: absolute;
          TOP: 136px" type="button" value="Button"
          id="Button2" name="Button2">



     The following fragment represents an ASP.NET server-side Button control which
     was the Button control that was dragged from the Web Forms section of your
     Toolbox pane:
       <asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 128px;
          POSITION: absolute; TOP: 88px" runat="server"
          Text="Button"></asp:Button>


     Aren’t they different! (Though you can’t tell the difference when looking at their
     graphical representation in Design View). One notable difference is that the Button
     control dragged from the Toolbox’s HTML section is an <INPUT> element, while
     the other is an <asp:Button> element.

     Another difference is that your <asp:Button> element has the
     runat="server" attribute/value pair, which means that this <asp:Button>
     control is a server-side control, and will be processed at the server.


6. Explore the Properties pane

     Besides the Solution Explorer and the Toolbox pane, there is another useful pane
     which you will use very frequently: the Properties pane. Each object in your Web
     form has certain properties which you can set using the Properties pane.

        F4 (but not the boy band): A useful shortcut to make the Properties pane appear is
     the F4 function key. Close the Properties pane. Select any control on your Web form,
     and hit F4.

     If you click on the drop-down field right on top of your Properties pane, you will see
     the list of available objects in your aspx page (figure 2-10). For now, you should be
     able to see:
         • 2 button objects (Button1, which is a <asp:Button> control, and
             Button2, which is an HTML <INPUT> control),
         • WebForm1 (which represents the <FORM>…</FORM> element of your page)
             and
         • DOCUMENT (which represents the whole Web page itself).

www.mokhengngee.per.sg/book
                                                                                       31




Figure 2-10: The list of available objects in your Web page so far


   Can’t see properties: If you only see DOCUMENT in the Properties pane’s drop-
down list, it may be because your aspx file is in HTML View. Click on the ‘Design’
tab to switch to Design View, and you should be able to see the full list of objects on
your aspx page.

Each object will have property settings specific to its type. So, you will see different
properties for each object. Let’s check out the <asp:Button> button: select
Button1 (not Button2, which is your HTML <INPUT> button) from the drop-
down list to view its properties (figure 2-11 left).




Figure 2-11: Set the properties of your ASP server-side Button control

Click on the BackColor property of your Button1 object and select a new color
(figure 2-11 middle). One property value which you will want to change is the Text
property.




                                                                       ASP.NET Workbook
32


     Change Button1’s Text value to ‘Click me’ or some text (figure 2-11 right).
     The changes (in BackColor and Text) are immediately reflected in the Design
     View of the Web page.

     You might also want to change the values of other properties. A brief description of
     the property you are trying to change will appear at the bottom of the Properties pane
     (see circled area in figure 2-11 middle).

        Property changes: What actually happens when you change an object’s property
     value in the Properties panel? These changes are reflected in the HTML
     representation of your Web page. To see the ‘effects’ of the changes that have just
     been made, switch over to HTML View.

     Notice that the <asp:Button> element has been altered with the new Text and
     BackColor values:

            <asp:Button id="Button1" style="Z-INDEX: 101;
             LEFT: 128px; POSITION: absolute; TOP: 88px"
             runat="server" Text="Click me" BackColor="Yellow">
            </asp:Button>

     Instead of using the Properties pane, you can also edit the HTML codes in HTML
     View directly (the changes will be reflected in the Properties pane), but it will be
     much easier to use the Properties pane.


7. View the end product in a client browser

     So far, we have created a Web page called WebForm1.aspx. Let’s view this page
     using a client browser. You can do that easily from within VS.NET: right-click on
     WebForm1.aspx in Solution Explorer, and select ‘View in Browser’. After a while
     (remember that it takes a little longer the first time you view a Web page), you will
     see the 2 buttons as they will appear in IE.

     Alternatively, you can open up IE and type in the correct URL (this URL is the same
     URL as that shown circled in figure 2-12).

       Remote access: If you are trying to view WebForm1.aspx from another
     machine, remember to replace localhost with your machine’s IP address in the
     URL.




www.mokhengngee.per.sg/book
                                                                                         33




   Figure 2-12: Browsing a Web page from within VS.NET itself.

   If you are using IE to view WebForm1.aspx, you can view the HTML source
   codes being displayed by selecting View Source from IE’s menu. You can also
   right-click on any blank space on the page and select View Source. If you are viewing
   the page within VS.NET, you can right-click on any blank space around the 2 buttons
   and select ‘View Source’ (figure 2-12).

8. Understand ‘server-side’ controls

   It is important to understand what is meant by ‘server-side’ controls – as opposed to
   ‘client-side’ controls. What does it mean when someone says that ‘server-side’
   controls are processed at the IIS server first before they are sent back to the client?

   Compare the source codes of WebForm1.aspx in HTML View and the final
   HTML codes that are sent back to the client browser (follow the instructions in the
   previous step to view the HTML codes being displayed at the client). The following
   code shows the HTML codes which have been sent over to the client browser:
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
   <HTML>
     <HEAD>
       <title>WebForm1</title>
       <meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.1">
       <meta name="CODE_LANGUAGE" content="Visual Basic.NET 7.1">
       <meta name="vs_defaultClientScript" content="JavaScript">
       <meta name="vs_targetSchema" content="...">
     </HEAD>

     <body MS_POSITIONING="GridLayout" bgColor="#ffffff">
       <form name="Form1" method="post" action="WebForm1.aspx" id="Form1">

       <input type="hidden" name="__VIEWSTATE"
        value="dDwtNTMwNzcxMzI0Ozs+aiTbi12xQ6EFGoEcr5DNWOhDMKo=" />

       <input type="submit" name="Button1" value="Click me"
        id="Button1" style="background-color:Yellow;Z-INDEX: 101;
        LEFT: 128px; POSITION: absolute; TOP: 88px" />

                                                                          ASP.NET Workbook
34


                           <INPUT style="Z-INDEX: 102; LEFT: 128px; POSITION: absolute;
                            TOP: 136px" type="button" value="Button" id="Button2"
                            name="Button2">

         </form>
       </body>
     </HTML>


     Notice that there are significant differences between the HTML codes the client
     receives and the original codes in WebForm1.aspx.

     The following shows the differences between the original and the final in the
     <FORM> element. (For now, ignore the first <INPUT type="hidden"> element
     which contains the strange series of random characters; the usage of this additional
     <INPUT> element will be covered subsequently.)

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




                             <asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 128px;
                              POSITION: absolute; TOP: 88px" runat="server"
                              Text="Click me" BackColor="Yellow"></asp:Button>

                             <INPUT style="Z-INDEX: 102; LEFT: 128px; POSITION: absolute;
                               TOP: 136px" type="button" value="Button" id="Button2"
                               name="Button2">

                           </form>



                           <form name="Form1" method="post" action="WebForm1.aspx"
                           id="Form1">
     Sent back to client




                             <input type="hidden" name="__VIEWSTATE"
                              value="dDwtNTMwNzcxMzI0Ozs+aiTbi12xQ6EFGoEcr5DNWOhDMKo=" />

                             <input type="submit" name="Button1" value="Click me"
                              id="Button1" style="background-color:Yellow;Z-INDEX: 101;
                              LEFT: 128px; POSITION: absolute; TOP: 88px" />

                             <INPUT style="Z-INDEX: 102; LEFT: 128px; POSITION: absolute;
                              TOP: 136px" type="button" value="Button" id="Button2"
                              name="Button2">

                           </form>




     Notice that the <asp:Button> element (Button1) which is a server-side control
     (it has the runat="server" attribute/value pair) has been processed by IIS and
     replaced with a normal HTML <INPUT type="submit"> (button) element
     before being sent over to the client.

     On the other hand, the <INPUT> element (Button2) which is a client-side control
     (pulled out from Toolbox’s HTML section) has remained intact. The element is

www.mokhengngee.per.sg/book
                                                                                         35


   meant to be sent over to the client browser unchanged, and will be processed by the
   client. IIS will not modify it since it is meant for the client.

     Runat-Server Form: Notice also that the <FORM> element has a
   runat="server" attribute/value pair. Some changes have also been made to the
   <FORM>’s attributes before being sent over to the client.

   In the next exercise, you will create a proper (but simple) Web application.


Exercise 2.2

Writing a Simple Web Page and Understanding Event
Handlers
The previous exercise has brought you on a whirlwind tour of the VS.NET IDE. In this
exercise, you will learn how to use VS.NET to write an ASP.NET Web form.

Objective:
   • Be able to write a simple Web application in VS.NET with a button and event
      handling code.

Instructions:

1. Create a new VS.NET project

   Start up VS.NET, and select File New Project from the menu. Select ‘Visual
   Basic Projects’ for ‘Project Types’ and ‘ASP.NET Web Application’ for ‘Templates’.
   In the ‘Location’ field, type in http://localhost/SimpleWebApp (figure 2-
   13). Click ‘OK’.




                                                                        ASP.NET Workbook
36




     Figure 2-13: Create a new ASP.NET Web application project in VB.NET


2. Insert controls to your Web form

     Rename WebForm1.aspx to Counter.aspx by right-clicking on
     WebForm1.aspx in Solution Explorer, and selecting ‘rename’.

     Drag and drop a Label server control from the Toolbox’s ‘Web Forms’ section (not
     ‘HTML’ section) to your Web form. Drag and drop 2 Button server controls from the
     same ‘Web Forms’ section. Notice the tiny green arrow on the upper left corner of the
     3 controls indicating that all of them are ‘server-side’ controls (figure 2-14).




     Figure 2-14: A Label and 2 Button server controls

     Select the Label by clicking once on it; the Properties pane will show the properties
     of the Label object.

     Change the (ID) property of the label from Label1 (that’s the default ID value) to
     lb_count. The ID is an important property of any control which is similar to a
     variable name. We will refer to this label object via its ID.

     Set the Text property of the Label control to 0 (figure 2-15).



www.mokhengngee.per.sg/book
                                                                                       37




   Figure 2-15: Changing the Label object’s (ID) and Text properties


3. Set the server controls’ properties

   Select the Button control on the left, and change its (ID) to bn_increase.
   Change its Text property to +. Select the Button control on the right, and change its
   (ID) to bn_decrease and its Text property to -.

   lb_count will be set to display a number later. When the client clicks on the +
   button, we want to increase the number displayed by lb_count. When the client
   clicks on the – button, we want to decrease the number displayed.




   Figure 2-16: Changing the Buttons’ (ID) and Text properties.

   At this point, you may want to switch over to Counter.aspx’s HTML View to see
   what HTML codes VS.NET has written for you.


                                                                       ASP.NET Workbook
38



4. Write the event handler for the Button controls

     Switch back to Design View and double click on the + button. When you do that,
     VS.NET will open up Counter.aspx.vb. This is the ‘code-behind’ file
     accompanying Counter.aspx. Here’s where you will enter VB.NET code for the
     + button’s event handler.

        What is an event handler? An event is something which happens. An event
     handler is a method which executes when that event happens. In this exercise, the
     event that you are trying to ‘trap’ is the button click. That is, when the user clicks on
     the + button, we want certain VB.NET codes to run in response to this button click.
     What you are going to do is to write the event handling codes in the
     bn_increase_Click method.

     Enter the 4 lines of code into the bn_increase_Click method as indicated
     below:

     Private Sub bn_increase_Click _
     (ByVal sender As System.Object, ByVal e As System.EventArgs)_
     Handles bn_increase.Click

       Dim c As Integer
       c = Convert.ToInt32(lb_count.Text)
       c = c + 1
       lb_count.Text = Convert.ToString(c)

     End Sub


        Is it compulsory for the event handler of bn_increase to be called
     bn_increase_Click? bn_increase_Click is just the default name given by
     VS.NET to correspond to the clicking of bn_increase. You can change the
     method’s name to any other valid name. It is the Handles
     bn_increase.Click (which is part of the method declaration) which tells
     VS.NET that this method (whatever its name) is the event handler for the Click
     event of bn_increase. However, don’t change the default event handler methods
     provided by VS.NET unless there is really a good reason to do so.

     Similarly, go back to Counter.aspx’s Design View and double click on the –
     button. Fill up the bn_decrease_Click method in Counter.aspx.vb:

     Private Sub bn_decrease_Click _
     (ByVal sender As System.Object, ByVal e As System.EventArgs) _
     Handles bn_decrease.Click

       Dim c As Integer
       c = Convert.ToInt32(lb_count.Text)

www.mokhengngee.per.sg/book
                                                                                        39


     c = c - 1
     lb_count.Text = Convert.ToString(c)

   End Sub




     VS.NET Intellisense: As you typed your codes into Counter.aspx.vb, you
   might observe a few things:

   • When you typed something wrongly (such as Di instead of Dim), squiggly blue
     lines appear under Di. Squiggly blue lines denote a syntax error. To see the
     problem, hover your mouse pointer over the squiggly blue line, and a brief
     description will pop up (figure 2-17). You have to ensure that there are no
     squiggly lines before even attempting to view the page in a browser.




     Figure 2-17: Squiggly blue lines denote a syntax error.

   • When you typed the full stop after certain words (such as lb_count., or
     Convert.), and wait for half a second, a list appears for you to select from. In
     figure 2-18, the list which appears contains the available properties for the
     lb_count Label object. You can select the correct property you want from the
     list and hit TAB (ENTER will cause the cursor to jump to a new line).




     Figure 2-18: Context sensitive assistance is available


5. Test your Web form

   It’s time to check out if your page works correctly. Right click on Counter.aspx
   in Solution Explorer and select ‘View in Browser’. (If Counter.aspx and/or its


                                                                      ASP.NET Workbook
40


     code-behind page Counter.aspx.vb have not been saved yet, VS.NET will save
     them for you automatically when you view it in a browser.)

     If everything goes fine, you should see your page with the 2 buttons. Try clicking on
     the buttons and see what happens.


6. Understand the codes

     The first statement simply declares a new local variable c of type Integer:
       Dim c As Integer

     Let’s examine the second statement:
       c = Convert.ToInt32(lb_count.Text)


     The expression lb_count.Text returns the Text value of the lb_count Label
     server control object. This was original set to “0” (as a string).
     Convert.ToInt32() is a method which takes in a string containing numbers
     only, and returns the same number value as an integer. So,
     Convert.ToInt32("0") will return 0 as an integer, and
     Convert.ToInt32("958") will return 958 as an integer. We then assign the
     integer returned by the Convert.ToInt32() expression to the variable c.

     What we have done is to take the Text value of the label, convert it into an integer,
     and assign it to c.

     Following that, we increase the value stored in c by 1:
       c = c + 1

     The next statement is:
       lb_count.Text = Convert.ToString(c)
     Convert.ToString() is a method which takes in an integer and returns it as a
     string. So, Convert.ToString(35)will return "35" as a string.

     This string value is then assigned to lb_count’s Text property, which is displayed
     on the Web page.

     Study the codes in the event handler for the – button; they are essentially the same
     except that instead of increasing c by 1, c is decreased by 1.


7. Use C# or J# instead

     Some of you may prefer to work using C# or J# instead of VB.NET. You can do so
     by selecting ‘Visual C# Projects’ (or ‘Visual J# Projects’) instead of ‘Visual Basic
     Projects’ when you selected File New Project from VS.NET’s menu in step 1.
www.mokhengngee.per.sg/book
                                                                                         41



   Of course, your code-behind file will be Counter.aspx.cs (or
   Counter.aspx.js) instead of Counter.aspx.vb.

   All the steps outlined above are the same, except that when you double click on the
   buttons to write your event handlers. The codes look different (it’s a different
   language!) The following C# codes do exactly the same thing:
   // C# - increase button event handler
   private void bn_increase_Click(object sender, System.EventArgs e)
   {
     int c;
     c = Convert.ToInt32(lb_count.Text);
     c = c + 1;
     lb_count.Text = c;
   }

   // C# - decrease button event handler
   private void bn_decrease_Click(object sender, System.EventArgs e)
   {
     int c;
     c = Convert.ToInt32(lb_count.Text);
     c = c - 1;
     lb_count.Text = c;
   }

   For programmers who prefer J#, the J# codes follow. Note that you will need to insert
   an additional import statement at the top of the file because the Convert class
   which is being referred to is in the System namespace, and the System namespace
   is not automatically imported in J# projects.
   // insert below the package statement
   import System.*;

   // J# - increase button event handler
   private void bn_increase_Click (Object sender, System.EventArgs e)
   {
     int c;
     c = Convert.ToInt32(lb_count.get_Text());
     c = c + 1;
     lb_count.set_Text(Integer.toString(c));
   }

   // J# - decrease button event handler
   private void bn_decrease_Click (Object sender, System.EventArgs e)
   {
     int c;
     c = Convert.ToInt32(lb_count.get_Text());
     c = c - 1;
     lb_count.set_Text(Integer.toString(c));
   }



8. Understand what gets sent back to the client

   View Counter.aspx again in a client browser. View the codes sent back to the
   browser (View Source from IE’s menu) and study it for a while:

                                                                        ASP.NET Workbook
42



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

        <input type="hidden" name="__VIEWSTATE"
         value="dDwxNTg5NjY5Njc4O3Q8O2w8aTwxPjs+O2w8dDw7Oz" />

        <span id="lb_count" style="Z-INDEX: 101; LEFT: 88px;
         POSITION: absolute; TOP: 32px">
        0</span>

        <input type="submit" name="bn_increase" value="+"
         id="bn_increase" style="Z-INDEX: 102; LEFT: 64px;
         POSITION: absolute; TOP: 64px" />

        <input type="submit" name="bn_decrease" value="-"
         id="bn_decrease" style="Z-INDEX: 103; LEFT: 96px;
         POSITION: absolute; TOP: 64px" />

      </form>


     Notice that the Label server control has been replaced by a <span> element to be
     sent back to the client, and both <asp:Button> controls have been replaced by
     HTML <input type="submit"> (submit buttons) elements.

     Also note that your form posts back to itself (action="Counter.aspx"). In
     other words, when either button is clicked on, the client browser sends a HTTP POST
     request back to the same Web page (Counter.aspx). The business logic for
     clicking on either button (i.e. the business logic in the event handlers) is not found in
     the HTML code which is being sent over to the client. Instead, when the user clicks
     on either button, the client will submit the form back to the server, and codes at the
     server will then determine what to do and recreate a new HTML page with the
     updated value (1 or -1) in the <span> element to be sent back.



        View State: Did you notice that the HTML codes that are sent back to the client
     browser has an additional <INPUT type="hidden"> element? ASP.NET
     improves over ASP 3.0 by automatically storing data such as text in TextBoxes and
     posting it as a hidden <INPUT> element with a name of "__VIEWSTATE" over to
     the target Web page (which, in this case, is itself). In the target page, this hidden
     <INPUT> element is examined, and ‘decoded’ at the server to recover this
     information. The form controls in the target page are then repopulated with the same
     information. All this is done transparently from the developer or user. In ASP 3.0 or
     other Web application technologies such as JSP, the developer has to write code
     manually to perform this ‘memory’ capability.




www.mokhengngee.per.sg/book
                                                                                          43




           Further Exercise

Write a Web form GST calculator which allows users to calculate the net price of a
product after factoring in GST. It can look like this:




Figure 2-19: GST calculation is no longer a headache with this application!

The user enters the Price and GST Rate and clicks on ‘Calculate’. The net price (i.e.
original price + GST) appears in the Net Price field.

Hints:
   • Your Price and GST Rate fields should expect double values (decimal values)
       instead of only just integers (whole numbers). Use the Convert.ToDouble()
       method to convert a string into a double value.
   • You will make use of the TextField server control from Toolbox’s ‘Web Forms’
       section. The TextField control allows users to enter values. Like Label,
       TextField has a Text property which you can use to retrieve or set its
       displayed value.


          Formatting controls: VS.NET provides a convenient way to ensure that your
       controls (such as TextBoxes) are vertically aligned. Select all the TextBoxes by
       clicking them individually with the shift key down, then select
       Format Align Lefts from the menu. There are other useful functions such as
       Format Make Same Size, Format Vertical Spacing and Format Horizontal
       Spacing which you can use for creating a neater user interface.



                                                                         ASP.NET Workbook
44




           Simple Error Handling

If the user enters a non-numeric string into either the Price or GST Rate fields, and click
on the Calculate button, an exception will be raised (figure 2-20). The reason is that
Convert.ToDouble() takes in only strings containing numeric characters.




        Figure 2-20: FormatException resulting from passing in a non-numeric string
        into Convert.ToDouble().

You might want to catch this problem and display an error message (by setting the Text
property of a Label server control when the user enters a non-numeric string into either
TextField. Here is a hint:

     Try
       price = Convert.ToDouble(TextBox1.Text)
       rate = Convert.ToDouble(TextBox2.Text)
     Catch err As FormatException
       lb_error.Text = _
         "Enter only numeric values in the Price and GST rate fields"
       Return
     End Try

When the user enters some non-numeric characters, an error message is shown instead
(figure 2-21).




www.mokhengngee.per.sg/book
                                                                                       45




     Figure 2-21: Your application can trap for exceptions and display error messages.


        Validator controls: we will learn how to make use of the Validator controls
     provided in the Toolbox to validate text fields in the next chapter. Validators are
     extremely convenient to ensure that the user enters only certain ‘valid’ values into
     text fields (such as only numbers in our case).

Happy programming!




                                                                       ASP.NET Workbook
46




Exercise 2.3


Understanding Code-Behind Pages
There are 2 ASP.NET programming models:
   • Single-page programming model and
   • 2-page programming model

In exercise 1.3, you were asked to create a text file called luckyno.aspx and save it
in c:\inetpub\wwwroot. Here is the source code for luckyno.aspx again:

     <!-- luckyno.aspx -->
     <SCRIPT runat="server" language="VB">
     Sub Page_Load
       Dim r As Random
       r = new Random()
       lb1.Text = "Your lucky number today is " + _
         Convert.ToString(r.Next(100))
     End Sub
     </SCRIPT>

     <HTML>
     <BODY>
       <FORM runat="server">
       <asp:label id="lb1" runat="server" />
       </FORM>
     </BODY>
     </HTML>

Luckyno.aspx makes uses of the single-page programming model: everything,
including the Page_Load method is coded in the same .aspx file. (Remember that
Page_Load is a special method which runs automatically when the Web page loads
up?)

The 2-page programming model involves code distributed between 2 files: the .aspx file
and the code-behind file which may be a .aspx.vb, .aspx.cs, or .aspx.jc file
depending on which language you chose for your project. In the previous exercises in
which you created a project in VS.NET, you have created a Web form based on the 2-
page programming model. Event handler methods are coded in the code-behind file
while visual elements (server controls, HTML elements etc) are placed in the .aspx
file.

We can ‘restructure’ luckyno.aspx so that it follows the 2-page programming model.


www.mokhengngee.per.sg/book
                                                                                        47


Objective:
   • Understand the difference between single-page programming model, and the two-
      page programming model

Instructions:

1. Create a new project

   Start up VS.NET and create a new VB.NET Web application project. Rename
   WebForm1.aspx to luckyno2.aspx. Go to HTML View of luckyno2.aspx
   and replace the <HTML> section with the codes below:

   ...
   <HTML>
     <BODY>
       <FORM runat="server" ID="Form1">
          <asp:label id="lb1" runat="server" />
       </FORM>
     </BODY>
   </HTML>

   It is important that you do not delete the statement on top which looks like this:
       <%@ Page Language="vb" AutoEventWireup="false"
       Codebehind="luckyno2.aspx.vb"
       Inherits="WebApplication6.WebForm1"%>


       Directives: This statement enclosed within <%@ and %> is a directive. Page
   directives are enclosed in <%@Page ... %> and are used to declare a number of
   attributes about the page. Of particular significance is the Codebehind attribute
   here which ‘links’ the current aspx page to its code-behind file.

   Table 2-1 shows what some Page attributes mean.

    Attribute               Possible Values      Comments
    Language                A valid .NET         Language used by all source codes on
                            language             the page.
    AutoEventWireup         true or false        Indicates if the page events are
                                                 automatically wired up. If false, events
                                                 (such as Page_Load) must be
                                                 enabled by the developer.
    Codebehind              A code-behind        Informs the compiler which file is the
                            file name            code-behind file for this aspx page.
    EnableSessionState      true, ReadOnly,      If true, the page has access to the
                            false                Session object. If ReadOnly, the
                                                 page can read but not change session
                                                 variables.
                                                                          ASP.NET Workbook
48


      EnableViewState         true, false         Page’s ViewState is maintained for
                                                  server controls.
      Inherits                Valid class name    Code-behind class that this page
                                                  inherits.
      ErrorPage               Valid URL           Page to be redirected to if an
                                                  unhandled error occurs
     Table 2-1: Some Page attributes


2. Edit the Web form

     Double click on luckyno2.aspx.vb in Solution Explorer to edit it. This is
     luckyno2.aspx’s code-behind file. (If you cannot see this file in Solution
     Explorer, click on the ‘Show All Files’ icon in Solution Explorer.)

     Notice that there is already a method in luckyno2.aspx.vb called Page_Load.

     Fill in Page_Load with the codes below:

     Private Sub Page_Load _
     (ByVal sender As System.Object, ByVal e As System.EventArgs)_
     Handles MyBase.Load

       'Put user code to initialize the page here
       Dim r As Random
       r = New Random
       lb1.Text = "Your lucky number today is " + _
         Convert.ToString(r.Next(100))

     End Sub


        Line continuation in VB.NET: Notice that line 3 in the Page_Load method
     (lb1.Text = "Your lucky number today is " + _) ends with an
     underscore. In VB.NET and VB6, the underscore is used to indicate that the current
     code line is to be continued on the next line. In C# or Java, each code statement ends
     with a semi-colon. VB does not use any special character to mark the end of a
     statement and each statement starts on a new line. If you want to break a statement
     into two or more lines in VB, you need to use the underscore to indicate that the
     current statement is to be continued on the next line.


3. Test out your pages

     View luckyno2.aspx in a browser, and you should get the same results as
     luckyno.aspx. The only difference is how the codes are structured.


www.mokhengngee.per.sg/book
                                                                                          49



      Defaulting to the 2-page model: When a new Web form is added to an ASP.NET
   project using VS.NET, it will always be based on the 2-page model type. The 2-page
   model is used in all ASP.NET projects. What are the advantages of using the 2-page
   model over the single-page model?

   The main advantage about the 2-page model is that it allows a cleaner separation of
   presentation-centric code and logical execution code. We place the presentation-
   centric ‘material’ (such as controls, HTML codes, client-side JavaScript etc) in the
   .aspx page, and the business logic (such as event-handler codes, special page life-
   cycle methods including Page_Load) in the code-behind .aspx.vb file.




Exercise 2.4

Creating a More Complex Web Form with Other Server
Controls
In this exercise, you will create a new Web form which allows the client to enter student
information such as name, email address, sex and telephone number. The page also
provides a submit button, which when clicked, will add this information to a TextBox
which will also be displayed on the same page.

Objectives:
   • To create a more complex Web form
   • Try out the server radio button list, drop down list and check box controls

Instructions:

1. Create a new project

   Create a new ASP.NET project with VB.NET. You may want to rename
   WebForm1.aspx to some other name. Add the Web server controls to the Web
   form and change the (ID) property and other control property values as indicated in
   the following table:

       Control type            ID               Property values to be modified
       asp:TextBox             tb_name          -
       asp:TextBox             tb_tel           -
       asp:TextBox             tb_email         -
       asp:TextBox             tb_records       TextMode: MultiLine
                                                ReadOnly: True

                                                                        ASP.NET Workbook
50


        asp:DropDownList         ddl_course
        asp:RadioButtonList      rbl_sex           BorderStyle: Solid
                                                   RepeatDirection: Horizontal
        asp:CheckBox             cb_issued
        asp:Button               bn_insert         Text: Insert Record

     You should end up with something like figure 2-22.

     For labels on your Web form (such as ‘Name’, ‘Course’ etc), use Label controls from
     the ‘HTML’ pane (instead of the ‘Web Forms’ pane) of the Toolbox. You can edit the
     Label’s text by selecting the Label control, and clicking once on it. Labels dragged
     over from the ‘HTML’ pane do not have a Text property which you can change, and
     run on the client side instead of the server side by default.

        Label dilemma: Why would you prefer to use the (client-side) Label control from
     the ‘HTML’ pane instead of the (server-side) Label control from the ‘Web Forms’
     pane? In this case, we will not be altering the text of the label programmatically and it
     will be more efficient to make use of ‘normal’ client-side labels (which will
     eventually become static HTML text in <DIV> elements). Do not make these label
     controls ‘run as server control’ since there is no need for them to be processed at the
     server.




        Figure 2-22: The controls on the form




www.mokhengngee.per.sg/book
                                                                                         51


2. Populate the DropDownList Control

   Select the DropDownList control and view its properties. Scroll down to the Items
   property and click on the tiny button with the “…” (figure 2-23).




   Figure 2-23: Setting the Items property of your drop down list control

   The ListItem Collection Editor pops up (figure 2-24). Here is where you can add in
   item values which the DropDownList will show.




   Figure 2-24: Adding members into the drop down list of your DropDownList
   control

   Click on the ‘Add’ button.

   On the right of the ListItem Collection Editor, type in a course name (such as
   ‘Diploma in Business Informatics’) in the ‘Text’ field, and a unique value (such as
   ‘DBI’) in the ‘Value’ field and click on the ‘Add’ button on the left. The ‘Text’ is
   what the user sees in the drop down list, and the ‘Value’ is what gets sent back to the
   server as the value of this DropDownList when the form is submitted.




                                                                         ASP.NET Workbook
52


     Insert a few courses in the same way. Here is an example of the members you can
     insert:
        Text                                     Value     Selected
        Diploma in Business Informatics          DBI       False
        Diploma in Information Technology        DIT       False
        Diploma in Engineering (Electrical)      DEE       False
        Diploma in Engineering (Manufacturing)   DEM       False
        Diploma in Chemical and Life Sciences    DCL       False

     You can use the up and down arrow buttons in the ListItem Collection Editor to alter
     the order in which the course names appear in the DropDownList. Click on ‘OK’
     when you are done. Switch to HTML View to examine what has been done to your
     Web form.

3. Populate the RadioButtonList Control

     Select the RadioButtonList control and view its properties. Scroll down to the Items
     property and click on the tiny button with the “…”. Add in the following items:

        Text        Value       Selected
        Male        M           True
        Female      F           False

     Select the ‘ListItem’ member and click on ‘Remove’ (figure 2-25).




     Figure 2-25: Delete the ‘ListItem’ member from the RadioButtonList control



        Populating Lists: In this exercise, you are populating the DropDownList and
     RadioButtonList controls manually. This isn’t exactly good practice for real
     applications. For more flexibility and convenience for future changes, you should be
     populating such controls programmatically at the server side (such as in the
     Page_Load method). The members can be read off a configuration file (such as
     Web.config, which will be covered later) or from a database table, and bound to
     the DropDownList or RadioButtonList control in Page_Load.

www.mokhengngee.per.sg/book
                                                                                     53



   To programmatically insert a string into a DropDownList with an ID of ddl_temp,
   you can do this:
     ddl_temp.Items.Add("some string")


4. Write the event handler for the Insert Button

   Double click on the Insert Button and fill up the event handler:

   Private Sub bn_insert_Click _
   (ByVal sender As System.Object, ByVal e As System.EventArgs)_
   Handles bn_insert.Click

     Dim temp As String
     temp = tb_name.Text + ", " + _
            tb_tel.Text + ", " + _
            tb_email.Text + ", " + _
            ddl_course.SelectedValue + ", " + _
            rbl_sex.SelectedValue + ", " + _
            cb_issued.Checked.ToString

     tb_records.Text += Chr(13)
     tb_records.Text += temp

   End Sub


   ddl_course.SelectedValue and rbl_sex.SelectedValue return the
   ‘Value’ of the DropDownList (“DBI”, “DIT”, “DEE” etc) and RadioButtonGroup
   (“M”, “F”) controls as strings.

   cb_issued.Checked returns a Boolean (true or false) depending on whether
   the CheckBox control is checked. Calling the Boolean object’s ToString method
   returns “True” or “False” as a string.

   Chr(13) in VB.NET returns the character represented by ASCII character 13 (i.e.
   Carriage Return). A Carriage Return character is appended to the text in
   tb_records, followed by the temp string.

      Newline characters: Instead of tb_records.Text += Chr(13), we can use
   Environment.NewLine property which returns a Carriage Return and Line Feed
   like this:
     tb_records.Text += Environment.NewLine




                                                                      ASP.NET Workbook
54


5. Test your application

     Check out if your application works in IE. Try entering some student info and
     inserting them (figure 2-26).

     For now, your simple Web application does not store inserted records permanently.
     You can modify this application to store student records in a database table after we
     have covered the ADO.NET exercises in chapter 5.

     Another thing which you might have noticed is that your simple application does not
     perform any field validation. The application is not smart enough to detect an invalid
     string in the email field, or if the user leaves the name field blank. In the next chapter,
     we will learn how to use ASP.NET’s Validator controls to perform such validation.




     Figure 2-26: Testing out your Student Personal Info System




www.mokhengngee.per.sg/book
3: Validator Controls
Validation ensures that your data is logically (follows business rules) and physically
(of the correct type) acceptable. ASP.NET comes with several useful Validator
controls which can be easily associated with your TextBoxes, so that the page gets
posted only when all fields have been properly validated.

There are 2 exercises in this chapter:
   • Exercise 3.1: Simple Validator Controls
   • Exercise 3.2: Other Validator Controls


Exercise 3.1

Simple Validator Controls
In this exercise, you will be introduced to the 2 simplest validator controls first: the
RequiredFieldValidator and the RangeValidator. You will also use the
ValidationSummary control to show customized validation errors to the user when
they enter something incorrectly.

Objectives:
   • Learn how to use the RequiredFieldValidator, RangeValidator and
      ValidationSummary controls
   • Understand how validator controls work

Instructions:

1. Create a new project

  Create a new ASP.NET project with VB.NET. Rename WebForm1.aspx to
  ValidatorWebForm.aspx. Add the server controls to the Web form and
  change the (ID) property and other control property values as indicated in the
  following table (the validator controls can be found in the ‘Web Forms’ section of
  the Toolbar):

    Control type                  ID             Property values to be modified
    asp:TextBox                   tb_name        -
    asp:TextBox                   tb_email       -
    asp:TextBox                   tb_tel         -
    asp:TextBox                   tb_level       -
    asp:Button                    bn_submit      Text: Submit

                                            55
56


      RequiredFieldValidator     rfv_name     ErrorMessage: Name is a required
                                              field.
                                              Text: *
                                              ControlToValidate: tb_name
      RequiredFieldValidator     rfv _email   ErrorMessage: Email is a required
                                              field.
                                              Text: *
                                              ControlToValidate: tb_email
      RequiredFieldValidator     rfv _level   ErrorMessage: Level is a required
                                              field.
                                              Text: *
                                              ControlToValidate: tb_level
      RangeValidator             rv_level     ErrorMessage: Enter a value between
                                              1 and 3 for Level.
                                              Text: *
                                              ControlToValidate: tb_level
                                              MaximumValue: 3
                                              MinimumValue: 1
                                              Type: Integer
      ValidationSummary           -           -


        It is important that your RangeValidator’s Type property be correctly set to
     Integer. Otherwise we will be treating the value entered by the user into
     tb_level as a string and validation happens with strange results.

     Put in and rename the Label controls from the ‘HTML’ pane too. Your Web form
     should look like figure 3-1.




     Figure 3-1: Form controls


www.mokhengngee.per.sg/book
                                                                                          57


2. Understand the requirements

   In this Web form we shall make the Name, Email and Level TextBoxes mandatory
   (i.e. is only valid when they are filled with something). We hence associate a
   RequiredFieldValidator with each of these TextBoxes. The other TextBoxes are
   optional, and are valid even if the user leaves them blank.

   In addition to being a mandatory field, the Level TextBox accepts only values of
   the range between 1 and 3 (inclusive). Hence we associate a RangeValidator with
   the MinimumValue and MaximumValue properties set to 1 and 3 respectively
   to this TextBox. In a real application, it might be more appropriate to use a
   DropDownList for such fields (especially when there are only 3 possible values),
   but we shall use a TextBox here to illustrate how the RangeValidator works.

     Validator properties: There are 3 validator control properties which are
   commonly set: ControlToValidate, Text and ErrorMessage.

   Each validator control has to be associated with another control for it to be useful,
   and the ControlToValidate property is where you will set the association
   between this validator control and the TextBox which it is validating.

   The Text property represents the value that will be displayed on the page when
   validation for the particular TextBox fails. For this exercise we use an asterisk to
   indicate a problem with the TextBox.

   The ErrorMessage will be the error message shown in the validation summary
   or pop up message box when validation fails.

      Multiple validators: It is possible for a single TextBox to be associated with
   more than one validator control. In this exercise, the tb_level TextBox is
   associated with RequiredFieldValidator rfv_level and RangeValidator
   rv_level. In this case, only when both validations are satisfied will the
   TextBox’s IsValid property become true. It is not possible for a single
   validator control to be associated with more than one TextBox without any
   tweaking though.

      Text property ‘overrides’ ErrorMessage property: If a validator control’s
   Text property is not defined (i.e. left blank), it will display the value stored in its
   ErrorMessage property when validation fails. Otherwise, if you set a value for
   Text, this is the string that gets displayed when validation fails. The
   ErrorMessage only appears in the ValidationSummary control if there is one
   on the Web form.

                                                                         ASP.NET Workbook
58



3. Test your Web form

     Right click on your Web form’s name in Solution Explorer and select ‘View in
     Browser’. Click on the Submit button without entering any values in the text
     boxes. What happens? (See figure 3-2.)

     The asterisks indicated in the validators’ Text property appear because the Name,
     Email and Level fields are mandatory. The ValidationSummary also appears with
     all the error messages of the various (unsatisfied) validators’ ErrorMessage
     property.




     Figure 3-2: Validators at work

4. Observe the behaviour of your validators

     Fill up the Name TextBox and click on the Email TextBox. Notice that when your
     cursor moves away from the Name field, the red asterisk associated with the Name
     field disappears indicating that that field has been properly validated.

        Client-side Validation: Notice that when the Name field loses focus the asterisk
     disappears even without a page submission to the server. What you are seeing is
     client-side validation using JavaScript. If you turn off client-side JavaScript
     support, or if you are using a browser which doesn’t support client-side JavaScript,
     then validation will only be performed at the server-side (i.e. after you click on the
     Submit button to post the form back). In this case, the asterisks will not appear
     even if you leave your mandatory fields blank until you submit the form.

     Check to see if your RangeValidator works by entering a number bigger than 3 or
     smaller than 1 in the Level TextBox, and click on any other Textbox. The red
     asterisk should appear to indicate that the Level TextBox is still not valid (figure 3-
     3).
www.mokhengngee.per.sg/book
                                                                                         59



   Although the Level TextBox has passed the RequiredFieldValidator’s requirement,
   it still hasn’t satisfied the RangeValidator’s requirement that the value entered be
   between 1 and 3.




   Figure 3-3: The RangeValidator detects a value out of range for the Level field
   although the RequiredFieldValidator has been satisfied.

5. View the client-side HTML codes

   View the HTML source codes for your validation Web form and study the lines of
   client-side JavaScript code that has been inserted into the HTML file by ASP.NET.

   Notice in particular that several JavaScript functions actually make calls to other
   JavaScript functions such as RequiredFieldValidatorEvaluateIsValid,
   RangeValidatorEvaluateIsValid, ValidatorOnLoad, and
   ValidatorCommonOnSubmit.


          Where are these JavaScript functions located? You may also notice this
   important <SCRIPT> element which points to a JavaScript package called
   WebUIValidation.js:

   <script language="javascript"
   src="/aspnet_client/system_web/1_1_4322/WebUIValidation.js"></scr
   ipt>

   This .js file is where these ‘missing’ JavaScript functions are found. This file
   will be downloaded to your client browser together with the HTML file.

      JavaScript dummy? Don’t worry too much if you don’t understand all the
   client-side JavaScript that ASP.NET generates for you. It really isn’t important –
   what’s important is acknowledging the fact that validator controls may generate

                                                                      ASP.NET Workbook
60


     client-side JavaScript for JavaScript-enabled browsers to perform client-side
     validation.

        Someone deleted the WebUIValidation.js file! If you are using a shared
     computer, it won’t be surprising (due to how little people know about ASP.NET)
     to find that someone has deleted all the folders in c:\inetpub\wwwroot in
     order to remove his own Web application from that machine.

     If you see this error message in figure 3-4 when you try to load up a Web form in
     which validation controls are used, it simply means what it says: this crucial
     WebUIValidation.js file from
     c:\Inetpub\wwwroot\aspnet_client\system_web\1_1_4322\
     has been deleted.




     Figure 3-4: the JavaScript file to be sent to the client browser has been deleted.

     A simple way to solve this problem is to copy the aspnet_client folder from
     another working machine over. Without this file, all client-side validation
     JavaScript cannot work.


6. Understand how validators work

     After having tried out how validators work, here comes the theoretical part.


             Validation can work at the client side (at the browser), or the server side (at
     the IIS Web server after the Web form gets posted back). Obviously client-side
     validation is preferable because forms containing invalid fields are not even posted
     back to the server (thus preventing unnecessary server-side work). Client-side
     validators will ensure that all fields are valid before posting the form over.

     ASP.NET validators work on both ends. Client-side JavaScript code is generated
     and sent back to the client browser for client-side validation if IIS detects that the
     client browser has JavaScript enabled. On the other hand, ASP.NET always also
     performs server-side validation even if the client supports JavaScript, and is
     capable of performing client-side validation.

        Double protection: Why bother with server-side validation if the client can
     perform client-side validation? The answer is quite obvious: why should the server
www.mokhengngee.per.sg/book
                                                                                       61


   trust the client totally? Experienced users who understand JavaScript can easily
   bypass all the client side JavaScript validation code and spoof a Web form post
   containing invalid field entries. This spoof will not work since there is another
   round of validation checks at the server.


7. Use the IsValid property of the page and the validator controls


            You will need to programmatically check for the validity of your validator
   controls. Each validator control will have an IsValid (Boolean) property which
   is set to true or false depending on whether its condition imposed on the control it
   is validating has been satisfied.

   The page also has an IsValid property which is set to true only when all the
   validator controls on the form are valid. The page’s IsValid property is often
   checked in the event handler method of the Submit button. When the user posts the
   form by clicking on the button, we can perform a server-side check on whether the
   page’s IsValid property is true. If so, we can carry on with other business logic,
   such as forwarding to another page. Otherwise, some validator control on the form
   is still not satisfied, and we would like the user to make the necessary corrections
   before resubmitting the form again.

   Here is an example of codes placed into a submit button’s event handler:

   Private Sub bn_submit_Click _
   (ByVal sender As System.Object, ByVal e As System.EventArgs)_
   Handles bn_submit.Click

     If Page.IsValid Then
       Response.Redirect("NextPage.html")
     End If

   End Sub

   When the user clicks on the submit button, the form gets posted back to the server
   and in the button’s event handler, a check is done to determine if all the validator
   controls are cleared. If so (and Page.IsValid returns true),
   Response.Redirect will forward the user to NextPage.html.

   If for some reason, you need to check the validity of each validator controller, you
   can also check out the validator controller’s IsValid property.


       Using Page.IsValid in Page_Load: One seemingly possible location to
   check the validity of all the validator controls in a page is in the Page_Load

                                                                      ASP.NET Workbook
62


     method. However, if you try to do that there, you will meet a HttpException
     with the description that ‘Page.IsValid cannot be called before validation has
     taken place’.

     The error is self-explanatory: the validity of the controls cannot be determined
     when the page loads. A better place to check out Page.IsValid will be the
     submit button’s event handler.

     After having grasped the basics of validator controls, you will explore the
     remaining validator controls in the next exercise.



Exercise 3.2

Other Validator Controls
This exercise builds upon the previous exercise. You will need to have
ValidatorWebForm.aspx ready since we are going to add on new validator
controls to that form.

Objectives:
   • Be introduced to the remaining Validator controls: CompareValidator ,
      RegularExpressionValidator and CustomValidator

Instructions:

1. Place validator controls on form

     From the ‘Web Forms’ section of the Toolbar, drag out a few more controls to the
     Web form and set their property values as indicated in the table below:

      Control type            ID                 Property values to be modified
      asp:TextBox             tb_pwd             TextMode: Password
      asp:TextBox             tb_confirmPwd      TextMode: Password
      CompareValidator        cv_pwd             ErrorMessage: Passwords do not
                                                 match.
                                                 Text: *
                                                 ControlToValidate: tb_confirmPwd
                                                 ControlToCompare: tb_pwd
      RegularExpressionV      rev_email          ErrorMessage: Email is not valid.
      alidator                                   Text: *
                                                 ControlToValidate: tb_email

www.mokhengngee.per.sg/book
                                                                                       63


                                                ValidationExpression: click on the
                                                “…” button and select ‘Internet E-
                                                mail Address’ from the Regular
                                                Expression Editor which pops up
                                                (figure 3-5).




   Figure 3-5: Using standard regular expressions for our
   RegularExpressionValidator

   Figure 3-6 shows how your Web form should look like.




   Figure 3-6: Form with new validator controls

2. Understand the additional validation requirements

   The RegularExpressionValidator checks to see if a value entered into a TextBox
   satisfies a regular expression (regex). Here we are setting the validator to check if
   the value entered into the Email TextBox satisfies the structure for a valid email
   address (i.e. contains an @ character with characters in front of and behind the @
   character etc).

                                                                       ASP.NET Workbook
64



     We want to use the CompareValidator to compare the values in the tb_pwd and
     tb_confirmPwd TextBoxes. If the values are not equal, we want the validation
     to fail.

        What are regexes? A Regular Expression is used by programmers to express
     how a program should look for a specified string which matches a particular
     pattern.

     For example, the regex ‘[A-Z][A-Z]’ means a string with 2 uppercase
     characters from A to Z. American state abbreviations such as ‘CA’ or ‘TX’ will
     satisfy this regex, while ‘CAT’, ‘12’, ‘ca’ will not. Another example is the regex
     ‘\d{5}’ which means 5 digits. Strings such as ‘55012’ and ‘12345’ will satisfy
     this regex. ‘\d{2}(-\c{3})’ is a more complex one meaning 2 digits followed
     optionally by a hyphen and 3 characters. ‘12’, ‘12-abc’, ‘99-ddd’ will match this
     regex, while ‘12-’, ‘12-a’ and ‘123-abc’ will not.

     VS.NET only comes with a small set of predefined regular expressions (which can
     be seen in the ‘standard expressions’ list box in figure 3-5). If you need to
     construct a special regex which is not in the list box, you may want to check up the
     Internet for predefined ones instead of going through the tedium of working it out
     yourself.

        TextBox with TextMode set to Password: Notice that such TextBoxes will not
     display the contents in clear. Another interesting thing to note is that such
     TextBoxes do not retain their values after a post back for obvious reasons.


3. Test your Web form

     Test out your new Web form and type in an invalid email address and non-
     matching passwords in the 2 password TextBoxes (figure 3-7).




www.mokhengngee.per.sg/book
                                                                                   65




   Figure 3-7: RegularExpressionValidator and CompareValidator working


      The versatile CompareValidator: Take a look at the CompareValidator’s other
   properties. Instead of validating against the value in another TextBox (which you
   did in this exercise), you can set the CompareValidator’s ValueToCompare
   property to a certain predefined value, and its Operator property to something
   else other than ‘Equal’.

   For example, we can set the ValueToCompare to 5 and Operator to
   GreaterThan and Type to Integer to check if the user has entered a value
   greater than the number 5 (hence making it work in a similar way as the
   RangeValidator). We can also set the ValueToCompare to 01/04/2004 and
   Operator to GreaterThan and Type to Date to ensure that a date value
   entered (in the form of dd/mm/yyyy) is later than April Fool’s Day in 2004!

   We can also use this validator to check if a field is of a particular data type by
   setting Operator to ‘DataTypeCheck’ and Type to say – Integer. Only if
   the user enters an integer will the validation succeed.


4. Insert a CustomValidator Control

   It’s time to check out the last validator control: the CustomValidator. As the
   name implies, the CustomValidator allows us to write customized code to
   perform the validation.

   From the ‘Web Forms’ section of the Toolbar, drag out a few more controls to the
   Web form and set their property values as indicated in the table below:


                                                                    ASP.NET Workbook
66


      Control type          ID               Property values to be modified
      asp:TextBox           tb_birthDate     -
      CustomValidator       custv_date       ErrorMessage: Must be older than 12
                                             years old!
                                             Text: *
                                             ControlToValidate: tb_birthDate


5. Understand the additional requirements

     We have added in an additional TextBox for the birth date, and a CustomValidator
     control. In this case, we want to validate that the birth date entered indicates that
     the age of the user be more than 12 years old (12-year-olds should not be in the
     polytechnic!). None of the ready-made validator controls can perform this kind of
     validation, and we have to resort to a CustomValidator.

        Customized to your needs: as the name implies, you use CustomValidators for
     ‘custom made’ validation. i.e. you will provide the code which decides if the value
     entered is valid or not. You need to fill up a special event handler called
     <CustomValidator name>_ServerValidate which will be called to
     evaluate the CustomValidator. In this method, you will set the IsValid property
     of this CustomValidator to true or false before returning.

     Custom validation is always performed on the server-side, but there is an option to
     provide an additional client-side JavaScript (or VBScript) function which you can
     include in your aspx page. You can indicate the name of the client-side script in
     the CustomValidator’s ClientValidationFunction property.


6. Write code for custom validation

     Double click on the CustomValidator on the Web form. This will bring you to the
     custv_date_ServerValidate method in the code-behind page. This is
     where you will fill up your custom validation business logic.

     Fill up custv_date_ServerValidate as indicated below:

     Private Sub custv_date_ServerValidate _
     (ByVal source As System.Object, ByVal args As _
     System.Web.UI.WebControls.ServerValidateEventArgs)_
     Handles custv_date.ServerValidate

       Dim bdate As Date
       Try
         bdate = CDate(args.Value)
         args.IsValid = bdate.AddYears(12) <= Date.Today
       Catch

www.mokhengngee.per.sg/book
                                                                                     67


       args.IsValid = False
     End Try

   End Sub


   The args parameter passed into the ServerValidate method is important. It
   represents a ServerValidateEventArgs object which has a IsValid
   property which can be set to True of False depending on whether your business
   logic thinks that validation has been satisfied. args also has a Value property
   which represents the value in the TextBox this particular CustomValidator has
   been associated with.


7. Test the CustomValidator control

   View the form in a browser and enter a date more than 12 years ago and one which
   is less than that into the Birth Date TextBox (figure 3-8). Notice that the asterisk
   appears only upon a form submit since custom validation works at the server-side
   (we have not included a client-side script for this exercise).




   Figure 3-8: The CustomValidator thinks that Lynn is too young.




          Explore other ValidationSummary properties

   Select the ValidationSummary control on your Web form and change the
   following properties:
    Control type           ID Property values to be modified
    ValidationSummary      -    DisplayMode: List or SingleParagraph
                                ShowMessageBox: True


                                                                     ASP.NET Workbook
68


     Observe any differences when the property values have been set in this way.
     Notice that the message box which pops up is generated by client-side script code,
     and will not indicate any error messages from your CustomValidator.




            Further Exercise

     Now that you have mastered validator controls, open up the Student Personal Info
     System Web form you have created in Exercise 2.4, and add in validators for the
     Name, Tel and Email fields.

     The records TextBox should not be updated unless a name, valid telephone
     number and valid email address have been entered.




www.mokhengngee.per.sg/book
4: State Management
It is a well-known fact that HTTP is a stateless protocol, and that it doesn’t keep state
information in between POST or GET requests from the browser client to the Web
server. Web applications ‘remember’ a particular client, and relate a client request to
subsequent ones via ‘artificial means’ such as using cookies deposited at the client’s
cookie cache.

Nevertheless, most Web applications need to be able to maintain some unique state
information for each client which visits the Web site. There are 2 general ways to
maintain state information: at the client, or at the server. ASP.NET provides 2 useful
universal objects (the Session and the Application) which the Web application
developer can use to store state variables at the server.

The exercises in this chapter will explore the usage of the Session and
Application object, and cookies for storing state information.

2 important configuration files which developers use to store configurable parameters
will also be introduced: Global.asax and Web.config.

There are 5 exercises in this chapter:
   • Exercise 4.1: State Management Using the Application and Session Objects
   • Exercise 4.2: Using Cookies
   • Exercise 4.3: Using Global.asax
   • Exercise 4.4: Extracting Parameters from Web.config Programmatically
   • Exercise 4.5: Tracing your Web application




                                                                                        69
70




Exercise 4.1

State Management Using the Session and Application
Objects
This exercise explains how to use the Session and Application objects to store
state information. In addition, URL tagging is introduced as an alternate way to
forward name/value pairs to the next page.

Objectives:
   • Learn how to use the Session and Application objects to store state variables.
   • Understand when to use the Session and Application objects
   • Understand how to use Application.Lock() and
      Application.UnLock() methods.
   • Use URL tagging for passing request parameters to the next page

Instructions:

1. Create a new project

     Create a new Web application project called StateWebApplication (you can
     select VB.NET, C# or J# as your language). Rename your default Web form from
     WebForm1.aspx to 1stpage.aspx.

     Add the server controls to the Web form and change the (ID) property and other
     control property values as indicated in the following table:

      Control type        ID              Property values to be modified
      asp:TextBox         tb_day          -
      asp:TextBox         tb_name         -
      asp:TextBox         tb_color        -
      asp:Button          bn_submit       Text: Submit

     Insert in the labels (from the HTML section of the Toolbox) so that the final Web
     form looks like figure 4-1.




www.mokhengngee.per.sg/book
                                                                                     71




   Figure 4-1: How 1stpage.aspx should look like.


2. Write the event handler for the submit button

   Double click on the Submit button to write its event handler. Fill in the method as
   follows:

   VB.NET code:
   Private Sub bn_submit_Click _
   (ByVal sender As System.Object, ByVal e As System.EventArgs)_
   Handles bn_submit.Click
     Application.Lock()
       Application("day") = tb_day.Text
     Application.UnLock()
     Session("name") = tb_name.Text
     Response.Redirect("2ndpage.aspx")
   End Sub

   C#:
   private void bn_submit_Click(object sender, System.EventArgs e)
   {
     Application.Lock();
       Application("day") = tb_day.Text;
     Application.UnLock();
     Session("name") = tb_name.Text;
     Response.Redirect("2ndpage.aspx");
   }

   J#:
   private void bn_submit_Click (Object sender, System.EventArgs e)
   {
     get_Application().Lock();
     get_Application().set_Item("day",tb_day.get_Text());
     get_Application().UnLock();
     get_Session().set_Item("name",tb_name.get_Text());
     get_Response().Redirect("2ndpage.aspx");
   }



      Using the Application or Session object: It’s extremely easy to place
   state variables into the Application or Session object.


                                                                      ASP.NET Workbook
72


     The following statement stores a variable called myvar with the corresponding
     string value "The sky is blue" into the Session object:
         Session("myvar") = "The sky is blue" ' VB.NET
          Session["myvar"] = "The sky is blue" // C#
          get_Session().set_Item("myvar","The sky is blue"); //J#


     To retrieve the value stored in myvar from the Session object, just access it
     using Session("myvar") in VB.NET or Session["myvar"] in C#/J#.
     The following statement retrieves the string value stored in the variable myvar in
     Session and stores it in another pre-declared string variable called temp:
         temp = Session("myvar") ' VB.NET
          temp = Session["myvar"] // C#
          temp = get_Session().get_Item("myvar"); // J#


     To store or retrieve variables from the Application object, just use
     Application instead of Session:
         Application ("myvar") = "The sky is blue" ' VB.NET
          Application ["myvar"] = "The sky is blue" // C#
          get_Application().set_Item("myvar","The sky is blue"); // J#

         temp = Application("myvar") ' VB.NET
          temp = Application ["myvar"] // C#
          temp = get_Application().get_Item("myvar"); // J#




3. Understand the codes

     Study the codes for the event handler, and try to understand what it does.

     When the Submit button is clicked, the text entered into tb_name will be stored
     in a variable called name in the Session object, and the text entered into
     tb_day will be stored in a variable day in the Application object. We will
     try to retrieve these variable in 2ndpage.aspx.

     Response.Redirect simply forwards the user to the new Web page (
     2ndpage.aspx), which you will create in the next step.

          Calling Application.Lock() and UnLock(): You would have noticed
     that the statement which actually modifies the variables stored with the
     Application object are between 2 statements: Application.Lock() and
     Application.UnLock(). Why should you call these methods before and after
     setting variables to the Application object?

     In a multi-user environment, there may be many concurrent visits to
     1stpage.aspx from different clients. And because ASP.NET is multi-threaded
     (of course server applications have to be multi-threaded!), you might have
www.mokhengngee.per.sg/book
                                                                                   73


  inconsistencies when the same statement attempting to update a variable into
  Application executes simultaneously by more than 1 client. To prevent other
  clients from executing such statements at the same time, the
  Application.Lock() method is invoked first. Only one of many
  concurrently running processes can execute statements within the ‘critical section’
  (between the Lock() and UnLock() statements). Only when that process which
  is executing statements within the critical section calls
  Application.UnLock() can other processes go into the critical section. This
  prevents multiple, concurrent access to the Application object, and is a good
  practice that should be followed.


4. Create 2ndpage.aspx

  We are now going to create a new Web form in the same project called
  2ndpage.aspx. In the Solution Explorer, right click on the name of your Web
  application (StateWebApplication) and select Add Add Web Form (figure
  4-2).




  Figure 4-2: Adding a new Web form into the same project

  Type in 2ndpage.aspx in the Name field, and click on Open (figure 4-3). You
  should be able to see this new Web form in the Solutions Explorer.




                                                                    ASP.NET Workbook
74




     Figure 4-3: Adding a new Web form into the same project.

        Adding new items into the project: You can add anything you want – such as a
     HTML page which you have already written – into the current project by right
     clicking the project name in Solution Explorer, and selecting Add Add New
     Item, or Add Add Existing Item. You can even create folders in your project by
     selecting Add New Folder to organize your Web forms when there are too many
     of them in the same project.

5. Edit 2ndpage.aspx

     Open up 2ndpage.aspx, and drag 2 server-side Label objects from the Web
     Forms pane of the Toolbox (figure 4-4):

     Control type         ID                Property values to be modified
     asp:Label            lb_statement1     -
     asp:Label            lb_statement2     -




     Figure 4-4: 2ndpage.aspx with 2 server-side Labels.

     We will change the Text property of these Label objects in the Page_Load
     method. Open up the code-behind file of 2ndpage.aspx.



www.mokhengngee.per.sg/book
                                                                                     75



   A fast and convenient way to do that is to double click on any blank space of
the Web form (in Design View).

Enter the following codes into the Page_Load method.

For VB.NET:
Private Sub Page_Load _
(ByVal sender As System.Object, ByVal e As System.EventArgs)_
Handles MyBase.Load
  'Put user code to initialize the page here
  lb_statement1.Text = "Hi, " + Session("name")
  lb_statement2.Text = "Today is " + Application("day")
End Sub

For C#:
private void Page_Load(object sender, System.EventArgs e)
{
  // Put user code to initialize the page here
  lb_statement1.Text = "Hi, " + Session("name");
  lb_statement2.Text = "Today is " + Application("day");
}

For J#:
private void Page_Load(Object sender, System.EventArgs e)
{
  lb_statement1.set_Text
    ("Hi, " + get_Session().get_Item("name"));
  lb_statement2.set_Text
    ("Today is " + get_Application().get_Item("day"));
}

The expression Session("name") returns the value stored in the variable
name in the Session object, and the expression Application("day")
returns the value stored in the variable day in the Application object.

    Does case-sensitivity matter for state variables? Variables stored into the
Application or Session object are not case-sensitive even if you are using a
case-sensitive language such as C# or J#. You can check this out by retrieving
variable NAME instead of name from the Session object in Page_Load, and
you should still be able to get the same results. Despite this, it doesn’t hurt to keep
to the correct case to prevent unnecessary confusion.

   See Ma, No Locks: Notice that for retrieving variables in the Application
object, we do not need to call the Application.Lock() or
Application.UnLock() methods. There is no danger of allowing
simultaneous retrieval of variables from the Application object; it’s only when
we are updating variables do you need to be careful.



                                                                     ASP.NET Workbook
76


6. Test your application

     Fire up 1stpage.aspx in your Web browser, and fill in the fields, then click on
     the submit button (figure 4-5).




     Figure 4-5: Testing out 1stpage.aspx

     Upon submission, the values you entered in the Day and Name TextBoxes will be
     stored in the Application and Session objects respectively, and your
     browser will then be redirected to 2ndpage.aspx, where those variables are
     retrieved from the Application and Session objects and displayed as Label
     text (figure 4-6).




     Figure 4-6: 2ndpage.aspx is able to retrieve information from the Session
     and Application objects.


7. Understand the difference between storing variables in Application and
   Session.



www.mokhengngee.per.sg/book
                                                                                 77


While keeping the current IE window still open, start up a new IE window, and
type in the URL for 2ndpage.aspx (not 1stpage.aspx) in the Address
field. You would have noticed that in this second IE client, 2ndpage.aspx is
unable to retrieve the name variable from the Session object, but can still
retrieve and display the day variable from the Application object (figure 4-7).

Similarly, open up a new IE window on your friend’s machine, and type in the
URL for 2ndpage.aspx hosted on your machine.

  Remember to replace localhost with your machine’s IP address; otherwise
you will be trying to access the page hosted on your friend’s machine instead!

The same result occurs (figure 4-7): 2ndpage.aspx is unable to find the name
variable stored in the Session object, but is able to find the day variable stored
in the Application object.




Figure 4-7: Variables stored in the Application object are available, whereas
variables stored in the Session object are not shared between unique sessions.

   The explanation: Variables stored in the Application object are shared by
all clients to the same Web application. You can view it as a location to store
‘global’ variables which any Web form in your Web application can set or retrieve.

On the other hand, every unique client will have its own Session object. When a
new client visits a Web page in your Web application, IIS creates a new Session
object for storing state variables. When the same client visits any Web page in the
same Web application again (before the session expires), IIS is able to match this
client with the same Session object.

In the exercise, when you opened the second IE window, that new window is
considered a new unique client which has its own unique session. That’s the reason
why Session("name") will return an empty string. On the other hand,


                                                                  ASP.NET Workbook
78


     Application("day") will still return something because these separate
     clients are sharing the same Application object.

        Team collaboration: When collaborating to write a Web application, it is
     advisable to have a controlled document which records the variables stored in the
     Session and Application object, including a brief description of what they
     are used for, the type, and from which pages they are used. This will prevent the
     accidental ‘overriding’ when different members create Web forms that
     coincidentally use the same state variable names in the Application or
     Session object.

     Place ‘global’ variables which are used by every page in the Application
     object. Place client-specific variables in the Session object. A good example of
     what to store in the Session object will be the user’s ID when the user logs in at
     the login page. Henceforth, all other pages in the same Web application can access
     the user’s ID from Session.

        Wasting memory: Do not place unnecessary variables (especially large objects)
     in Session or Application! The reason is because it takes up server
     resources to store these variables for persistence across multiple pages.

     For variables that are relevant only for the next page, you should set it as a
     Response parameter in the URL instead (such as:
     Response.Redirect("2ndpage.aspx?color=Lemon-yellow"). URL
     tagging will be explained in the next step.

           The Session and Application objects: the Session object is
     actually an instance of the HttpSessionState class, and the Application
     object is an instance of the HttpApplicationState class. Both Session
     and Application state are structured as a key-value dictionary for storing
     session or application-specific information that needs to be maintained between
     server round trips across requests for pages. The Application and Session
     states are implemented as a hash-table and store data based on key/value pair
     combinations. The key will be a variable name, and the value will be the value
     corresponding to that variable.


8. Use URL tagging for Response parameters

     The value entered by the user in the Color TextBox in 1stpage.aspx cannot be
     retrieved in 2ndpage.aspx because we did not save this variable in the


www.mokhengngee.per.sg/book
                                                                                  79


Session or Application. We are going to use URL tagging to set this
favorite color value as a response parameter.

Response parameters are only retrievable by the next immediate Web page.

   Limitations of using Response parameters: whilst you can store a variable of
any type (not only strings) into the Session or Application (you will need to
type cast them to the correct type upon retrieval subsequently), only strings can be
passed via URL tagging as name/value pairs.

  URL tagging is client-side state management: Appending information at the
end of the URL, or query string in this way is usually considered a Client-side state
management method, rather than server-side. The reason is because the URL
posted to the server as part of the form’s submission comes from the client.

Open the code-behind file for 1stpage.aspx and edit the page redirecting
statement in the event handler for the Submit button:
   Application("day") = tb_day.Text
   Session("name") = tb_name.Text
   Response.Redirect("2ndpage.aspx?color=" + tb_color.Text)

Assuming that the user had entered ‘Lemon-yellow’ into the favourite color
TextBox, when the Submit button is clicked, she will be forwarded to the
following URL:
  2ndpage.aspx?color=Lemon-yellow

Insert another asp:Label object (call it lb_statement3) into
2ndpage.aspx. Open the code-behind file for 2ndpage.aspx and insert a
statement into your Page_Load method:

  lb_statement1.Text="Hi, " + Session("name")
  lb_statement2.Text="Today is " + Application("day")
  lb_statement3.Text="Fave color is "+Request.Params("color")


The expression Request.Params("color") will return the value associated
with color in the request URL. Note that other pages in the same Web
application will not be able to access this value, unlike variables stored in the
Session or Application object.

  Tagging multiple parameters to the URL: To ‘pass over’ more than one
name/value pair in the URL to the next page, you can do something like this to the
URL:
  targetpage.aspx?param1=value1&param2=value2&param3=value3




                                                                   ASP.NET Workbook
80


     The targeted Web page in this case (targetpage.aspx) will be able to retrieve
     the values of param1, param2 and param3 from the Request object in the
     same way (i.e. Request.Params("param1") etc).

9. Check if URL tagging works

     Test your application to check if the color value has been successfully passed
     over. Take note of the URL after you have clicked on Submit (figure 4-8).




     Figure 4-8: Passing name/value pairs by URL tagging

        Spaces in URLs: You might have noticed in the URL (shown in figure 4-8), the
     space between Pale and Turquoise has been replaced with %20. Spaces in
     URLs are usually replaced with %20. The space is ASCII character number 32, or
     2016.


10. Set Session Time-out

            Because HTTP is a client-driven protocol, there is no way the server knows
     if a client is still active unless it sends a POST or GET request over. Web
     applications keep track of whether a particular client is still active in a passive way
     by setting a time-out period for each user session. If the Web server doesn’t
     receive any request within this time-out period, the Web application will assume
     that this client is no longer active (though the user might just have gone off for a
     long coffee break).

       Default timeout: The default timeout period for ASP.NET is set to 20 minutes.
     You can change this value in Web.config.




www.mokhengngee.per.sg/book
                                                                                        81


   Open up Web.config by double clicking it in Solution Explorer. Scroll down
   until you see the <sessionState> element, and change the timeout
   attribute’s value from 20 to 1. Save Web.config.

   <sessionState
      mode="InProc"
      stateConnectionString="tcpip=127.0.0.1:42424"
      sqlConnectionString=
        "data source=127.0.0.1;Trusted_Connection=yes"
      cookieless="false"
      timeout="1" />

   From this point onwards, all user sessions will expire in 1 minute’s time. Upon
   time-out, the Session object will be invalidated, and all the variables associated
   with it will be lost.

   To prove that this is true, open up 1stpage.aspx again, fill in the Name
   TextBox (this value is stored in the Session object) and submit. You will see the
   entered name in 2ndpage.aspx. Refresh the page a few times, and notice that
   the name is still there.

   Wait for 1 minute and refresh the page again. This time you will notice that the
   name variable has been removed because your session has already expired.

      Killing a session programmatically: You can programmatically invalidate a
   user session by calling the Session.Abandon() method.

      Tracing: ASP.NET provides a Trace feature which we can use to read off all
   the variables in the Session and Application object for debugging purposes.
   We will explore the Trace feature in exercise 4.4.




Exercise 4.2

Using Cookies
Using the Session and Application object to store state information is a
common but expensive solution to maintain a conversational state at the server side.
Cookies is another commonly employed solution to store state information at the
client side. Cookies are usually used to ‘remind’ a Web application that a particular
client has previously visited the same site, and store useful information such as her

                                                                      ASP.NET Workbook
82


user preferences (preferred color, area of interest etc). In this exercise, you will learn
how to cookie-enable your ASP.NET Web application.

           What’s a Cookie – is it edible? A cookie is a small text file that can be used
     to store small amounts of information needed to maintain state. Cookies are saved
     in the client’s browser cache, and hence maintaining state using cookies is
     considered a client-side state management method, rather than server-side.

     When the client browser requests for a page, it sends the information in the cookie
     along with the request information.

          Cookie Categories: there are 2 types of cookies: temporary and persistent.

     Temporary cookies are also known as session cookies, and exist in the memory of
     the client browser. They are removed when the browser is closed.

     Persistent cookies are stored in the client’s machine. For IE, persistent cookies are
     stored in C:\Documents and Settings\<username>\Cookies (where
     <username> refers to the account name used to log into Windows). Check out
     this folder, and you will find that each cookie file is named using the format
     username@domainname.txt. When the same user visits a Web page in the
     same domain, the associated cookie information will be sent over to the Web
     server automatically. Persistent cookies have life spans, which can be set by the
     Web application. Upon expiry, they will no longer be valid.


         Cookies are often used to keep user profiles for marketing purposes by
     commercial sites, and have since gained a notorious reputation as a privacy
     invading feature. When writing Web applications that get or set cookies, take into
     consideration the fact that most browsers allow the user to turn off cookie support.
     Your Web application can either force the user to enable cookie support (Yahoo!
     Mail does that), or you can ensure that the application still works without cookies.

     If you want to turn off cookie support in IE6, click on Tools Internet Options,
     select the Privacy tab, and click on the Advanced button (figure 4-10).




www.mokhengngee.per.sg/book
                                                                                       83




   Figure 4-10: Disabling cookies in IE6.

   If you are using the older IE5, click on the Security tab (instead of the Privacy tab),
   and click on the Custom Level button.

For this exercise, we are going to write a simple Web application which keeps track of
the number of times a user has visited the page from the same machine. The
application keeps track of this information by storing this counter value in a persistent
cookie at the client’s machine.

Objective:
   • Learn how to set and get cookies to/from the client

Instructions:

1. Create a new project

   Create a new Web application project called CookieWebApp using C#, J# or
   VB.NET.

   Add a Label server control to the Web form as indicated in the following table:
    Control type        ID               Property values to be modified
    asp:Label           lb_statement     -


2. Write the Page_Load method

   Open up the Web form’s code-behind page and insert the following statements into
   the Page_Load method:

       Private Sub Page_Load _

                                                                       ASP.NET Workbook
84


        (ByVal sender As System.Object, ByVal e As System.EventArgs)_
        Handles MyBase.Load

          '1st visit
          If Request.Cookies("visitCookie") Is Nothing Then
            lb_statement.Text = "Welcome to this site!"
            SetCookie(1)
            Return
          End If

          'Subsequent visits
          Dim c As HttpCookie = Request.Cookies("visitCookie")
          Dim noOfVisits As Integer
          Dim lastTime As DateTime

          noOfVisits = c.Values("count")
          lastTime = c.Values("time")
          lb_statement.Text = "You have visited this site " + _
            Convert.ToString(noOfVisits) + _
            " times. Your last visit was " + _
            Convert.ToString(lastTime)

          'Readjust values and set cookie
          noOfVisits += 1
          SetCookie(noOfVisits)
        End Sub



3. Write the SetCookie method

     Write a new method called SetCookie which takes in the new counter value as
     an Integer:
        Private Sub SetCookie(ByVal counterValue As Integer)
          'newC is the new cookie to be set
          Dim newC As New HttpCookie("visitCookie")

          'create & set cookie to client
          newC.Values.Add("time", Now())
          newC.Values.Add("count", counterValue)
          Response.Cookies.Add(newC)
        End Sub

     Read the codes and try to understand what you have written. In VB.NET, the
     Now() method returns the current system time as a DateTime object. (In C#/J#,
     you can use DateTime.Now instead.)


4. Test your application

     Run your Web form and refresh the page a few times (figure 4-11). Does your
     Web application keep track of the number of visits and your last visit time?



www.mokhengngee.per.sg/book
                                                                                          85




   Figure 4-11: Testing our Cookie


5. Create persistent cookies

   While the first browser is still open, open up a new IE browser from the START
   button and type in the same URL. You will notice that the visitCookie that
   our application has set to the first client browser isn’t ‘picked up’ by the second.

       Sharing sessions in IE: If you open a new IE window from File New of an
   existing IE windows, the newly opened IE window will share the same session as
   its ‘parent’ IE window. On the other hand, if you start up a new IE window via the
   START button, you will get an IE window with a totally new session distinct from
   any other IE windows which are already open.

   Refresh the first browser a few more times, followed by the second browser.

   Open up your cookie folder (that’s C:\Documents and
   Settings\<username>\Cookies if you are using IE). Arrange the cookie
   text files in order of time modified; you will notice that no new cookie file has
   been stored there.

   Why is this so? The reason is because what the Web application has sent over to
   the client browser is a temporary cookie, which is not stored in the client’s cookie
   cache.

   In order to create a persistent cookie, you need to insert an additional statement
   into your SetCookie method:

        'Create & set cookie to client
        newC.Values.Add("time", Now())
        newC.Values.Add("count", counterValue)
        newC.Expires = Now.AddHours(1)
        Response.Cookies.Add(newC)




                                                                        ASP.NET Workbook
86


     This statement sets our new cookie to expire 1 hour later. You can use
     Now.AddDays() or Now.AddMonths()or even Now.AddYears() if your
     cookie is to be long-living.

     Open up your browser’s cookie folder again, and you should be able to find the
     new persistent cookie file that has been deposited by the Web application.

     This time, view your Web form in a browser, refresh it a few times, open a few
     new browser windows and see the differences between how temporary and
     persistent cookies work. You can close all your browser windows, and open a new
     one; the cookie is still valid and successfully retrieved unless it has expired.

        Expired persistent cookies: Once a persistent cookie expires, it is no longer
     valid. You can verify this by setting a persistent cookie with a lifespan of 1 minute
     (use Now.AddMinutes(1)), refresh your page a few times, then go off for a 1-
     minute break. When you come back, refresh the same page and see what happens.


6. Cookie summary

     Here are the codes on how to set a cookie:

     VB.NET:
        Dim c As New HttpCookie("cookieName")
        c.Values.Add("param1", "some value")
        c.Values.Add("param2", "some other value")
        c.Values.Add("param3", "yet some other value")

     C#/J#:
        HttpCookie c = new HttpCookie("cookieName");
        c.Values.Add("param1", "some value");
        c.Values.Add("param2", "some other value");
        c.Values.Add("param3", "yet some other value");

     Here are the codes on how to retrieve a cookie:

     VB.NET:
        Dim   c As HttpCookie     =   Request.Cookies("cookieName")
        Dim   temp1 As String     =   c.Values("param1")
        Dim   temp2 As String     =   c.Values("param2")
        Dim   temp3 As String     =   c.Values("param3")

     C#/J#:
        HttpCookie c     =   Request.Cookies["cookieName"];
        string temp1     =   c.Values("param1");
        string temp2     =   c.Values("param2");
        string temp3     =   c.Values("param3");


www.mokhengngee.per.sg/book
                                                                                      87




Exercise 4.3

Using Global.asax
There are 2 important configuration files which you need to be aware of in ASP.NET:
global.asax and Web.config. When you create a new project in VS.NET, you
should be able to see them in Solution Explorer.

The global.asax is a code file where developers place application and session-
level event handler code. In this exercise, you are going to explore the
global.asax file of a Web application and make changes to some of the event
handlers within.

   Changing global.asax: If a change is made to the Web application’s
global.asax file when the application is currently hosted, the application ‘shuts
down’ dynamically. When a new page request comes in, the Web application will
restart.

    Optional file: global.asax is an optional file. But if it exists, it must be located
in the root of the Web application (i.e.
c:\inetpub\wwwroot\<project_name>).

Objectives:
   • Understand how to use the event handlers in global.asax.
   • Understand the purpose of Web.config.

Instructions:

1. Create a new project and open global.asax for editing

   Create a new ASP.NET Web application project using your preferred language.
   Click on the cross beside the global.asax file name in Solution Explorer and
   double click on the global.asax.vb (or global.asax.cs, depending on
   the language you had selected) to edit it. This is the code-behind file which
   contains the application and session-level event handlers.


2. Understand event handlers in global.asax

   Examine the event handler methods that are available. The following table
   describes when they are called:

                                                                       ASP.NET Workbook
88



     Event             Description
     Application_Start Called when a Web application starts. This method will
                       only be called once when the first client sends a page
                       request to the Web application.
                       Put application initialization code here. For example,
                       developers usually set Application variables here.
     Application_End Called when the application shuts down. Put code to
                       clean up any shared resources here.
     Session_Start     Called when a new client session starts. This method is
                       called once every time a new Web client session is
                       detected.
                       Put session initialization code here. For example,
                       developers usually initialize Session variables here.
     Session_End       Called when the client session ends.
     Application_Error Called when an unhandled error occurs in the Web
                       application.

     Fill up Application_Start, Session_Start and Session_End
     methods:

     Sub Application_Start _
     (ByVal sender As Object, ByVal e As EventArgs)
       'Fires when the application is started

       Application("noOfUniqueClients") = 0
       Application("noOfCurrentClients") = 0
       Application("timeAppStarted") = Now()
     End Sub

     Sub Session_Start _
     (ByVal sender As Object, ByVal e As EventArgs)
       'Fires when the session is started

      Dim unique As Integer = Application("noOfUniqueClients")
      Dim current As Integer = Application("noOfCurrentClients")
      unique += 1
      current += 1

      Application.Lock()
      Application("noOfUniqueClients") = unique
      Application("noOfCurrentClients") = current
      Application.UnLock()

       Session("timeSessionStarted") = Now()
     End Sub

     Sub Session_End _
     (ByVal sender As Object, ByVal e As EventArgs)
       'Fires when the session ends

      Dim current As Integer = Application("noOfCurrentClients")


www.mokhengngee.per.sg/book
                                                                                     89


     current -= 1

     Application.Lock()
     Application("noOfCurrentClients") = current
     Application.UnLock()
   End Sub

   Read through the codes and try to understand them. There are 3 variables in the
   Application object and 1 variable in the Session object in this application
   as shown in this table:
    Scope          Variable               Type         Description
    Application noOfUniqueClients         Integer      Number of unique client
                                                       sessions that have been
                                                       initiated since the
                                                       application started.
                   noOfCurrentClients     Integer      Number of clients with
                                                       their sessions still valid
                                                       currently.
                   timeAppStarted         DateTime Time when the
                                                       application started.
    Session        timeSessionStarted     DateTime Time when the current
                                                       session started.


3. Create a Web form to view these values

   Drag 4 Label controls from the Toolbar onto WebForm1.aspx:
    Control type    ID                Property values to be modified
    asp:Label       lb_statement1     -
    asp:Label       lb_statement2     -
    asp:Label       lb_statement3     -
    asp:Label       lb_statement4     -

   Fill in the Page_Load method in the Web form’s code-behind page:
   Private Sub Page_Load _
   (ByVal sender As System.Object, ByVal e As System.EventArgs)_
   Handles MyBase.Load
     'Put user code to initialize the page here
     Dim unique As String = _
       Convert.ToString(Application("noOfUniqueClients"))
     Dim current As String = _
       Convert.ToString(Application("noOfCurrentClients"))
     Dim sessionStartTime As String = _
       Convert.ToString(Session("timeSessionStarted"))
     Dim appStartTime As String = _
       Convert.ToString(Application("timeAppStarted"))

     lb_statement1.Text = _
       "There is/are " + unique + " unique client(s) so far."


                                                                   ASP.NET Workbook
90


       lb_statement2.Text = _
         "Of which " + current + " is/are currently online."
       lb_statement3.Text = _
         "Time this session started : " + sessionStartTime
       lb_statement4.Text = _
         "Time this app started : " + appStartTime
     End Sub


     What Page_Load does is simply to show the various variable values as the
     labels’ text.


4. Test your Web application

     Edit Web.config so that the session timeout is changed to 1 minute instead of
     the default 20 minutes. We will want sessions to time out quickly, so that we can
     observe the behavior of our application when a client session times-out.

     Open a new browser and test out WebForm1.aspx. Open another new browser
     and key in the same URL. Refresh the first browser, refresh the second browser.
     Go over to your friend’s machine and key in your application’s URL. Refresh the
     3 browsers and observe the values.

     Time out some clients (by not refreshing the page within 1 minute), then refresh
     the various clients again. Do your observations tally with what you have expected
     based on your understanding?

       Remember that refreshing a browser which has already timed-out will create a
     new session, and is considered a new unique client.


5. Use the Application_Error event handler

     Purposely introduce an error into your code by inserting an illegal statement in
     WebForm1.aspx’s code behind page. You can insert something such as
     Convert.ToDouble("test") in the Page_Load method. This statement
     will cause a runtime error because the string cannot be converted into a double
     value.

     View WebForm1.aspx with the introduced error in a browser, and notice that
     you will be shown ASP.NET’s default error page (which shows the exception
     stack).

     You might have noticed that global.asax has an Application_Error
     method, which will be called once there is a compilation or runtime error


www.mokhengngee.per.sg/book
                                                                                   91


   generated from any page within the Web application. Open global.asax again
   and fill in this method:

   Sub Application_Error _
   (ByVal sender As Object, ByVal e As EventArgs)
     'Fires when an error occurs
     Response.Redirect("err.html")
   End Sub


   You are instructing ASP.NET to redirect to an error page called err.html
   whenever some compilation or runtime error occurs.


6. Create the error page err.html.

   We now create the static HTML page err.html. Right click on your project’s
   name in Solution Explorer, select Add HTML Page, and type in err.html as the
   name of the new HTML file to generate.

   Simply insert a client-side label from the HTML section of the Toolbar and change
   the text inside to "An unexpected error has occurred". Try to view
   WebForm1.aspx again, and this time, instead of the default error page, the user
   will be redirected to err.html.

   This short exercise shows how we can use the Application_Error event
   handler in global.asax.



Exercise 4.4

Extracting Parameters from Web.config
Programmatically
In the previous exercises, you have already tried editing Web.config to set session-
related parameters. In this exercise, you see an example of how to put in key/value
pairs into this useful configuration file and programmatically read out these values.

Objective:
   • Learn how to use Web.config as a storage space for key/value pairs
   • Learn how to programmatically read such values programmatically.




                                                                    ASP.NET Workbook
92


Instructions:

1. Create a new Web form

     Create a new Web form in your current project, or a new ASP.NET Web
     application project. Pull out 2 TextBox controls from the Toolbar to get
     something like figure 4-14.




     Figure 4-14: Simple Web form with 2 textboxes.

     What we want to do is to edit Web.config to place in 2 key/value pairs. When
     the Web form loads, the Page_Load method will read out the values from
     Web.config, and display in the 2 Textbox controls.

2. Edit Web.config

     Open up Web.config, and insert an <appSettings> element with the
     key/value pairs. For this simple example (which simply tries to show a point), you
     can use the variable names mykey1 and mykey2.

     <?xml version="1.0" encoding="utf-8" ?>
     <configuration>

       <appSettings>
         <add key="mykey1" value="myvalue1" />
         <add key="mykey2" value="myvalue2" />
       </appSettings>
       ...
     </configuration>


3. Edit Page_Load to read from Web.config

     After saving Web.config, open up WebForm1.aspx.vb, and fill in the
     Page_Load method:

     Private Sub Page_Load _
     (ByVal sender As System.Object, ByVal e As System.EventArgs) _
     Handles MyBase.Load
       tb_value1.Text = ConfigurationSettings.AppSettings("mykey1")
       tb_value2.Text = ConfigurationSettings.AppSettings("mykey2")

www.mokhengngee.per.sg/book
                                                                                     93


   End Sub


      ConfigurationSettings.AppSettings is a convenient static/shared
   method which takes in the key name, and returns the corresponding value as read
   from Web.config as a string.

4. Test your Web form

   View your Web form in a browser, and check that myvalue1 and myvalue2
   appears in the 2 TextBoxes.

   With the Web form still showing in the browser, edit Web.config by replacing
   myvalue1 and myvalue2 with something else. Go back to the browser, and
   refresh the page; the new values should be reflected.

      Use Web.config for configurable parameters: As this short exercise has
   shown, Web.config is the place to place configurable parameters for your Web
   application. If you are writing a database application, variable parameters such as
   the connection string, path and file name of the database file etc can be placed
   here.



Exercise 4.5

Tracing your Web Application
ASP.NET has a trace feature which helps developers in debugging their Web
applications. In this exercise, we will explore the application-level trace facility
provided. You need to have completed exercise 4.1 since you will be using the forms
created there.

Objective:
   • Learn how to use ASP.NET’s trace facility for debugging

Instructions:


1. Edit Web.config

   Open up the StateWebApplication you created in exercise 4.1. Double click
   on Web.config in Solution Explorer to edit it.


                                                                     ASP.NET Workbook
94


     Scroll down Web.config until you see the <trace> element. Set the enabled
     value to "true". This will enable tracing for all Web pages in this Web
     application.

     <trace enabled="true" requestLimit="10" pageOutput="false"
     traceMode="SortByTime" localOnly="true" />

     Save Web.config.

2. Check if application-level tracing is working

     Let’s check out if the page-level trace facility is working. View 1stpage.aspx
     in a browser, fill in the TextBoxes in the form and click on the Submit button.
     Open up another IE window and type in the following in the Address field of your
     browser:
        http://localhost/StateWebApplication/Trace.axd

     This page shows each HTTP POST or GET request from clients since your Web
     application started, including useful information such as the time of request, HTTP
     status code returned, and the page (file) accessed (figure 4-12).




     Figure 4-12: trace.axd shows each request to your Web application.

        What is requestLimit? The <trace> element in Web.config has a
     requestLimit attribute which is set to 10 by default. This is the number of
     requests that will be traced when tracing is enabled. If there are more than 10
     requests, only the first 10 will be recorded and shown when you try to view
     Trace.axd.

     You can click on the [clear current trace] hyperlink, and start all over again, but
     the maximum number of requests that will be recorded is determined by the

www.mokhengngee.per.sg/book
                                                                                         95


   requestLimit value in Web.config. Tracing obviously requires server
   resources; do not increase the value of requestLimit to some large value
   unless it is necessary.


3. View more details of each trace

   Click on the ‘View Details’ hyperlink of the last request to view more information
   about the state of the server at that time.

   You should be able to see the Session and Application state (the variables
   stored with the Session and Application object). HTTP header information
   and query string (URL) variables are also other information that can be useful
   when troubleshooting your application (figure 4-13).




   Figure 13: View useful information about the state of the server after a particular
   request has been posted.




                                                                      ASP.NET Workbook
5: ADO.NET
We are now moving on to a very important part of ASP.NET: database access. The
“ADO” in “ADO.NET” stands for “ActiveX Data Object”, and works significantly
differently from the previous ADO version used in ASP 3.0. One major difference is
that with ADO.NET, developers usually deal with disconnected data sets; i.e. data
from the database is pulled down from the database management server (DBMS) and
cached locally. Any changes to this set of data will not be reflected in the actual
DBMS until an update is actually performed. Another significant difference is that
with ADO.NET, all communications between the DBMS and the database client (such
as your Web application) will be passed via XML. However, all the marshalling from
the DBMS into XML codes, and conversion back from XML codes back to objects in
the database client are transparently done.

In this chapter, we will first take a look at how to use the DataTable and the
DataGrid Web control, followed by examples on how to use the DataReader
class to read off a database table, and how to perform CRUD operations
programmatically.

There are 3 exercises in this chapter:
   • Exercise 5.1: Using the DataTable Class
   • Exercise 5.2: Reading from the Database and Using the DataReader
   • Exercise 5.3: Performing Simple CRUD Operations


Exercise 5.1

Using the DataTable Class
This exercise gets you familiar with the DataTable class which is often used in
database access codes. After populating this class with some rows and columns, you
will then associate it with a DataGrid control for display in a Web page.

Objectives:
   • Create a DataTable and populate it with data
   • Try out a DataGrid, and bind it to a DataTable




                                         96
                                                                                     97


Instructions:

1. Create a new project

   Create a new Web application project using VB.NET and rename
   WebForm1.aspx to UsingDataGrid.aspx. In the Design View of
   UsingDataGrid.aspx, drag a DataGrid control from the Web panel of the
   Toolbox.

   We are going to create a DataTable object, fill in the rows and columns of this
   DataTable, and then bind it to the DataGrid that we have pulled out from the
   Toolbox. If you view this control’s properties, you will realise that the default ID
   given is DataGrid1.


2. Write code for Page_Load

   Open up the code-behind file UsingDataGrid.aspx.vb and fill in the
   Page_Load method:

   Private Sub Page_Load _
   (ByVal sender As System.Object, ByVal e As System.EventArgs)_
   Handles MyBase.Load

        Dim dr As DataRow
        Dim dt As New DataTable

        dt.Columns.Add("Id")
        dt.Columns.Add("Name")

        dr = dt.NewRow
        dr(0) = "01"
        dr(1) = "Peter Lim"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr(0) = "02"
        dr(1) = "Alex Liaw"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr(0) = "03"
        dr(1) = "Fatimah Annadi"
        dt.Rows.Add(dr)

       DataGrid1.DataSource = dt
       DataGrid1.DataBind()
     End Sub




                                                                      ASP.NET Workbook
98



        Of DataTables and DataGrids: You can view a DataTable as a data
     structure for holding rows and columns. Assuming that dt is a variable which
     refers to an instance of a DataTable, you can insert a new column like this:
        dt.Columns.Add("new column name")
     You can insert a new row to the table like this:
        dt.Rows.Add(dr)
     where dr is an instance of a DataRow.

     A DataGrid is a display control which you can associate with a DataTable by
     assigning its DataSource property to the DataTable (as in
     DataGrid1.DataSource = dt).

     Read and try to understand the code which you have just placed into Page_Load.
     View UsingDataGrid.aspx in a browser. You should see something like
     figure 5-1.




     Figure 5-1: DataGrid showing DataTable contents.

         Must call DataBind: Associating the DataGrid with a data source such as
     a DataTable is not enough; it is important to call the DataGrid’s
     DataBind() method. If your DataGrid does not show up, check to see if you
     have called the DataGrid’s DataBind method.


3. Check out other properties of the DataGrid

     Go back to the Design View of UsingDataGrid.aspx. Select the DataGrid
     control and view its properties. Experiment with properties such as BackColor,
     BorderColor, BorderStyle, BorderWidth, CellPadding and
     CellSpacing. View the page in a browser again to check if any changes to
     these properties are reflected.




www.mokhengngee.per.sg/book
                                                                                     99


4. Display the contents of a folder in a DataGrid

   Let’s do something more challenging. You can write a new Web form which reads
   the directory contents of C:\ on your local hard disk, place the contents into a
   DataTable, then display the DataTable in a DataGrid.

   Add a new Web form into the current project and call it
   ViewContentsOfRoot.aspx. Drag a DataGrid control from the Toolbar to
   the page and modify its properties if you want to.

   Open its code-behind page, and insert this Imports statement at the top of your
   ViewContentsOfRoot.aspx.vb file:
     Imports System.IO
   This is necessary because the FileInfo and DirectoryInfo classes which
   will be used in your Page_Load method are in the System.IO namespace.

   Fill in the Page_Load method of ViewContentsOfRoot.aspx.vb:

   Private Sub Page_Load _
   (ByVal sender As System.Object, ByVal e As System.EventArgs) _
   Handles MyBase.Load

     Dim   dr As DataRow
     Dim   fi As FileInfo
     Dim   dir As New DirectoryInfo("C:\")
     Dim   dt As New DataTable

     dt.Columns.Add("FileName")
     dt.Columns.Add("Size")

     For Each fi In dir.GetFiles()
       dr = dt.NewRow
       dr(0) = fi.Name
       dr(1) = fi.Length
       dt.Rows.Add(dr)
     Next

     DataGrid1.DataSource = dt
     DataGrid1.DataBind()

   End Sub

   View the page in a browser. You should see something like figure 5-2 showing the
   names and sizes of files in C:\. Read and understand the codes you have written.




                                                                     ASP.NET Workbook
100




      Figure 5-2: Viewing the files in C:\ in a Web form.

      This ends our mini-experiment with DataTables. We will learn how to read
      from a real database in the next exercise.



Exercise 5.2

Reading from the Database and Using the DataReader
Class
This exercise shows an example of how your Web application can read from a
database table using a DataReader class, and show the information in a DataGrid
for display in your Web page.

We need to create a database in Microsoft Access first. Here are the steps to create a
database file called db1.mdb in C:\TEMP. This database will contain 1 table called
StudentInfo. StudentInfo has the following columns: StudentId (primary
key), Name, Address, Email, and Tel. To keep things easy, all columns will be of
the text type.

Instructions to create the sample database for this exercise:

(i)      Start up Microsoft Access. Select New Blank Database. Type in
         c:\temp\db1.mdb as the name and location of the Access database file
         when prompted to enter a new file name (figure 5-3). Click on the Create
         button.



www.mokhengngee.per.sg/book
                                                                                        101




        Figure 5-3: creating a new Access database file called db1.mdb.

(ii)    Double-click on ‘Create Table by Design View’ (figure 5-4).




        Figure 5-4: Create a new table in Design View.

(iii)   Type in the field names and select ‘Text’ as the type for all fields as (figure 5-
        5).




                                                                         ASP.NET Workbook
102




       Figure 5-5: Specifying column (field) names and types in Design View.

(iv)   Right-click on the StudentId row and select ‘Primary Key’ to make the
       StudentId the primary key of this table (figure 5-6). The primary key will
       always be unique – in the same way, there shouldn’t be 2 students sharing
       identical StudentIds.




       Figure 5-6: Make StudentId the primary key of the table.

(v)    Select File Save from the menu bar. Because this is the first time you are
       saving this table, a dialog box pops up to ask you for a name for this table.
       Type in StudentInfo and click OK (figure 5-7).




www.mokhengngee.per.sg/book
                                                                                   103




        Figure 5-7: Giving your table a name.

        What you have just done is to create a new database table called
        StudentInfo with 5 columns (or fields) in the db1.mdb file. Now, you
        need to populate the table with sample data.

(vi)    Close the StudentInfo table and double-click on the StudentInfo table
        name to enter data (figure 5-8).




        Figure 5-8: Double-click on the table to enter sample data.

(vii)   Enter some sample data like that shown in figure 5-9.




                                                                      ASP.NET Workbook
104




         Figure 5-9: Enter some sample data into the StudentInfo table.

(viii) Select File Save and close the Access database. We now have an Access
       database to read from.


Now that we have the sample database to experiment with, we shall proceed to write a
simple Web form with a DataGrid control. When this page loads, the Page_Load
method opens a database connection to c:\temp\db1.mdb and reads out all the
data in the StudentInfo table. This data is returned in a DataReader object. We
then associate this DataReader object with the DataGrid, so that the user can
view it in a Web page.


Objective:
   • Write a simple Web application which reads off a table in an Access database
      file and display the data in a Web form

Instructions:

1. Create a new project

      Create a new Web application project or if you still have the previous Web
      application project open, you can add a new Web form to the same project.
      Rename your Web form to UsingDataReader.aspx.

      What you are going to do next is to place a DropDownList control on the Web
      form. When the page loads, codes in the Page_Load method will open a
      database connection to db1.mdb and read in each student’s StudentId and
      Name, and add each row as a single string to the DropDownList.




www.mokhengngee.per.sg/book
                                                                                   105


2. Insert controls to your Web form

   Drag a DropDownList and a Label control from the Toolbar’s Web Forms
   section to UsingDataReader.aspx in Design View. You may rename them,
   but the example in this exercise will retain their default IDs (i.e.
   DropDownList1 and Label1 respectively). Label1 will display messages to
   the user, so set its Text property to blank in Design View (figure 5-8).




   Figure 5-8: DropDownList and Label controls in
   UsingDataReader.aspx.


3. Write the Page_Load and Read_DataBase methods

   Open the code-behind file (UsingDataReader.aspx.vb) and edit the
   Page_Load method:

   Private Sub Page_Load _
   (ByVal sender As System.Object, ByVal e As System.EventArgs) _
   Handles MyBase.Load
     If Not Page.IsPostBack Then
       Read_DataBase()
     End If
   End Sub


   When UsingDataReader.aspx loads, it will check if this is a ‘first post’ or a
   ‘post back’ (meaning the user arrived at this page again after submitting from the
   same page). If it’s a ‘first post’, the Read_DataBase() method is called.

      We are assuming that the StudentInfo table doesn’t change when the user
   reads this Web form. That’s why the Page_Load method does not re-read the
   table when there it is a PostBack. This assumption may not be true for some real
   applications.

   Insert this statement at the top of the code-behind file:
      Imports System.Data.OleDb




                                                                     ASP.NET Workbook
106


      We will be making use of classes such as OleDbConnection,
      OleDbCommand and OleDbDataReader which are in this
      System.Data.OleDb namespace.

      Read_DataBase() basically reads the StudentInfo table in db1.mdb and
      populates the DropDownList control. Insert this method into the code-behind
      file:
      Private Sub Read_DataBase()
        Dim cnn As New OleDbConnection _
          ("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\temp\db1.mdb")
        Dim strSQL As String = "SELECT StudentId, Name FROM StudentInfo"
        Dim cmd As New OleDbCommand(strSQL, cnn)
        Dim dr As OleDbDataReader

        Try
          cnn.Open()
          dr = cmd.ExecuteReader()

          Do While dr.Read
            Dim toDisplay As String = _
               dr("StudentId").ToString() + ":" + dr("Name")
            DropDownList1.Items.Add(toDisplay)
          Loop
        Catch ex As Exception
          Label1.Text = ex.Message
        Finally

          If Not cmd Is Nothing Then
            cmd.Dispose()
          End If

          If Not dr Is Nothing Then
            dr.Close()
          End If

          If Not cnn Is Nothing Then
            cnn.Close()
            cnn.Dispose()
          End If
        End Try
      End Sub



4. Test your Web form

      View UsingDataReader.aspx in a browser and if nothing goes wrong, the
      DropDownList will be populated with each row of StudentId and Name from
      the StudentInfo table. If something goes wrong (such as if the db1.mdb file
      couldn’t be found), an exception occurs, and the exception message appears as the
      text of Label1 (figure 5-10).




www.mokhengngee.per.sg/book
                                                                                    107




  Figure 5-9: DropDownList populated from the database.




  Figure 5-10: Exception message shown as text of Label1 if db1.mdb couldn’t
  be found.


5. Understand the codes in Read_DataBase()

  It is important to understand how the Read_DataBase method works.

    Dim cnn As New OleDbConnection _
      ("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\temp\db1.mdb")


  The first line above declares a connection object (OleDbConnection) and
  creates a new instance of this connection object by passing in the connection
  string. Notice that the connection string for Access databases looks like this:
     "Provider=Microsoft.Jet.OLEDB.4.0;
     Data Source=c:\temp\db1.mdb"
  The exact location of the Access database file is specified in the connection string.

      Use Web.config for connection strings. In real development projects, it is
  bad practice to hard-code ‘potentially changeable’ strings such as the connection
  string. They should be placed in easily configurable files such as Web.config
  and retrieved dynamically from the code. Placing such changeable strings in
  Web.config enables it to be changed easily without the need to recompile your
  codes.




                                                                      ASP.NET Workbook
108



         Using the Server.MapPath method. As far as simple proof-of-concept Web
      applications which involve an Access database file are concerned, it might be a
      good idea to save the database file in the same folder as your Web application (i.e.
      in c:\inetpub\wwwroot\<project folder>). This is very convenient
      when you need to copy the whole Web application from 1 PC to another; there is
      no need to search for the database file which is in another folder, and copy it over
      separately to the new PC.

      You can use the Server.MapPath method in your program which returns the
      current folder in which the Web application is found. For example, assuming that
      the current application’s project folder is WebApplication1Server, the
      expression MapPath("db1.mdb") will return the string
      "c:\inetput\wwwroot\WebApplication1\db1.mdb".

          Different connection strings for different database providers. The connection
      string for Microsoft SQL server or other DBMS servers will look different. For
      example, the connection string for SQL server 2000 may look like this:
        User Id=sa;Password=password;
        Initial Catalog=Northwind;Server=.
      This connection string is used to open the Northwind database running on the SQL
      Server on the local machine with the specified user Id and password.


        Dim strSQL As String = "SELECT StudentId, Name FROM StudentInfo"


      The statement above declares strSQL as a string containing the SQL SELECT
      statement. This SELECT statement selects the StudentId and Name fields from
      the StudentInfo table. strSQL will be used later.
        Dim cmd As New OleDbCommand(strSQL, cnn)

      The statement above declares a new command object (OleDbCommand) by
      passing into the constructor the SQL Select string and the connection object. After
      this statement, we are ready to run the SQL command since it is already associated
      with a database connection, and a SQL statement.
        Dim dr As OleDbDataReader


      The statement above declares a DataReader object (OleDbDataReader). This
      variable (dr) will be used to reference the data that gets returned when the cmd
      object is executed.

      Study the next code fragment:
        Try
          cnn.Open()
          dr = cmd.ExecuteReader()


www.mokhengngee.per.sg/book
                                                                                   109


    Do While dr.Read
      Dim toDisplay As String = _
        dr("StudentId") + ":" + dr("Name")
      DropDownList1.Items.Add(toDisplay)
    Loop
    ….
  End Try

It is common practice to place statements that actually execute the database
command within a Try block because it is likely that an exception may be issued
(such as when the database server is down). The connection object is first opened
(by calling its Open() method). Then the executeReader() method of the
command object is called. This method returns the results from the SELECT
statement (which is a collection of rows) as a DataReader object which we store
in the variable dr.

Following this, we use a Do While loop to loop through each row in the
DataReader object. dr.Read returns false if there is nothing else in the
DataReader object. Otherwise, the statements in the Do While loop
constructs a display string and inserts it into the DropDownList control.

The following expression returns the StudentId value of the current row in the
DataReader:
   dr("StudentId")
Similarly, the following expression returns the Name value of the current row in
DataReader:
   dr("Name")


   Retrieving field values from DataReader: Instead of
dr("StudentId")and dr("Name"), you could have used the expressions
dr(0) and dr(1) instead. dr(0) returns the value of the first field, while
dr(1) returns the value of the second field. In fact, using the number is more
efficient than the field name. The obvious disadvantage is that using numbers is
less intuitive and it is much easier to make mistakes.

Let’s take a look at the catch block:

  Catch ex As Exception
    Label1.Text = ex.Message

The catch block simply prints out the exception object’s message as Label1’s
Text. (No rocket science here.)

The finally block is important; remember that the finally block is always executed
regardless of whether an exception occurs or not.
  Finally

                                                                  ASP.NET Workbook
110



          If Not cmd Is Nothing Then
            cmd.Dispose()
          End If

          If Not dr Is Nothing Then
            dr.Close()
          End If

          If Not cnn Is Nothing Then
            cnn.Close()
            cnn.Dispose()
          End If
        End Try

      In the finally block, we:
          • call the Dispose method of the command object (if it has been created),
          • call the Close method of the DataReader object (if it has been created),
          • call the Close and Dispose methods of the connection object (if it has
              been created).

          Closing connections: You should always close all database connections after
      you are done with them. Database connections are precious resources, and not
      closing them may result in an unused open connection. As a general rule, you
      should also call the Dispose methods of the command object after you are done
      with it. You must also close the DataReader, otherwise the connection
      providing data will be busy.

            More about the DataReader class: The DataReader class is a fast and
      efficient way to retrieve data from a database table for reading only. You cannot
      perform updates, insertions or deletions via a DataReader (you can use a
      DataAdapter for CRUD operations).

      The DataReader is analogous to a forward-only, read-only, server-side record
      set. You use it to retrieve 1 row at a time from the data source, and you can only
      move through the data 1 row at a time. This data is not cached on the client side,
      and will be lost when the next row is retrieved from the database server.




                 Making the DropDownList more useful

      Let’s make the DropDownList more useful. You are going to enhance
      UsingDataReader.aspx so that when the user selects a different student from
      the DropDownList, it’s going to execute an event handler which will change the
      Text of Label1.
www.mokhengngee.per.sg/book
                                                                                      111



In Design View of UsingDataReader.aspx, double click on the
DropDownList control. You will be brought to the
DropDownList1_SelectedIndexChanged method – this is the event
handler that will run when the user selects s different item in the drop down list.

Type in the statement below in this event handler.

Private Sub DropDownList1_SelectedIndexChanged _
(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles DropDownList1.SelectedIndexChanged
  Label1.Text = "You have selected " + _
    DropDownList1.SelectedValue
End Sub

You need to do another thing before this works: go to Design View again, and
view the properties of the DropDownList control. Change its AutoPostBack
property from false to true.

   What is AutoPostBack? When the AutoPostBack property is set to true,
there will be a HTTP post back to the same Web form when the user selects a
different item from the DropDownList control. If you are interested in how it
works, take a look at the HTML source code generated by ASP.NET for you when
AutoPostBack is true. Of course, don’t set this property to true unless you
need dynamic response (which you put into the event handler for the
DropDownList) when the user changes the selected item.

Check out your page again in a Web browser.



           Further Exercise

Create a new table called StudentScore in the same database file (db1.mdb).
The StudentScore table stores each student’s semester scores. Figure 5-11
gives an example of how StudentScore can look like.




                                                                    ASP.NET Workbook
112




      Figure 5-11: The StudentScore table containing 3 scores for each student’s
      Quiz, Project and Examination.

      Modify your Web form such that when the user selects a particular student from
      the DropDownList, the event handler opens a database connection to the
      StudentScore table and selects the Quiz, Project and Exam scores for that
      particular student. These scores are then displayed on the same Web form in a
      DataGrid control.

      Hints:

         • Here is a SQL SELECT statement to retrieve the scores for the student with
           StudentId of 2:
                SELECT Quiz,Project,Exam FROM StudentScore WHERE
                StudentId = "2"

         • The DataGrid’s DataSource can also be set to a DataReader, not
           necessary a DataTable (which you did in exercise 5.1). Assuming that
           dr refers to a DataReader object, the following is perfectly fine:
                DataGrid1.DataSource = dr
                DataGrid1.DataBind()




Exercise 5.3

Performing Simple CRUD Operations
In this exercise, you will write a simple CRUD (Create, Read, Update, Delete) Web
application which reads, updates, inserts and deletes rows from the StudentInfo
table which you have created for the previous exercise. You need to have the
StudentInfo Access table from the previous exercise ready.

Objective:

www.mokhengngee.per.sg/book
                                                                                     113


   • Write codes to INSERT, UPDATE and DELETE rows of a database table
     using the Command class

Instructions:

1. Create a new Web form

   Create a new Web form in your current project, or in a new project and rename it
   SimpleCrud.aspx. Add the server controls to the Web form and change the
   (ID) property and other control property values as indicated in the following
   table:

    Control type            ID                  Property values to be modified
    asp:TextBox             tb_name             -
    asp:TextBox             tb_email            -
    asp:TextBox             tb_tel              -
    asp:TextBox             tb_address          -
    asp:DropDownList        ddl_studentId       AutoPostBack: true
    asp:Button              bn_delete           Text: Delete
    asp:Button              bn_update           Text: Update

   The Web form should look like figure 5-12.




   Figure 5-12: Design View of SimpleCrud.aspx.


2. Insert data controls to the Web form

   From the Data section of the Toolbox, drag out an OleDbConnection control
   to your Web form. It will be relocated to the bottom of your form since it is not a

                                                                      ASP.NET Workbook
114


      Web control. Also drag 2 OleDbCommand controls to the same Web form (figure
      5-13).




      Figure 5-13: Data controls associated with this Web form appear at the below it.

      You can rename these Data controls by right-clicking on the icons, selecting
      properties, and changing the (Name) property. (For the screen shots in this
      exercise, the default names are used, though you should really choose a more
      relevant name for all your objects in real projects.)


3. Set the OleDbConnection’s properties

      Select the OleDbConnection1 object and view its property window. Select
      <New Connection…> for the ConnectionString property (figure 5-14).




      Figure 5-14: Setting the ConnectionString property of the
      OleDbConnection object



www.mokhengngee.per.sg/book
                                                                                 115


The DataLink Properties window pops up with the ‘Connection’ tab as the active
tab by default. Select the ‘Provider’ tab instead (figure 5-15). By default, the
Provider has been set to ‘Microsoft OLE DB Provider for SQL Server’. Since you
are using an Access database for this exercise, you should select ‘Microsoft Jet 4.0
OLE DB Provider’ (this is the database provider for the Access database).




Figure 5-15: Use Microsoft Jet 4.0 OLE DB Provider if you are using Microsoft
Access as your database.

Click on the ‘Next’ button or the ‘Connection’ tab, to go to the ‘Connection’ tab.
You will realise that this time, the Connection pane looks different compared to
when the ‘Microsoft OLD DB Provider for SQL Server’ had been selected in the
‘Provider’ pane. Different database providers will require different connection
parameters.

Enter the path and name of db1.mdb and click on the ‘Test Connection’ button.
You do not have to enter a user name or password for this Access database,
because this database is not protected via a user name and password (figure 5-16).




                                                                   ASP.NET Workbook
116




      Figure 5-16: Test the database connection here

      When the ‘Test Connection’ button is clicked, a window should pop up to notify
      that the connection is successful. What this ‘Test Connection’ does is to check if
      the database file specified actually exists, and whether it can be opened using the
      specified connection parameters (user name and password).

      Click on the OK button. A window pops up to inform that the password specified
      is saved as clear text and is readable in the source codes. For our exercise, since
      user names and passwords are not required to open our database, it really doesn’t
      matter. Click on either the ‘Include Password’ or ‘Don’t Include Password’ button.


4. Set the properties of the OleDbCommand objects

      Select the OleDbCommand1 icon on the Web form and view its properties. Set
      the CommandText property to ‘SELECT * FROM STUDENTINFO’, and the
      Connection property to OleDbConnection1 (figure 5-17).

      Select the OleDbCommand2 icon on the Web form and view its properties. Leave
      the CommandText property blank (you will be programmatically setting the
      CommandText property later), but set its Connection property to
      OleDbConnection1, as you did in the previous step.




www.mokhengngee.per.sg/book
                                                                                   117




  Figure 5-17: Setting the OleDbCommand object’s properties.


5. Write code for the Page_Load method

  Now that we have all the necessary objects, it’s time to write the event handlers.

  Open up SimpleCrud.aspx.vb and insert into the Page_Load method the
  following:

  Private Sub Page_Load _
  (ByVal sender As System.Object, ByVal e As System.EventArgs)_
  Handles MyBase.Load
    If Not IsPostBack Then
      LoadAndShowData()
    End If
  End Sub


  When the form loads for the first time, the LoadAndShowData() method will
  be invoked. This method, which you will write in the next step, reads the
  StudentInfo table and displays the values on the Web form.


6. Write code for the LoadAndShowData method

  Insert the LoadAndShowData method:

  Private Sub LoadAndShowData()
    'clear drop down list first
    ddl_studentId.Items.Clear()

    Dim reader As OleDbDataReader
    OleDbConnection1.Open()
    reader = OleDbCommand1.ExecuteReader()

    Dim firstRow As Boolean = True
    While reader.Read()
      ddl_studentId.Items.Add(New ListItem(reader(0).ToString))


                                                                     ASP.NET Workbook
118


          If firstRow Then
            tb_name.Text = reader("Name").ToString
            tb_address.Text = reader("Address").ToString
            tb_tel.Text = reader("Tel").ToString
            tb_email.Text = reader("Email").ToString
            firstRow = False
          End If
        End While
        reader.Close()
        OleDbConnection1.Close()
      End Sub


      Read and try to understand what LoadAndShowData does.


7. Write the event handler for the DropDownList

      Double click on the DropDownList on the Web form; this will bring you to the
      event handler for ddl_studentId. This method will run when there is a change
      in the selected index.

      Fill in the event handler:

      Private Sub ddl_studentId_SelectedIndexChanged _
      (ByVal sender As System.Object, ByVal e As System.EventArgs)

        Dim studentId As String = ddl_StudentId.SelectedItem.Text
        OleDbCommand2.CommandText = _
          "SELECT * FROM STUDENTINFO WHERE STUDENTID='" + _
          ddl_StudentId.SelectedItem.Text + "'"

        OleDbConnection1.Open()

        Dim reader As OleDbDataReader
        reader = OleDbCommand2.ExecuteReader(CommandBehavior.SingleRow)

        If reader.Read() Then
          tb_name.Text = reader("Name")
          tb_address.Text = reader("Address")
          tb_email.Text = reader("Email")
          tb_tel.Text = reader("Tel")
        End If

        reader.Close()
        OleDbConnection1.Close()

      End Sub



8. Test your Web form

      So far, you have written all the code except for the event handlers for both the
      Update and Delete buttons. You can check out if the DropDownList works first.

www.mokhengngee.per.sg/book
                                                                                 119


   View SimpleCrud.aspx in a browser. The Web form should load with the
   DropDownList containing all the student IDs in the StudentInfo table, with
   the first student’s particulars displayed (figure 5-18).




   Figure 5-18: Dynamic student data read from the StudentInfo table is
   displayed.

   Select a new student ID from the DropDownList and you should see the Web form
   refreshed with the selected student’s particulars.


9. Write the event handlers for the Update and Delete buttons

   It’s time to make your Update and Delete buttons work. Double click on both the
   Update and Delete buttons in Design View and fill in the code for each button’s
   event handler:

   'Event handler for Update button click
   Private Sub bn_update_Click _
   (ByVal sender As System.Object, ByVal e As System.EventArgs)_
   Handles bn_update.Click

     Dim strSQL As String = _
       "UPDATE STUDENTINFO SET NAME='" + _
       tb_name.Text + "',ADDRESS='" + _
       tb_address.Text + "',TEL='" + _
       tb_tel.Text + "',EMAIL='" + _
       tb_email.Text + _
       "' WHERE STUDENTID='" + ddl_studentId.SelectedItem.Text + "'"

     OleDbConnection1.Open()
     Dim cmd As New OleDbCommand(strSQL, OleDbConnection1)
     cmd.ExecuteNonQuery()
     OleDbConnection1.Close()
   End Sub

   'Event handler for Delete button click
   Private Sub bn_delete_Click _
   (ByVal sender As System.Object, ByVal e As System.EventArgs)_
   Handles bn_delete.Click


                                                                   ASP.NET Workbook
120



        Dim strSQL As String = _
          "DELETE FROM STUDENTINFO WHERE STUDENTID='" + _
          ddl_StudentId.SelectedItem.Text + "'"
        OleDbConnection1.Open()
        Dim cmd As New OleDbCommand(strSQL, OleDbConnection1)
        cmd.ExecuteNonQuery()
        OleDbConnection1.Close()

        LoadAndShowData()
      End Sub

      Read and try to understand what the event handlers do.


10. Test your Web form again

      View SimpleCrud.aspx in a browser. Select one student from the
      DropDownList, and make changes to one of his particulars. Click on the Update
      button. To verify that actual changes have been made to the table, open up
      db1.mdb using Access and check that the changes have indeed been made.

      Select one student and click on the Delete button. The form will refresh and show
      the first student’s particulars again. Similarly, open the table using Microsoft
      Access to verify that a delete has indeed been performed.

      Congratulations! You have successfully written a simple Web application which
      can read, update and delete rows from an actual database table.




              Further Exercise

SimpleCrud is a very simple Web application which isn’t very robust. Improve
your application by:

      • Adding in exception handlers for the database access codes. In the event of an
        SQL exception or any database exception, you might want to show an error
        message to the user.

      • Add an Insert Web form whereby users can insert a new student’s particulars
        into the StudentInfo table. Take note that student ID is a primary key, and
        it is illegal to perform a SQL INSERT statement with a duplicate student ID
        field. Think about how your application should deal with situations whereby
        the user tries to enter a new student with duplicate student IDs.


www.mokhengngee.per.sg/book
                                                            121


The SQL INSERT statement can look like this:

      INSERT INTO StudentInfo
      (StudentID, Name, Address, Email, Tel)
      VALUES ('99 ', 'Kristen Wong', '180 Ang Mo Kio Ave 8',
      'kristen@kristenwong.per.sg ', '65501654')




                                               ASP.NET Workbook
6: Web Services
Web services are largely popular today, and as related specifications become more
stable, we should be expecting Web services to be used universally for inter-server
communications. The main reason why Web services has a great chance to succeed as
the de facto remote method invocation standard is because almost every major player
in the IT market (including Microsoft, IBM, Sun Microsystems) support these
specifications.

In this chapter, you will learn to how to create and expose a public method as a Web
service to the network, and how to consume a Web service as a client.

There are 4 exercises in this chapter:
   • Exercise 6.1: Creating a Web Service Provider
   • Exercise 6.2: Creating a Web Service Consumer
   • Exercise 6.3: Consuming Web Services from Google (optional)
   • Exercise 6.4: Consuming Web Services from Amazon (optional)



Exercise 6.1

Creating a Web Service Provider
Objective:
   • Write an application with a method which returns the latest stock index, and
      expose this method as a Web service.

Instructions:

1. Create a new Web service project

   Select File New Project from VS.NET’s menu bar. Select ‘Visual Basic
   Project’ from the ‘Project Types’ panel on the left, and ‘ASP.NET Web Service’ on
   the ‘Templates’ panel on the right (figure 6-1).

   In the Location field, type in
   http://localhost/<something>WebService, whereby
   <something> may be one of the following Stock market indexes:
          • STI (Straits Times Index)
          • HSI (Hang Seng Index)
          • KLSE (Kuala Lumpur Composite Index)

                                         122
                                                                                  123


      • N225 (Nikkei 225 Index_
      • NYSE (New York Stock Exchange)
      • GSPC (United States S&P 500)
      • NASDAQ (Nasdaq Composite)
Choose a different stock index from your friends, so that you can consume their
Web services in the next exercise.




Figure 6-1: Creating a new ASP.NET Web service project

Instead of WebForm1.aspx, VS.NET will create Service1.asmx. And
Service1.asmx does not have a visual interface, unlike Web forms (figure 6-
2).

Right-click on Service1.asmx in Solution Explorer, and select Rename.
Change the name of your Web service to UpdateService.asmx.




Figure 6-2: Service1.asmx in Design View.


                                                                 ASP.NET Workbook
124



2. Look at an example of a Web method

      You are now going to add code into UpdateService.asmx.vb. Click on the
      blue ‘hyperlink’ ‘click here to switch to code view’ in the Design View of
      UpdateService.asmx.vb.

      In the code view, you will see that a class called Service1 has been created for
      you. For now, Service1 is an empty class. There are some commented codes
      containing a Web service example called HelloWorld in Service1. Study it
      now:

         <WebMethod()> Public Function HelloWorld() As String
           Return "Hello World"
         End Function

      The above statements define a public method called HelloWorld which takes in
      no parameters and returns a String ("Hello World") when invoked. To
      expose this method as a Web method in VB.NET, all you have to do is to prepend
      <WebMethod()> as part of the method declaration. Without <WebMethod()>
      in front, HelloWorld will just be a common public method in the class.

         Functions vs. Subroutines in VB.NET: If you are observant enough, you will
      have realised that HelloWorld is a Function – as opposed to a Sub(routine) which
      you have been writing in your Web forms so far. Most languages such as C, C#,
      C++, J# and Java do not differentiate between subroutines and functions the way
      VB 6 and VB.NET do (they are all known as either ‘functions’ or ‘methods’.)
      However, in VB, a function returns a value, unlike a subroutine which cannot
      return a value. HelloWorld returns a string, and hence must be declared with the
      Function keyword instead of Sub.

         Web methods in C# and J#:
      In C#, we expose a public method as a Web method using a C# attribute instead.
      Here is an example:
        [WebMethod]
        public string HelloWorld(){
          return "Hello World";
        }
      In J#, we use a JavaDoc comment:
        /** @attribute WebMethod() */
        public String HelloWorld(){
          return "Hello World";
        }




www.mokhengngee.per.sg/book
                                                                                        125


3. Write the business code for GetStockIndex

   Write a Web method called GetStockIndex which returns an integer (the stock
   index value of your Index). To keep this exercise really simple, you can use a
   random number generator to determine the latest index value:

   <WebMethod()> _
   Public Function GetStockIndex() As Integer
     Dim r As Random = New Random
     Dim i As Integer = r.Next(500) + 500
     Return i
   End Function

   The GetStockIndex method above returns 500 + a random number between 0
   and 499 (inclusive) as the latest stock index value.

       Going public? Web methods must be declared with the Public modifier: it is
   important to remember that regardless of which .NET language you use, Web
   methods must be declared as public methods. Otherwise, if you use any other
   accessibility modifier, the class will compile, but the Web method will not be
   available for consumption by the Web service client.

      Multiple Web methods: It is possible to have as many Web methods as you
   want in your class. You can also have other non public common methods which
   your Web methods may invoke. However, we will stick to 1 Web method in this
   exercise – feel free to experiment yourself.


4. Check if your Web service works

   Save your class (correct any compilation errors if there are any) and it’s time to
   check out whether your Web method works. Like most other Web service tools,
   VS.NET provides a way for testing if the Web services hosted on a machine are
   working as expected.

   Back in Solution Explorer, right-click on UpdateService.asmx and select
   View in Browser. VS.NET opens a Web interface for testing the Web services
   hosted (figure 6-3). All the available Web methods are shown on the page as
   hyperlinks. In this exercise, since only the GetStockIndex method has been
   exposed as a Web method, that’s the only one we see in figure 6-3.




                                                                      ASP.NET Workbook
126




      Figure 6-3: Checking out the available Web methods.

      Click on the GetStockIndex hyperlink on the Web test page. You will be
      shown very useful information on the SOAP packets that will be generated by this
      Web method (figure 6-4).

         Input parameters for the Web method: In our exercise, our GetStockIndex
      method doesn’t take in any parameters. If you write a Web method that takes in 1
      or more parameter, you should be able to see fields for entering these parameter
      values above the Invoke button in figure 6-4.




www.mokhengngee.per.sg/book
                                                                                 127




Figure 6-4: SOAP packets that will be generated for your Web method are shown.

Click on the Invoke button to see what this method will return. You should see
something like figure 6-5, except that the random integer returned will be different.
This integer value will be ‘embedded’ into the SOAP packet’s
<GetStockIndexResult> element (in the second SOAP message in figure 6-
4).




                                                                   ASP.NET Workbook
128




      Figure 6-5: The SOAP packet that gets returned will have the int value replaced
      with 928.


5. View the WSDL file

      Hit the backspace key until you get back to the screen in figure 6-3 (or right-click
      on UpdateService.asmx and select View in Browser in Solution Explorer
      again). Click on the Service Description ‘hyperlink’ instead of the GetStockOption
      ‘hyperlink’ this time. This will lead you to the WSDL file which you need to
      provide to Web service clients for consuming your Web service (figure 6-6).




      Figure 6-6: Viewing your WSDL file.

        Viewing the WSDL file: Another way to view your WSDL file is just to append
      ?WSDL after the URL pointing to your asmx file. For example, in this exercise,
      you can view the WSDL file directly by entering
      http://localhost/STIService/Service1.asmx?WSDL in a browser.

      Take note of the URL which displays your WSDL file (shown circled in figure 6-
      6). This is the URL which you need to record down and give to your friends who
      need to consume your GetStockIndex Web service. (If your URL shows
      http://localhost... , you need to give your friends your IP address too, so
      that they can replace localhost with your actual IP address in the URL.)
www.mokhengngee.per.sg/book
                                                                                        129



   That’s all – isn’t it easy? Your Web service should be ready for consumption by
   Web service clients. In the next exercise, you shall write a Web service client to
   consume this GetStockIndex Web service method.



Exercise 6.2

Creating a Web Service Consumer
In this exercise, you will be writing an ASP.NET Web application that consumes the
Web service which you and your friends have generated in the previous exercise, and
invoke the GetStockIndex Web method to obtain the results.

You need to have completed the previous exercise before continuing.

Objective:
   • Learn how to write a Web service consumer Web form

Instructions:

1. Create a new Web application project

   Select File New Project from VS.NET’s menu bar. Select ‘Visual Basic
   Project’ from the ‘Project Types’ panel on the left and ‘ASP.NET Web
   application’ from the ‘Templates’ panel on the right. In the Location field, type in
   http://localhost/StockIndexDisplay.

   Rename your default Web form from WebForm1.aspx to
   StockDisplay.aspx.

   Add the server controls to the Web form and change the (ID) property and other
   control property values as indicated in the following table:

    Control type         ID               Property values to be modified
    asp:TextBox          tb_sti           -
    asp:Button           bn_update        Text: Update
    asp:Label            lb_msg           ForeColor: Red
                                          Text: (blank)

   Insert in the labels (from the HTML pane of the Toolbox) so that the final Web
   form looks like figure 6-7.

                                                                      ASP.NET Workbook
130




      Figure 6-7: When the Update button is clicked, the current STI value will appear

      You are now creating a Web page which shows the latest stock index values.
      When the user clicks on the Update button, this Web application (which acts as a
      Web service client) invokes the GetStockIndex method of the STI (or any
      other index) Web service provider, gets the return integer, and displays it in the
      Textbox. The lb_msg label is for displaying error messages when exceptions
      occur – such as when the Web service provider server is down.

       Notice that the lb_msg Label control is displayed as [(ID)] in Design View.
      When the Label’s Text property is blank, this is how it shows up.


2. Add a Web reference

      Right-click on References in the Solution Explorer, and select ‘Add Web
      Reference’. You should see the Add Web Reference dialog box (figure 6-8).

      In the URL field, enter the URL for the WSDL file of the Web service you hosted
      in the previous exercise, and click on Go.




www.mokhengngee.per.sg/book
                                                                                  131




Figure 6-8: Adding a Web reference


VS.NET will attempt to retrieve the WSDL file from the URL you had specified.
If this is successful, the list of available Web methods from this particular Web
service provider will be displayed (figure 6-9). In this exercise, you should be able
to see the GetStockIndex() Web method which returns an integer.

Enter WebRefSTI (or some other relevant name) in the ‘Web reference name’
field (in figure 6-9), and click on the ‘Add Reference’ button.




Figure 6-9: Viewing the available Web methods.




                                                                    ASP.NET Workbook
132


      Back in Solution Explorer, you should be able to see the Web references used for
      your project (figure 6-10). You may add any number of Web references as
      necessary.

         Renaming a Web reference: It’s easy to rename your Web references. Just
      right-click on the Web reference in Solution Explorer and select Rename.




      Figure 6-10: Web References for each project are visible in Solution Explorer


3. Write code to consume the Web service in the Button’s event handler

      Double click on the Update button in Design View of StockDisplay.aspx to
      fill in the event handler codes:

      Private Sub bn_Update_Click _
      (ByVal sender As System.Object, ByVal e As System.EventArgs)_
      Handles bn_Update.Click
       lb_msg.Text = ""

        Dim ws As WebRefSTI.Service1
        Dim sti As Integer

        Try
          ws = New WebRefSTI.Service1
          sti = ws.GetStockIndex()
          tb_sti.Text = sti
        Catch ex As Exception
          lb_msg.Text = "An exception occurred: " + ex.Message
        End Try

      End Sub

      Read the codes and try to understand them. We have created a proxy instance to
      the Web service provider and used the variable ws to refer to this proxy.



www.mokhengngee.per.sg/book
                                                                                   133


4. Test out the Web form

   View DisplayStock.aspx in a browser and click on the Update button. If
   everything is okay, the Web method is invoked, and the current index value is
   returned and displayed in the TextBox (figure 6-11).




   Figure 6-11: Your Web form which is also a Web service consumer.


5. Disable your Web service provider to generate an exception

   Let’s check out what happens when an exception occurs. We can shut down the
   Web Service provider which is running on your same machine. To do that, open up
   IIS Manager and click on (local computer), Web sites, Default Web site, and
   search for your Web service provider application (figure 6-12). Right click on your
   application and select Properties.




                                                                    ASP.NET Workbook
134




      Figure 6-12: Viewing the Web service provider application in IIS Manager

      To disable this application temporarily, click on the Remove button (figure 6-13).
      In IIS Manager, notice that the icon representing this Web service provider
      application is now a folder icon, indicating that it is not active.




      Figure 6-13: Disabling the Web service provider.

www.mokhengngee.per.sg/book
                                                                                    135



   View DisplayStock.aspx in a browser again. This time you should be able to
   view the exception message.

   Enable the Web service provider application again via IIS Manager. This time
   instead of the Remove button (figure 6-13), you should see a Create button instead.


6. Consume multiple Web service providers

   So far, what you have done is pretty simple: In exercise 6-1, you have written a
   Web service provider with a Web method called GetStockIndex() exposed.
   In this exercise, you have written a Web application which is a Web service client,
   and which consumes the GetStockIndex() Web method when the Update
   button is clicked. Everything is running on your local machine.

   Now, you are going to try to consume multiple Web methods hosted on your
   friends’ machines.

   Modify DisplayStock.aspx so that 2 to 3 other TextBoxes are added in
   (figure 6-14).




   Figure 6-14: The new StockDisplay.aspx Web form.


7. Add in other Web references

   In this step, you are going to add in 2 or 3 more Web references each referring to a
   remote Web service hosted by 2 or 3 of your friends. Then you will modify the
   event handler for the Update button so that each of the GetStockIndex Web
   method gets invoked. Show their return values in the TextBoxes which you have
   added to the Web form.

                                                                      ASP.NET Workbook
136



      Repeat step 2 for each remote Web reference that you are going to add. This time,
      instead of indicating the URL of the WSDL file for the Web service running on
      your machine, get the URLs from your friends. Give each Web reference a
      different and meaningful name.

      Modify the event handler for the Update button so that each Web method is
      invoked in turn, and the respective index values are displayed in the Textboxes.

      That’s it! You have written a Web service client which consumes multiple remote
      Web services.




             Timing out remote Web service providers

There are 2 main sources of exceptions when a Web service client attempts to invoke
remote Web methods:
   • The remote Web service is not available (for example when the remote
      machine is shut down, or the remote application isn’t running.) Sometimes, the
      remote application is so bogged down by Internet traffic that it may take too
      much time to respond to a Web service request.
   • SOAP exceptions. These are errors internal to the Web service, and results in
      error messages from the service in the form of SOAP exceptions.

Web service client applications which need a response from a remote Web service
server within a certain time may set the Timeout property of the Web service proxy
to some value (in milliseconds). (The default timeout value is set to 100000 ms.) For
example, we can set the proxy’s time out to 100 ms like this:

  Dim ws As WebRefSTI.Service1
  Dim sti As Integer
  Try
    ws = New WebRefSTI.Service1
    ws.TimeOut = 100
    sti = ws.GetStockIndex()
  Catch ex As Exception
    'Do something
  End Try

In the code fragment above, if the remote Web service provider doesn’t respond
within 100 ms, an exception will be thrown. You can check if this works by inserting
a delay in the Web method in the Web service provider. The following statement can
be used to insert a 200 ms delay in the codes to slow the response:
         System.Threading.Thread.Sleep(200)



www.mokhengngee.per.sg/book
                                                                                137


As for SOAP exceptions, we can catch them, and extract more information. Here is an
example:

      Try
        'Invoke Web service here
      Catch ex As System.Web.Services.Protocols.SoapException
        lb1.Text = ex.Message 'Message of the original exception
        lb2.Text = ex.Code    'Server fault code
        lb3.Text = ex.Actor   'URL of the Web service method
      Catch ex As Exception
        'Deal with other exceptions here
      End Try




                                                                  ASP.NET Workbook
138




Exercise 6.3 (Optional)

Consuming Web Services from Google
Now that you are familiar with how to consume Web services, this exercise requires
you to consume Web services exposed by Google through the Internet. Theoretically
speaking, the only file you will need to consume Google’s Web services is the WSDL
file, but you will need the necessary documentation (such as what each parameter for
the method invocations mean).

Visit http://www.google.com/apis; all the necessary instructions can be
found there (figure 6-15). You will need to:
   • Download the Google Web API Developer’s Kit (666 KB) which contains the
       WSDL file and examples of how to write the Web service client in .NET and
       Java, plus an important API document.
   • Register with Google to get a unique key. You will use this key to invoke
       Google’s Web service. (To register, you will need an email address to which
       they will send the key to.)




      Figure 6-15: Google’s Web API page where you can download your developer’s
      kit and register for a key.

Write a ASP.NET Web application which emulates www.google.com. Your Web
form can take in a search string and display the top 10 hits when a button is hit.



www.mokhengngee.per.sg/book
                                                                                  139




Exercise 6.4 (Optional)

Consuming Web Services from Amazon
Go to www.amazon.com; scroll down the page, and click on the ‘Web Services’
hyperlink on the left (figures 6-16 and 6-17). Just like for Google’s case, you can
download the Amazon Web services developer’s kit (540 KB) and register for a key
(Amazon calls it a token).




      Figure 6-16: Click on ‘Web Services’ at Amazon’s Web site.




                                                                    ASP.NET Workbook
140




      Figure 6-17: Download Amazon’s Web services developer’s kit

Amazon’s Web service might be more interesting and useful. You can write a Web
form which allows the user to search for a particular book and display information
about the book when a match is found.

Happy experimenting!




www.mokhengngee.per.sg/book
7: Site Security
It is extremely important for developers to be aware of the various options for
securing their ASP.NET Web applications. In this chapter, you will learn how to set
access rights to certain Web pages in your Web application so that users need to log in
to view certain protected pages.

There is only 1 exercise in this chapter:
   • Exercise 7.1: Web Form Authentication using Web.config


Exercise 7.1

Web Form Authentication using Web.config
ASP.NET provides 3 different modes for authenticating users:
    • Form-based,
    • Microsoft Passport, and
    • Windows.
In this exercise, we will look at the most commonly employed user authentication
method: form-based.

    Why not Passport or Windows authentication? Passport authentication requires
the user to log into his own Microsoft Passport account, and for the server to subscribe
to the Passport service. Windows authentication allows a user to be authenticated
based on his Windows account on the Windows domain. While Windows
authentication might be convenient for intranet Web applications where all users are
expected to have a Windows user account in the domain, it is not applicable for
general Web users from the Internet who may or may not even be accessing your Web
application from a Windows machine.

Objectives:
   • Understand how to edit Web.config to enable form-based authentication,
      and to allow or deny certain users from accessing particular Web pages, or
      Web pages in a particular directory.
   • Learn how to use the FormsAuthentication class to programmatically
      check if authentication is successful.

Instructions:

1. Create a (privileged) dummy page

                                          141
142



      Create a new ASP.NET Web application project called FormAuthWebApp.
      WebForm1.aspx which is automatically created for you shall be our ‘dummy
      page’ which we assume contains privileged information. Onlyauthenticated and
      authorized users should be able to view WebForm1.aspx.

      Pull in a Label onto WebForm1.aspx and set its Text property to some
      message such as ‘You are viewing some confidential data in
      WebForm1’.

      Right click on WebForm1.aspx in Solution Explorer and select ‘View in
      browser’ (figure 7-1). Like all our previous projects, WebForm1.aspx is not
      protected in any way. i.e. once it is hosted on your IIS server, any user can view it
      by just typing in the correct URL to that page
      (http://<your_ip_address>/FormAuthWebApp/WebForm1.aspx).




      Figure 7-1: WebForm1 is currently free-for-all to see.


2. Edit Web.config to enable Form-based authentication

      Open up Web.config and scroll down to the <authenticate> element.
      Replace it with the following:

         <authentication mode="Forms">
           <forms name="authcookie"
                  path="/"
                  loginUrl="login.aspx"
                  protection="All"
                  timeout="1">
             <credentials passwordFormat="Clear">
               <user name="user1" password="pwd1" />
               <user name="user2" password="pwd2" />
               <user name="user3" password="pwd3" />
             </credentials>
           </forms>
         </authentication>




www.mokhengngee.per.sg/book
                                                                                      143


Scroll down to the <authorization> element and replace it with the
following:
   <authorization>
     <allow users="user1" />
     <deny users="*" />
   </authorization>


    Authentication cookie: ASP.NET’s form-based authentication relies on an
authentication cookie. When the user requests for any protected Web page, IIS
checks to see if there is an authentication cookie in the request. If not, IIS will
redirect the user to the authentication page (as specified by the loginUrl
attribute). This authentication cookie’s name is specified in the name attribute.
  <forms name="authcookie"
         path="/"
         loginUrl="login.aspx"
         protection="All"
         timeout="1">


Based on the <forms> element above, the name of the authentication cookie has
been set to authcookie, and if the user fails to enter the correct user
ID/password, she will be redirected to login.aspx.

   Understanding the other <forms> attribute: The protection attribute
specifies if the authentication cookie should be validated and/or encrypted. Only
the following values are acceptable for the protection attribute: All, None,
Encryption, Validation. Setting protection to All will cause the
authentication cookie to be both encrypted and validated, setting it to None means
that the cookie should not be validated nor encrypted. Validation here checks that
the authentication cookie has not been tampered with. You should use the All
value unless there is a good reason for doing otherwise.

The timeout attribute is set to an inactivity timeout period in minutes. In this
example, we are setting it to 1 minute so that if there is no activity from the client
after having logged in successfully (via login.aspx) after 1 minute, she will be
sent back to login.aspx again if she tries to access any protected Web page
after timeout. Differentiate this authentication timeout from session timeout; the
session may still be valid even though the authentication period has timed out.

   User authentication and authorization: The <credentials> element is the
place for you to specify the list of user names and password. Here, we have
‘created’ 3 user accounts for authentication: user1, user2 and user3, with
their corresponding passwords:

    <credentials passwordFormat="Clear">

                                                                     ASP.NET Workbook
144


            <user name="user1" password="pwd1" />
            <user name="user2" password="pwd2" />
            <user name="user3" password="pwd3" />
          </credentials>


      That is not enough; we need to use an <authorization> element to specify
      who in the list of valid users are able to access the Web pages in the current
      directory:
          <authorization>
            <allow users="user1" />
            <deny users="*" />
          </authorization>


      The above <authorization> element allows only user1 to access the Web
      pages in the current directory, and denies everyone else (* is the wildcard
      character which represents everyone). You can also use ? to represent anonymous
      users (anonymous users are users without any valid user name and password – i.e.
      anyone). The examples below will explain better.

      The following grants user1 and user2 access, but denies everyone else.
           <authorization>
             <allow users="user1,user2" />
             <deny users="*" />
           </authorization>

      The following grants user1 access, but denies user2 and user3.
          <authorization>
            <allow users="user1" />
            <deny users="user2,user3" />
          </authorization>

      The following denies all anonymous users (i.e. any user without a valid user name
      and password as stated in the <credentials> element.) user1, user2 and
      user3 are granted access because they are non-anonymous:
          <authorization>
              <deny users="?"/>
          </authorization>


          Tricky authorization: Take note that the <authorization> element is
      processed from top to bottom. What this means is that you can place the <deny>
      element before the <allow> element, and the users specified in the <deny>
      element will ‘override’ those specified in the <allow> element since it appears
      after <deny>.

      The following will allow all users (including user3) access to all pages in the
      directory:
          <authorization>
            <allow users="*" />

www.mokhengngee.per.sg/book
                                                                                  145


         <deny users="user3" />
       </authorization>


   The following will deny user3 but allows all other users to access all pages in the
   directory:
       <authorization>
         <deny users="user3" />
         <allow users="*" />
       </authorization>


   The only difference between the 2 examples above is that the <allow> element
   comes first in the former, and the <deny> element comes first in the latter.


3. Create a login page

   We are now going to create a login page where users can enter their user ID and
   password. Right click on the Project name in Solution Explorer and select
   Add Add Web Form. Type in login.aspx as the name of the new Web form
   which you are going to create.

   Add the server controls to login.aspx and change the (ID) property and other
   control property values as indicated in the following table:

    Control type       ID                Property values to be modified
    asp:TextBox        tb_userid         -
    asp:TextBox        tb_pwd            TextMode: Password
    asp:Button         bn_submit         Text: Login
    asp:CheckBox       cb_remember       Text: Remember me
    asp:Label          lb_message        ForeColor: Red
                                         Text: (leave blank)

   Drag a few client-side Labels from the HTML section in the Toolbox, and change
   their text. The resulting Web form should look like figure 7-2.




                                                                    ASP.NET Workbook
146




      Figure 7-2: login.aspx with its server controls

4. Writing the event handler for the Submit button

      Double click on the Login button and fill up the event handler for the button:

      Private Sub bn_submit_Click _
      (ByVal sender As System.Object, ByVal e As System.EventArgs)_
      Handles bn_submit.Click

        If FormsAuthentication.Authenticate(tb_userid.Text,tb_pwd.Text)
        Then
          FormsAuthentication.RedirectFromLoginPage _
            (tb_userid.Text, cb_remember.Checked)
        Else
          lb_message.Text = "Wrong user ID or password. Try again."
        End If

      End Sub




         About FormsAuthentication: The FormsAuthentication class is a
      .NET framework library class in the System.Web.Security namespace. The
      Authenticate method is a static (or shared in VB.NET terminology) method
      of this class which takes in the user name and password as strings, and returns a
      boolean value depending on whether the credentials are valid based on the
      credential store used.

      The RedirectFromLoginPage static/shared method of
      FormsAuthentication redirects an authenticated user back to the originally-
      requested URL. It takes in a string (user name for authentication cookie purposes)
      and boolean (which specifies whether a persistent cookie should be issued). This

www.mokhengngee.per.sg/book
                                                                                        147


   method looks at the URL’s ReturnUrl parameter to determine where is the
   original URL to redirect to (see note in the next section). In the event that this
   parameter is missing, this method will redirect the user to Default.aspx.

5. Try accessing your Web form with an invalid account

   We are going to attempt to access the WebForm1.aspx page without first
   logging in. Right click on WebForm1.aspx in Solution Explorer and select
   ‘View in Browser’.

   This time round, instead of WebForm1.aspx showing up, IIS realises that the
   user hasn’t been authenticated yet, and displays login.aspx instead (figure 7-
   3).




   Figure 7-3: login.aspx appears instead of WebForm1.aspx when you
   attempt to view the latter.

   Type in some random into the UserID and Password TextBoxes and click on the
   Login button. Login fails because there is no such account (specified in
   Web.config), and the error message appears as the label’s text (figure 7-4).




                                                                        ASP.NET Workbook
148




      Figure 7-4: User validation fails

6. Try accessing your Web form with an unauthorized valid account

      This time, type in user2 and pwd2 in the UserID and Password TextBoxes and
      click on the Login button. There is such a valid account in Web.config, but
      user2 isn’t supposed to be able to view WebForm1.aspx according to the
      <authorize> settings in Web.config.

      This time round, no error message appears (since this is a valid account), but the
      user is redirected back to the same login page instead of WebForm1.aspx.

7. Try accessing your Web form with an authorized valid account

      Finally, try by logging in with user1 and pwd1. You should be able to see the
      ‘confidential’ contents of WebForm1.aspx since user1 is a valid account with
      authorization to view all the forms in the current directory.

         Remembering the actual requested page: If your login is successful, IIS will
      automatically send you back to the original page you requested (in this case,
      WebForm1.aspx). How does IIS remember?

      Take a closer look at the URL in figure 7-3. Instead of
      http://localhost/FormAuthWebApp/login.aspx
      we have something extra tagged behind:
      http://localhost/FormAuthWebApp/login.aspx?ReturnUrl=%2fFormAuthW
      ebApp%2fWebForm1.aspx

      This ReturnUrl parameter value is used to tell IIS which page to send the user
      back to after she has logged in successfully. In this case, the user will be sent back


www.mokhengngee.per.sg/book
                                                                                     149


   to FormAuthWebApp/WebForm1.aspx when the user has proven herself to
   be authorized.

   Refresh WebForm1.aspx a few times; you realise that once you have logged in
   successfully, you are able to view WebForm1.aspx as long as your
   authentication period hasn’t timed out.

   The authentication timeout has been set to 1 minute for this application. Wait for 1
   minute without sending any request to the Web server, and try to refresh
   WebForm1.aspx again. You will be redirected back to login.aspx again.


8. Understand folder-based access control

   What you have done so far either denies or allows access to all the Web pages in
   the whole Web application. What you may want to do is to allow different access
   rights to different users to different groups of Web pages. Now, we are going to
   explore folder-based access control using multiple Web.config files.

       Multiple Web.config files: You can have any number of Web.config
   files for each Web application. The rule is that each folder in your application can
   have only up to 1 such file.

   Web.config works in a hierarchical ‘overriding’ way. You will understand what
   this means after you have completed this exercise.

9. Creating new physical folders and Web forms in your application

   Right-click on your Web application’s name (FormAuthWebApp) in Solution
   Explorer and select Add New Folder. Type in level1 as the new folder’s
   name. Right click on the new folder you have created in Solution Explorer, and
   select Add New Folder again. Call the new sub-folder level2.

     What we have done is to create a new physical folder called level1 in
   c:\Inetpub\wwwroot\FormAuthWebApp, and a new sub-folder called
   level2 in c:\Inetpub\wwwroot\FormAuthWebApp\level1.

   Right-click on folder level1 and select Add New Form. Call your new Web
   form WebFormInLevel1.aspx, and type in a static Label in your new form so
   that we are aware when WebFormInLevel1.aspx shows up.




                                                                      ASP.NET Workbook
150


      Similarly right-click on the level2 folder, and add in a new Web form called
      WebFormInLevel2.aspx with a static Label. Your file hierarchy should look
      like figure 7-5.




      Figure 7-5: Setting the experimental stage

10. Verify that application-level authorization works

      Open Web.config in the application’s ‘root folder’ and edit the
      <authorization> element to allow user1 and user2 to access all the Web
      pages in this application:
         <authorization>
           <allow users="user1,user2" />
           <deny users="*" />
         </authorization>


      Now try to view WebFormInLevel1.aspx in the level1 folder. You will be
      redirected to login.aspx. Try logging in as user3 (this should fail), and then
      as user1 (this should succeed). Push the backspace key to go back to the
      login.aspx page, and this time log in as user2 (this should succeed too).

      Do the same with WebFormInLevel2.aspx in the level2 folder. Everything
      is working as expected – no surprises so far.


11. Add in Web.config into the level1 folder

      Right click on the level1 folder and select Add Web User Control. Select
      ‘Web Configuration File’ in the right Templates panel, leave the name as
      Web.config and click on the Open button.



www.mokhengngee.per.sg/book
                                                                                  151


  You need to open level1/Web.config for editing. Replace the whole file
  with the following:

     <?xml version="1.0" encoding="utf-8" ?>
     <configuration>
       <system.web>
         <authorization>
             <allow users="*" />
         </authorization>
       </system.web>
     </configuration>


  What you have done is to place a new Web.config file in level1, and
  indicated that all the Web pages in level1 are to be viewed by all.

  Check out whether this authorization setting ‘overrides’ the setting in the
  Web.config file in the application’s ‘root folder’ by trying to view
  WebFormInLevel1.aspx and WebFormInLevel2.aspx. You will not be
  redirected to the login page this time.

  Try to view WebForm1.aspx which you created in step 1, and you will be
  redirected to login.aspx, since that is still a ‘protected’ page (courtesy of
  Web.config in the ‘root folder’).

  This new Web.config setting affects all the Web pages in level1, and all sub-
  folders (including every page in level2).

12. Add in Web.config into the level2 folder

  Next, we are going to add in a separate Web.config file into the level2 sub-
  folder and configure it so that full access to everyone is given to
  WebFormInLevel1.aspx (in folder level1), but only user3 has access to
  WebFormInLevel2.aspx (in folder level2).

  Right-click on level2 in Solution Explorer, and select Add Web User Control.
  Select ‘Web Configuration File’ in the right Templates panel, leave the name as
  Web.config and click on the Open button.

  You need to open level1/level2/Web.config for editing. Replace the
  whole file with the following:

     <?xml version="1.0" encoding="utf-8" ?>
     <configuration>
       <system.web>
         <authorization>
             <allow users="user3" />
             <deny users="*" />
         </authorization>

                                                                    ASP.NET Workbook
152


           </system.web>
         </configuration>


      This time, try to view WebFormInLevel2.aspx, and you will have to login as
      user3 to see this page.

      You have effectively learnt how to enable different levels of access control to
      various folders in your Web application. Remember that Web.config is an
      optional file, but if it is present in a particular folder, the settings in this
      configuration file will ‘override’ those in the Web.config found at the next
      ‘higher level’.


          Hierarchical config files: The Web configuration settings you see in
      Web.config are arranged in a hierarchical fashion. Right at the top is
      machine.config (found in
      C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG), followed
      by Web.config in the Web application’s ‘root folder’, and the Web.config
      files in the various sub-folders. The settings in the most local folder ‘override’ the
      parent and global settings. There are certain other rules, such as the fact that some
      settings are only allowed in specific locations. For example, Web.config in sub-
      folders can only contain security information, but not module configuration
      settings.




              Further Exercise

This exercise verifies that you have understood the previous section.

The following table shows the contents of the <authorization> element in each
configuration file and their locations:

 Location                                       Contents of <authorization>
 machine.config                                 <allow users="*" />
 Web.config at application root (/)             <allow users="user1" />
                                                <deny users="*" />
 Web.config at /sales                           (empty – not specified)
 Web.config at /sales/team1                     <allow users="user2" />

 Web.config at                                  <allow users="user3" />
                                                <deny users="*" />
 /sales/team1/misc

Questions:

www.mokhengngee.per.sg/book
                                                                                     153


   • Can user1 and user2 access a Web page in /sales/team1/misc?
   • Can user1 and user3 access a Web page in /sales/team1? (This one is
     tricky because there is no explicit <deny> element at this level.
   • Can user1, user2 and user3 access a Web page in /sales?




           Setting file-level access

Besides setting user access at folder level by using multiple Web.config files in
each folder, you can set specific access to a particular Web page in a folder by using
the <location> element within <configuration> of Web.config.

Here is an example:

       <?xml version="1.0" encoding="utf-8" ?>
       <configuration>
         <location path="SomeFile.aspx">
           <system.web>
             <authorization>
                 <allow users="user2" />
                 <deny users="*" />
             </authorization>
           </system.web>
         </location>
         <location path="SomeOtherFile.aspx">
           <system.web>
             <authorization>
                 <allow users="user2,user3" />
                 <deny users="*" />
             </authorization>
           </system.web>
         </location>
       </configuration>




           Clear passwords in Web.config?

      If you think that storing users’ passwords in clear in the <credentials>
element in Web.config isn’t quite right, you are correct. In most professional
applications which keep track of user names and passwords, the actual passwords are
known only to the user who selected them. The application hashes up the password
and stores the hash instead of the actual password in their databases. This helps
prevent Web administrators from seeing the users’ passwords in clear. Users are
assured of more privacy and security.


                                                                      ASP.NET Workbook
154


The FormsAuthentication class has a very useful static/shared method called
HashPasswordForStoringInConfigFile that comes in extremely useful for
obtaining the hash of a string. This method supports 2 hash algorithms: SHA-1 and
MD5. All you have to do is to pass in the string for hashing, and the hashing algorithm
("sha1", or "md5") as the 2 parameters when calling this method.

Here is an example in VB.NET (tb_pwd is the TextBox control containing the
password):

Dim hashedPasswordSHA1 As String
  hashedPasswordSHA1 = _
  FormsAuthentication.HashPasswordForStoringInConfigFile _
  (tb_pwd.Text, "SHA1")


   Which hashing algorithm should you use? Of the 2 inherently-supported hash
algorithms MD5 is faster to calculate, but SHA1 is more secure. So it depends on
whether speed or security is more important in your application.



              Further Exercise

1. Write a simple Web application which allows the user to enter a password in clear
   into a TextBox, and upon the click of a button, displays the MD5-hashed and
   SHA1-hashed value (figure 7-6).




      Figure 7-6: A simple application to get hashed values

2. Use this simple application to obtain the hashed value of a few passwords (use
   either MD5 or SHA1). Edit Web.config by replacing the clear passwords with
   their corresponding hashed value.

3. If you try the login page now, and key in the clear password, obviously the login
   will fail as your clear password does not match the hashed value in Web.config.
www.mokhengngee.per.sg/book
                                                                                 155


We need to do something before your application is ‘hash-enabled’. There are 2
ways to do this (the second is the ‘correct’ way):

(i)    In the event handler of the login button, you can use the
       HashPasswordForStoringInConfigFile method to calculate the
       hash value and pass the hash into the Authenticate method.

(ii)   You don’t have to do this hash conversion manually; ASP.NET supports
       ‘automatic’ hashing of the password passed into Authenticate. All you
       have to do is to alter the <credentials> sub-element in
       <authenticate> of Web.config. Change the passwordFormat
       attribute value from Clear to either MD5 or SHA1. Here is an example:
       <credentials passwordFormat="SHA1">
         <user name="user1"
           password="A63D4B132A9A1D3430F9AE507825F572449E0D17" />
         <user name="user2"
           password="C88B5C841897DAFE75CDD9F8BA98B32F007D6BC3" />
         <user name="user3"
           password="145E43FF6E0AF0C32986A494C0D951B3F305F268" />
       </credentials>


Change Web.config to reflect the hashed passwords, and try to login again to
see if your login works.




                                                                ASP.NET Workbook

								
To top