Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
37 views

Advanced C# Programming Unit 4-6 (CSPBC-09 V1.5) Learner Guide

This document provides an introduction to the Advanced C# Programming course. It outlines the structure and requirements of the course, which covers units on storing data, ASP.NET, and .NET distributed computing. Students will learn to create advanced Windows and web applications using techniques like Windows controls, file I/O, XML, databases, and ASP.NET features. The goal is for students to demonstrate these skills through a final project and exams. Close attention should be paid to each unit's theory, exercises, and exams in order to complete the course successfully.

Uploaded by

Duane Raath
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views

Advanced C# Programming Unit 4-6 (CSPBC-09 V1.5) Learner Guide

This document provides an introduction to the Advanced C# Programming course. It outlines the structure and requirements of the course, which covers units on storing data, ASP.NET, and .NET distributed computing. Students will learn to create advanced Windows and web applications using techniques like Windows controls, file I/O, XML, databases, and ASP.NET features. The goal is for students to demonstrate these skills through a final project and exams. Close attention should be paid to each unit's theory, exercises, and exams in order to complete the course successfully.

Uploaded by

Duane Raath
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 331

Advanced C# Programming

CSPBC-09 V1.5 
Advanced C# Programming
CSPBC-09

Compiled by Kyle Brunette, Angelique Kolle, Lance Whyte, and Daniel Sansom

Edited by Anita Campbell and Cameron Dalton

Version 1.5

 April 2010 CTI Education Group


TABLE OF CONTENTS
INTRODUCTION TO THE C# B COURSE 1 
About this course 1 
Resources 1 
Requirements 1 
How to approach this course 1 
Structure of a unit 3 
Course outcomes 4 
Beginning a project 4 
Required documentation 6 
How projects are evaluated 6 
Project documentation 7 
Symbol guide 10 
Font guide 10 

UNIT 4 – STORING DATA 11 


4.1 Windows User Control (custom control) 13 
4.2 DateTime data type 25 
4.3 Deploying a Windows Application 33 
4.4 Maintaining and Supporting a Windows Application 41 
4.5 Attributes 45 
4.6 Reflection 51 
4.7 File I/O 55 
4.8 ADO.NET 65 
Unit 4 Test your knowledge (Self-test) 107 

UNIT 5 – ASP.NET 111 


5.1 ASP.NET Fundamentals 113 
5.2 Microsoft Visual Web Developer Express Edition IDE 115 
5.3 ASP.NET: Events and controls 125 
5.4 Validating data: Validation Controls 145 
5.5 Data-binding 157 
5.6 Using databases with ASP.NET 167 
5.7 ASP.NET Objects 203 
5.8 Distributing ASP.NET applications 217 
Unit 5 Test your knowledge (Self-test) 221 

UNIT 6 - .NET DISTRIBUTED COMPUTING 223 


6.1 Introduction 225 
6.2 XML data 234 
6.3 .NET Remoting 258 
6.4 Web Services 280 
6.5 Project 290 
Unit 6 Test your knowledge (Self-test) 304 

LANGUAGE COMPARISON 307 

BIBLIOGRAPHY 319 

C# – EXERCISE CHECKLIST 321 


Introduction to the C# Course Page 1

Introduction to the C# B Course

About this course

Congratulations on passing the C# A course and welcome to the C# B course! When the
C# B course has been successfully completed, the requirements for C# as a first
programming language will have been met.

Resources

The following textbook will be used for this course:

 Foxall J, 2008, Sams Teach Yourself Visual C# 2008 in 24 Hours, New Jersey:
Pearson Education, Inc. (ISBN 978-0-672-32990-6)

The study guide does not reference the textbook. The textbook is an invaluable tool
should difficulties be experienced at any point in the course. The textbook and study guide
are based on the assumption that the concepts may be unfamiliar and detailed
explanations are always provided.

Requirements

The following software must be installed on the computer that is used:

 Windows Vista
 Microsoft Office Access 2007
 Microsoft SQL Server 2008 Management Studio
 Microsoft Visual C# 2008 Express Edition
 Microsoft Visual Web Developer 2008 Express Edition

How to approach this course

This study guide covers C# B (units 4 to 6).

© CTI Education Group


Introduction to the C# Course Page 2

The following time and mark schedule applies to this course:

Section Unit Days % Notes

C# B 100% 10 Go through unit and start project


4
2 10 Theory exam at the end of the unit
10 Go through unit and continue project
5
2 10 Theory exam at the end of the unit
10 5 Go through unit and finish project
6 3 45 Theory exam covering the whole course
1 30 Practical exam

Each unit consists of:

 Theory – in the study guide and any extra reading from the textbook.
 Theory exam – written after each unit, comprising theory and application questions.

A project must be submitted in Unit 6 and is a prerequisite to writing the theory exam for
Unit 6. The practical exam is the final exam at the end of Unit 6 and may only be
attempted when a pass mark has been achieved for both the project and the theory exam.

Be sure that each unit is thoroughly understood before writing the theory exam. The
exams are made up of theory questions based on the study guide. The application
questions in the exam refer to short pieces of code about which questions will be asked.
Go through all the examples in the study guide. The exercises will help with preparation
for the project and the exams, so it vital to complete them. The checklist provided at the
end of the study guide lists all the exercises and questions which have to be completed
before the project may be handed in, or the final theory exam written.

The theory exam consists of multiple choice questions, true/false questions, multiple
response questions, identifying errors in an existing section of code, and matching
questions. The theory exam at the end of Unit 6 will cover questions from units 1 to 6.

The practical exam involves coding programs using the knowledge gained while working
through the course. The study guide and one textbook of choice are permitted in the
practical exam.

It is advisable to start planning and preparing the project as soon as possible. This
spreads the workload over a longer period of time, and ensures that the project is fully
functional and ready in time. Naturally, the coding of the project cannot commence until
such a time as all the necessary concepts are understood; however, the necessary
research may be done and decisions made about the look and feel of the project.
Diagrams, flowcharts, etc. are invaluable tools in the logical planning of the project.

Use all the available study aids – they help to gain a better understanding of the material.

© CTI Education Group


Introduction to the C# Course Page 3

Structure of a unit

Each unit is broken down into smaller sections. The first section is always an Objectives
section, which outlines what is of particular importance in that section. There are
exercises in each section to test knowledge of the material. Please note that the exercises
are not optional. The exam includes material from these exercises. Therefore, make
sure that all the exercises are done and should something not be clear, please ask for
help. Revision questions are a good indication of what to expect in the exam, although
some exam questions will undoubtedly be more difficult than the revision questions.

Each unit ends with a Test your knowledge section. These sections contain questions
similar to those found in the theory exams. It is therefore very important to attempt these
questions and then to check the answers with an instructor.

The Project specifications are found at the end of Unit 6. It is very important to start with
the project as soon as possible. The project specifications are guidelines which need to
be followed in order to meet the project requirements. Any project which does not meet
the specifications will have to be resubmitted. The instructor will give advice as to which
project should be completed.

© CTI Education Group


Introduction to the C# Course Page 4

Course outcomes

Learning outcomes Assessment criteria for pass


To achieve each outcome a learner must
demonstrate the ability to:
1 Create advanced Windows  Use advanced Windows controls
applications.  Use the File Input and Output
 Manipulate an XML file using C#
 Use and manipulate data from a database

2 Create Web pages using  Create a basic Web page using the An IDE and
ASP.NET ASP.NET.
 Illustrate the use of events and event handlers
in an ASP.NET application.
 Create an advanced Web from using code-
behind files.
 Illustrate the use of data binding and database
connection in an ASP.NET application.
 Make an ASP.NET application visible to others.

3 Comprehend .NET  Illustrate the use of the XPath in an ASP.NET


distributed computing and application.
create services.  Produce a distributed application.
 Create a Web service.
 Create a Windows service.

Beginning a project

The project should be started as soon as possible and must be completed by the end of
Unit 6. In order to complete a project successfully, the following should be kept in mind:

1. Read the relevant sections in the study guide to be familiar with the material.
2. Go through the relevant sections of the textbook with the study guide at hand. The
study guide contains extra information on certain topics which provides a broader
knowledge base for the exams, as well as pointers to important concepts that could be
applied in the project.
3. Type in the examples from the study guide. This might seem pointless, but it is an
easy way to become familiar with the language. Make sure to experiment with the
code; make deliberate mistakes to get a feel for the way the compiler handles errors.

© CTI Education Group


Introduction to the C# Course Page 5

4. Do the exercises at the end of every unit in the study guide. The best way to learn a
language is through practice.
5. Plan the application in advance. Decide what the user interface will look like, what
classes need to be created, etc.
6. Start with the project as soon as possible.

© CTI Education Group


Introduction to the C# Course Page 6

If these guidelines are followed, the project should not prove too difficult.

Required documentation

Once the project is complete it must be submitted on a disk and placed in a folder that has
the learner’s name and learner number clearly displayed, together with the following
documentation:

 Printed copy of the user documentation for the application


 Printed copy of the source code (program listing)

How projects are evaluated

An instructor will mark the project and a project evaluation form consisting of various
sections will then be returned. The general expectations for each of the sections are given
below:

Program design
The project specifications must be followed. For example, if the project specification
specifies the use of a class, then that class must be used. Creativity is encouraged, but
certain elements must be incorporated into the project.

Source code

 The program listing (or source code) must be clear and well laid out.
 The naming standards for variables and method names must be followed.
 Method and variable names should be descriptive.
 Each file must be clearly labelled, with a prologue giving the details for that file.
 There should be adequate and suitable comments in the code.

User documentation

 This should include the program name, the date on which the document was last
modified, and the name and contact details of the author.
 Give an indication of the data that will have to be entered, as well as valid values for
these data items.
 If any files are read from or written to, include these details.
 Outline any errors which may occur, and how to handle them.
 There should be no mistakes in the user/operation documentation.

© CTI Education Group


Introduction to the C# Course Page 7

User interface

 Ensure a pleasing screen layout.


 Always give the user clear instructions: include messages such as “Press any key to
continue…” while waiting for user response and “Please wait a moment” when the
program is delayed for a few seconds.
 Display monetary values with an appropriate symbol, e.g. R, £, or $. The percentage
symbol (%) must be used to display percentages.

Marking the project


Marks will be deducted as follows:

 Coding
o If the program does not run, or there are warnings of any kind. If the program
does not run, the project will be failed.
o If there are any syntax errors.
o If there is redundant or inefficient code.
o If there are any logic errors.
o If variable names are not descriptive.
o If variables are declared as the incorrect type.
o If method names are not descriptive or self-explanatory.
o If the specifications are not followed.

 User interface
o If the interface is not eye-pleasing.
o If any functionality does not work, or is missing.
o If the interface is not reasonably self-explanatory, i.e. someone who has not used
it before should be able to understand how it works with minimal effort.
o If the specifications are not followed.

 User documentation
o If the user documentation does not adequately explain how to install and run the
application, working on the assumption that the end-user has no prior experience
of doing so.
o If the user documentation does not explain how to use each feature of the
application. The screenshots included must clarify each operation.
o If the user documentation is not handed in with the project, printed in colour.

If a project is failed, it will need to be redone from scratch and resubmitted.

Project documentation

Printed copy of all the documentation must accompany the project disk that is handed in to
the instructor as it is also evaluated.

© CTI Education Group


Introduction to the C# Course Page 8

All programs should be adequately documented so that:

 Those who have to maintain the code know what every single line of code is intended
to do (program design documentation and source code documentation).
 Those who have to use the program know how to run it, what to expect, and what
output will be displayed or printed (user documentation).

Program design documentation


In the planning stage of the project various techniques may be employed, e.g. flow
diagrams, class diagrams, pseudocode, etc. A structured plan will be an invaluable aid to
developing a fully functional project.

Source code documentation


For any serious application, it is almost guaranteed that programmers will have to return to
the code to correct a problem or to add a new feature. These programmers are often not
the original authors of the application. It is thus important that code is easy to read, with
comments that clearly explain what is intended by structures and blocks in the code. If a
programmer who has to maintain the code must first try to understand what the actual
intention was, it not only wastes time, but also opens up the possibility that the coding is
misunderstood, which can then lead to further problems.

A well-documented program will be easier to follow, modify, debug, and maintain. At the
minimum, comments should be included for each program flow or control statement (e.g.
For, If, While, etc), stating what is intended.

It is also important to include a prologue at the top of each file listing (the printout of that
file), which should look similar to the following example:

/*
* Filename: MyProgram.cs
* Author: John Doughnut
* Created: 03/11/2008
* Operating system: Windows Vista
*
* Description:
* This program was written to convert Fahrenheit to Celsius.
*/

The following information should be provided in the prologue:

 Name of file
 Name of author
 Date created
 Operating system
 ‘Big picture’ description of the code
 Any modification information

© CTI Education Group


Introduction to the C# Course Page 9

User documentation
The user documentation is a separate document to the source code documentation. The
emphasis should be on how the program is used, rather than a description of code. The
user documentation must contain the following information:

 The general purpose of the program.


 Details of the author of the documentation, and the date when it was written.
 Details on how to run the program (i.e. what to type at the MS-DOS prompt, or on
which file to click, etc.).
 The information that must be entered by the user and in what format data should be
entered, e.g. two integers in the form “a, b”, or a price in the form “123.56”.
 Indicate the range of valid values.
 Indicate any errors that can occur and what should be done if they do.
 If any files are needed, or created, the user should be informed of this.

Screenshots of the application, and any output it might generate, should be included in the
user documentation. When the program is running, screenshots can be taken using the
Print Screen key (hint: hold down the <Alt> key while pressing <Print Screen> to take a
screenshot of the current window). After the screenshot has been taken, the image can be
pasted into a graphics editing application (for example, Microsoft Paint) and saved. Once
saved, the image can be inserted into the user documentation to give the user an idea of
what to expect when the program runs.

© CTI Education Group


Introduction to the C# Course Page 10

Symbol guide

Denotes the start of each unit in the study guide.

Denotes the start of each main subsection of each unit in


the study guide.

Denotes the objectives to be achieved in every section.

Recommended exercises for each section – usually a


good indication of the exam questions.

Revision questions for each section.

Font guide

This is how examples of source code look.

This is how examples of console output look.

© CTI Education Group


Unit 4 – Storing Data Page 11

Unit 4 – Storing Data

This unit counts 10% towards part B (Units 4, 5, and 6) of the C# mark, and there are 12
days to complete it. The time and marks are scheduled as follows:

Reading 10 days
Exam preparation and exam 2 days 10%

This unit covers user controls, deploying applications, maintaining and supporting
applications, attributes, reflection, file I/O, and ADO.NET.

© CTI Education Group


Unit 4 – Storing Data Page 12

© CTI Education Group


Unit 4 – Storing Data Page 13

4.1 Windows User Control (custom control)

At the end of this subsection, you should be able to:

 Create a custom control from scratch.


 Implement the custom control created.

4.1.1 Creating and implementing a custom Windows control


There are already a variety of controls available to choose from when designing an
application, such as the Button, TextBox, and Label controls. There are even more
sophisticated controls, such as the various Dialog types. However, sometimes a control to
perform a very specific function is required and a custom control will have to be created
from scratch.

A custom control will be referred to from now on as a user control. Make sure that all the
steps below, demonstrating how to create a user control, are followed precisely and
accurately, paying attention to all the details. Also note that there are two ways to add a
user control to a project.

 Start by creating a new project.


 Go to File > New Project > Windows Forms Application.
 Name the application CustomTimerControl and click OK.

The application should look like the one in Figure 4.1 below:

Figure 4.1 – New Windows Forms Application

© CTI Education Group


Unit 4 – Storing Data Page 14

Not much can be done with this application at the moment, so the custom control itself
must now be created. For this example, a user control called TimerControl is created.
User controls can be contained in a .dll file, but they do not themselves contain .dll files.

 Create a new user control class by going to Project > Add User Control…
 A dialog window will appear with user control already selected.
 Name the user control TimerControl.cs and click OK.

An empty grey rectangle will appear where the Form was previously (as in Figure 4.2). It
can be treated just like a Form, because controls can be added to it to create functionality.

Figure 4.2 – Empty grey form-like rectangle

A user control can be made up of other existing controls. This means that other controls
such as the Label, TextBox, and Button controls can all be added to make up the user
control. In the end, these controls will have to function together in order to perform one
task that will be controlled by the user control.

The next step is to add the necessary controls to the new user control and add some code
to it.

 Add a Label control named lblTime and a Timer control named tmrNow to the
empty user control.
 Set the Text property of lblTime to “Time”.
 Set the Enabled property of tmrNow to true, and the Interval property to 1000.

At this stage, the TimerControl should look like Figure 4.3 below:

Figure 4.3 – TimerControl form

Next the code has to be added.

 Press the <F7> key or right-click on the form and select View Code.

The following code will be displayed:

© CTI Education Group


Unit 4 – Storing Data Page 15

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CustomUserControl
{
public partial class TimerControl : UserControl
{
public TimerControl()
{
InitializeComponent();
}
}
}

 Add functionality to the tmrNow control by clicking the Tick event-handler.


 Add the code below so that the whole program looks as follows:

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Data;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9
10 namespace CustomUserControl
11 {
12 public partial class TimerControl : UserControl
13 {
14 public TimerControl()
15 {
16 InitializeComponent();
17 }
18
19 private void tmrNow_Tick(object sender, EventArgs e)
20 {
21 lblTime.Text = DateTime.Now.ToLongTimeString();
22 }
23 }
24 }

Note that lines 19 to 22 have been added to the previous code snippet. The
ToLongTimeString() method converts Now to a string containing the current time.
The get and set properties are used to expose the colour to be added to the user control.

© CTI Education Group


Unit 4 – Storing Data Page 16

 Add the following private variables to the TimerControl class just below the first
curly bracket ({):

public partial class TimerControl : UserControl


{
private Color colFColour; // Private variables.
private Color colBColour;

In order for these variables to work add the following properties below the public
TimerControl() class:

public Color ClockBackColour


{
get
{
return colBColour;
}
set
{
colBColour = value;
lblTime.BackColor = colBColour;
}
}

public Color ClockForeColour


{
get
{
return colFColour;
}
set
{
colFColour = value;
lblTime.ForeColor = colFColour;
}
}

The entire section of code, incorporating all the additions outlined above, should look as
follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CustomUserControl
{
public partial class TimerControl : UserControl
{
// Private variables.
private Color colFColour;
private Color colBColour;

public TimerControl()
{

© CTI Education Group


Unit 4 – Storing Data Page 17

InitializeComponent();
}

public Color ClockBackColour


{
get
{
return colBColour;
}
set
{
colBColour = value;
lblTime.BackColor = colBColour;
}
}

public Color ClockForeColour


{
get
{
return colFColour;
}
set
{
colFColour = value;
lblTime.ForeColor = colFColour;
}
}

protected virtual void tmrNow_Tick(object sender, EventArgs e)


{
lblTime.Text = DateTime.Now.ToLongTimeString();
}
}
}

 Now that the TimerControl has been created, press the <F6> key to build the
project.

This should add the TimerControl to the top of the Toolbox window. If it still does not
appear in the Toolbox window, go to the Design view in the main form and it should
appear.

Once the user control has been added to the form, check the Properties window. It is
now possible to set the background and foreground colour of the timer, as shown in Figure
4.4:

Figure 4.4 – ClockBackColour and ClockForeColour properties

 Add a Label control named lblOne to the form and change the Text property to
“The current time is:”
 Drag and drop the TimerControl onto the form.
 Press the <F5> key for the application to run.

© CTI Education Group


Unit 4 – Storing Data Page 18

The application should now look like Figure 4.5:

Figure 4.5 – The application’s Form

One way of adding a user control to a form has now been explored but if the user control
needs to be available to other applications, a different approach must be taken.

Simply follow the steps below:

 Create a new Class Library by going to File > New Project > Class Library and
name it TimeUserControl.
 Right-click on the project name (CustomTimerControl) in the Solution Explorer.
From there select Add > User Control. Name it TickTimeUserControl. This process
is shown in Figure 4.6:

Figure 4.6 – Adding a User Control

 The Solution Explorer contains a file called Class1.cs as shown in Figure 4.7. This
file must be deleted!

© CTI Education Group


Unit 4 – Storing Data Page 19

Figure 4.7 – Class1.cs that needs to be deleted

The same controls that were created in the previous example can be added to this user
control. After the controls have been added, the TickTimeUserControl should look
identical to Figure 4.7.

 Add the same code that was added to the previous example for the tmrNow_Tick
event-handler.

Make sure that the project is built before closing it and after any changes are made. This
is done by going to Build > Build Solution or by pressing the <F6> key on the keyboard.
If this is not done, the user control will not be available for use in other applications.

Follow the steps below very carefully:

 Create a new Windows Forms Application. Call it TimeUserControlApplication.


 Add a Label control named lblOne and change its Text property to “The current
time is:”
 Right-click on the Toolbox window and select Choose Items…
 A dialog window should appear with a Browse button in the bottom right-hand corner.
 Click on the Browse button and search for the user control, (TimeUserControl),
which has just been created. It is a “.dll” file and should be located in the bin/Release
folder or in the debug folder.
 Click OK.
 Add the TickTimerUserControl to the form.

The TimeUserControl should then be displayed in the Toolbox window.

These were simple examples to explain the concept of user controls and how to add and
use them.

© CTI Education Group


Unit 4 – Storing Data Page 20

4.1.2 Another example


The following example is a bit more complicated and will require a value to be sent to the
user control.

 Create a new Windows Forms Application and call it TestControl.


 Add a User Control to the project and call it TestUserControl.
 Add a ProgressBar control to the form and call it prgProgress (Figure 4.8).
 Add a Label control next to the ProgressBar control and call it lblPercentage
(Figure 4.8).

Figure 4.8 – TestUserControl design

 Right-click on the form and select View Code to go to the Source code view.
 Alter the code as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TestControl
{
public partial class TestUserControl : UserControl
{
private int maximum = 100;
private int minimum = 0;
private int val = 0;

public TestUserControl()
{
InitializeComponent();
}

public int Maximum


{
set
{
maximum = value;
prgProgress.Maximum = maximum;
lblPercentage.Text = (((val - minimum) * 100) / (maximum –
minimum)).ToString() + "%";
}
get
{
return maximum;
}
}

© CTI Education Group


Unit 4 – Storing Data Page 21

public int Minimum


{
set
{
minimum = value;
prgProgress.Minimum = minimum;
lblPercentage.Text = (((val - minimum) * 100) / (maximum –
minimum)).ToString() + "%";
}
get
{
return minimum;
}
}

public int Value


{
set
{
val = value;
prgProgress.Value = val;
lblPercentage.Text = (((val - minimum) * 100) / (maximum –
minimum)).ToString() + "%";
}
get
{
return val;
}
}
}
}

Please note that if the properties have private access, they will not be recognized when
adding the user control to the main form and these properties will not be accessible. All
properties must have public access.

 Build the TestUserControl and switch to the Design view of the Windows Forms
Application that was created at the start of the example. The TestUserControl control
should appear at the top of the Toolbox window.
 Add the TestUserControl control to the form.
 Add two Button controls to the form: btnValueAdd and btnMaxAdd (Figure 4.9).

Figure 4.9 – Adding user control and others to form

© CTI Education Group


Unit 4 – Storing Data Page 22

 Double-click on the btnValueAdd Button control and change the code as follows:

private void btnValueAdd_Click(object sender, EventArgs e)


{
testUserControl1.Value += 10;
}

 Double-click on the btnMaxAdd Button control and change the code as follows:

private void btnMaxAdd_Click(object sender, EventArgs e)


{
testUserControl1.Maximum += 10;
}

 Build and run the project.

The output should look as follows if both Button controls have been pressed once
(Figure 4.10):

Figure 4.10 – TestUserControl in progress

© CTI Education Group


Unit 4 – Storing Data Page 23

4.1.2 Exercises
1. As what is a user control also known?
2. Which event is used in this section for the TickTimer control?

4.1.3 Revision questions


1. True/False: User controls are automatically added to the form.

2. In which directory will a class library (.dll) be found once the project
has been built?
a. obj/Debug
b. bin/Debug
c. bin/Release
d. obj/Release

3. True/False: The user control must be added to the Toolbox window by


the programmer before it can be dragged and dropped onto the form.

4. True/False: A new Class Library can never be used to create a new


user control.

© CTI Education Group


Unit 4 – Storing Data Page 24

© CTI Education Group


Unit 4 – Storing Data Page 25

4.2 DateTime data type

At the end of this subsection, you should be able to:

 Use the DateTime data type


 Add to or subtract from a date or time
 Retrieve parts of a date
 Access the current date and time

4.2.1 Introduction to the DateTime data type


DateTime variables represent an instant in time. The DateTime data type is not really
like the string data type but can be treated as a string is because of the ToString()
method. The way in which the data is stored also allows the DateTime data type to be
treated as integers. http://msdn.microsoft.com/en-us/library/system.datetime(VS.71).aspx
has more information.

4.2.2 Understanding the DateTime data type


The DateTime data type is one of the most complicated data types. It is possible (and
common practice) to use values without storing them in variables. The following code
shows how a DateTime instance can be created:

DateTime myDate = new DateTime(year, month, day);

It is not possible to pass a string value (e.g. a value entered into a TextBox control)
directly to a DateTime variable. The string must first be parsed before assigning it to
the DateTime variable. The example below parses the string and then assigns it to the
DateTime variable:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StringToDateTimeExample
{
class Program
{
static void Main(string[] args)
{
string myDate = "11/04/2009";
DateTime dt = Convert.ToDateTime(myDate);
Console.WriteLine("Year: {0}, Month: {1}, Date: {2}", dt.Year,
dt.Month, dt.Day);
}
}
}

© CTI Education Group


Unit 4 – Storing Data Page 26

The application has the following result:

Year: 2009, Month: 11, Date: 4

Note that when converting a string to a DateTime, the following syntax is used, but it
can be changed:

string myDate = month/date/year;

4.2.3 Adding to or subtracting from a date or time


Table 1 lists some of the most common DateTime methods used to add to or subtract
from dates and times. These methods do not change the current DateTime variable.

Table 1 – Common DateTime methods


Method Description
AddDays() Adds a specified number of days to the value of the instance.
AddHours() Adds a specified number of hours to the value of the instance.
AddMilliseconds() Adds a specified number of milliseconds to the value of the
instance.
AddMinutes() Adds specified number of minutes to the value of the instance.
AddMonths() Adds a specified number of months to the value of the instance.
AddYears() Adds a specified number of years to the value of the instance.

4.2.3.1 AddMonths() method


The following example shows how the AddMonths() method is used:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DateTimeExample
{
class Program
{
static void Main(string[] args)
{
DateTime myDate = new DateTime(1999, 11, 4);
DateTime newMyDate = myDate.AddMonths(6);
Console.WriteLine("Initial date: {0}", myDate);
Console.WriteLine("New date: {0}", newMyDate);
}
}
}

© CTI Education Group


Unit 4 – Storing Data Page 27

The application has the following output:

Initial date: 1999/11/04 12:00:00 AM


New date: 2000/05/04 12:00:00 AM

Note that no additional namespaces have to be imported, as those that were automatically
included will suffice. Also note the time added after the date. This is a default time placed
in a DateTime variable when only a date is specified.

In the next example the AddMonths() method is used to subtract a month:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DateTimeExample
{
class Program
{
static void Main(string[] args)
{
DateTime myDate = new DateTime(1999, 11, 4);
DateTime newMyDate = myDate.AddMonths(-1);
Console.WriteLine("Initial date: {0}", myDate);
Console.WriteLine("New date: {0}", newMyDate);
}
}
}

The application has the following output:

Initial date: 1999/11/04 12:00:00 AM


New date: 1999/10/04 12:00:00 AM

4.2.3.2 AddYears() method


This example shows how to use the AddYears() method of the DateTime class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DateTimeExample
{
class Program
{
static void Main(string[] args)
{
DateTime myDate = new DateTime(1999, 11, 17);
DateTime newMyDate = myDate.AddYears(9);
Console.WriteLine("Initial date: {0}", myDate);
Console.WriteLine("New date: {0}", newMyDate);
}
}
}

© CTI Education Group


Unit 4 – Storing Data Page 28

The result of the above application looks as follows:

Initial date: 1999/11/17 12:00:00 AM


New date: 2008/11/17 12:00:00 AM

4.2.3.3. AddHours() method


This example uses the AddHours() method of the DateTime class to add two hours to
myDate:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DateTimeExample
{
class Program
{
static void Main(string[] args)
{
DateTime myDate = new DateTime(1999, 11, 17);
DateTime newMyDate = myDate.AddHours(2);
Console.WriteLine("Initial date: {0}", myDate);
Console.WriteLine("New date: {0}", newMyDate);
}
}
}

The application will have the following result. Notice how only the time value has changed
and not the date.

Initial date: 1999/11/17 12:00:00 AM


New date: 1999/11/17 02:00:00 AM

4.2.4 Retrieving parts of a date


There are times when only part of a date is needed. For example, the calculation for the
age of a person only requires the year in which they were born. The following example
demonstrates how to retrieve the year, month, and date separately:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DateTimeExample
{
class Program
{
static void Main(string[] args)
{
DateTime myDate = new DateTime(1999, 11, 04);
int yearResult = myDate.Year;
Console.WriteLine("The year: {0}", yearResult);
int monthResult = myDate.Month;
Console.WriteLine("The month: {0}", monthResult);

© CTI Education Group


Unit 4 – Storing Data Page 29

int dateResult = myDate.Day;


Console.WriteLine("The date: {0}", dateResult);
}
}
}

The application above has the following result:

The year: 1999


The month: 11
The date: 4

The following example is very similar to the previous one, except the day (in words) will be
retrieved here:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DateTimeExample
{
class Program
{
static void Main(string[] args)
{
DateTime myDate = new DateTime(1999, 11, 04);
int yearResult = myDate.Year;
Console.WriteLine("The year: {0}", yearResult);
int monthResult = myDate.Month;
Console.WriteLine("The month: {0}", monthResult);
string dateResult = Convert.ToString(myDate.DayOfWeek);
Console.WriteLine("The day: {0}", dateResult);
}
}
}

The output should look as follows:

The year: 1999


The month: 11
The day: Thursday

4.2.5 Retrieving the current System Date and System Time


To check the current date and time of the computer system, click on the clock in the
bottom right-hand corner of the screen. The screen shown in Figure 4.11 should appear:

© CTI Education Group


Unit 4 – Storing Data Page 30

Figure 4.11 – Date and Time Properties of the computer

This is the date and time at a specific moment. The DateTime class provides a property
which can be used to access the current date and time. The following example shows
how this is done:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CurrentDateTimeExample
{
class Program
{
static void Main(string[] args)
{
DateTime curDateTime = DateTime.Now;
Console.WriteLine("The current date and time: {0}", curDateTime);
}
}
}

The result of the above example looks as follows:

The current date and time: 2009/01/12 11:16:25 AM

In order to access only the current date, the DateTime.Today property is called:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CurrentDateTimeExample
{
class Program
{
static void Main(string[] args)
{
DateTime curDateTime = DateTime.Today;

© CTI Education Group


Unit 4 – Storing Data Page 31

Console.WriteLine("The current date: {0}", curDateTime);


}
}
}

The result looks as follows:

The current date: 2009/11/21 12:00:00 AM

Note that a default time is added because it was not specified. Remember that
DateTime.Now accesses both the date and time, and DateTime.Today accesses only
the date.

4.2.6 Exercises
1. What needs to be done when passing a string value to a
DateTime variable?
2. Which method is used to subtract a month from a certain date?

4.2.7 Revision questions


1. Which one of the following is not a DateTime method?
a. AddMilliseconds()
b. AddYears()
c. Months()
d. AddMinutes()

2. True/False: The date and time must always be used together.

3. True/False: It is only possible to access the current date.

© CTI Education Group


Unit 4 – Storing Data Page 32

© CTI Education Group


Unit 4 – Storing Data Page 33

4.3 Deploying a Windows Application

At the end of this subsection, you should be able to:

 Deploy a Windows application.

4.3.1 Deploying a Windows application


Deploying an application makes it easy for other users to access it, but does not allow
them to alter the source code of the application. The technique used below is called the
ClickOnce technique. The deployed application is both installed and run when the
installer file is executed. Follow the steps below to deploy an application. Any previous
projects that have been created can be used:

 Open the project in Visual C# Express.


 Go to Build > Publish (Project Name).

The window displayed in Figure 4.12 should appear:

Figure 4.12 – Step one of Publish Wizard

 Specify the path where the application must be published.


 Click the Next > button.

© CTI Education Group


Unit 4 – Storing Data Page 34

The window displayed in Figure 4.13 should appear:

Figure 4.13 – Step two of Publish Wizard

 Select From a CD-ROM or DVD-ROM option.


 Click the Next > button.

The window displayed in Figure 4.14 should appear:

Figure 4.14 – Step three of Publish Wizard

 Select the The application will not check for updates option.
 Click the Next > button.

© CTI Education Group


Unit 4 – Storing Data Page 35

The window displayed in Figure 4.15 should appear:

Figure 4.15 – Step four of Publish Wizard

 Click the Finish button.

The folder where the application was published automatically opens. In this case, it has
been published to the desktop. The window displayed in Figure 4.16 should appear:

Figure 4.16 – Folder automatically opened

© CTI Education Group


Unit 4 – Storing Data Page 36

Notice the setup.exe file:

 Double-click on the setup.exe file. The file will load automatically.

The window displayed in Figure 4.17 should appear:

Figure 4.17 – Application Install window

 Click on the Install button.

The application should then appear as shown in Figure 4.18:

Figure 4.18 – Application

If images are used in an application, it is very important to note the following procedure
when adding the images to the project.

Assume the application uses a Button control to display an image.

 Click on the Button control, select its Image property, and add all the images to the
resources folder as shown below in Figure 4.19:

© CTI Education Group


Unit 4 – Storing Data Page 37

Figure 4.19 – Properties window

 Click on the “…” button and the window displayed in Figure 4.17 should appear:

Figure 4.20 – Select Resource window

 Click on the Import… button and browse the folders to select the images that need to
be added to the project.
 Click the OK button and the images should now appear in the Solution Explorer
window as shown in Figure 4.21:

© CTI Education Group


Unit 4 – Storing Data Page 38

Figure 4.21 – Solution Explorer window

When the images are added to the project in this way and the application is added to any
other folder, the application will not crash since it knows where to find the images.

Select the image in the Solution Explorer window and change the following properties:

 Set the Build Action property to Content.


 Set the Copy to Output Directory property to Copy always.

The properties will look like the image displayed in Figure 4.22 below:

Figure 4.22 – Image properties

One advantage of deploying an application in this way is that the application is added to
the Start menu automatically and it can be found in the Control Panel.

Should the need to delete the deployed application ever arise, follow this procedure: go to
Start > Control Panel > Programs and Features. The application name is the same as
the project name.

 Select the application and click on the Uninstall/Change button at the top of the
window as shown in Figure 4.23:

© CTI Education Group


Unit 4 – Storing Data Page 39

Figure 4.23 – Deleting an application

4.3.2 Exercises
1. Name one advantage of deploying a Windows application.
2. What is the technique of deploying an application called?

4.3.3 Revision questions


1. True/False: The deployed application is added to the desktop only
when specified to do so.
2. True/False: Once the application is deployed it can be uninstalled
using the Programs and Features tool in the Control Panel.
3. True/False: If an application uses images, they must be imported
into the project or the application will not work correctly when
installed.

© CTI Education Group


Unit 4 – Storing Data Page 40

© CTI Education Group


Unit 4 – Storing Data Page 41

4.4 Maintaining and Supporting a Windows Application

At the end of this subsection, you should be able to:

 Describe the performance factors that should be considered when


designing a Windows application.

4.4.1 Designing a Windows application for performance


Performance is one of the most important factors that have to be taken into consideration
during the development cycle of software. Performance considerations should be made
as early as possible in the design phase. It could prove to be very costly if problems that
could have been avoided then arise later on.

Below is a list of standards for writing high-performance applications when using the .NET
Framework:

 Frequent boxing and unboxing should be avoided.


Boxing is the process whereby a value type is copied or converted to a reference type,
e.g. converting an int to an Object. Unboxing is the reverse, i.e. copying a
reference type to a value type. These processes require the creation, deletion, and
transfer of data onto the heap and stacks. As such, the overhead associated with
these tasks is very high. The use of boxing and unboxing should thus be minimized.

 The StringBuilder class should be used when manipulating and


concatenating complicated strings.
Any variables of the string data type cannot be changed once a value has been
assigned. As such, any modifications will cause a new string to be created. The
garbage collector will pick up any old string variables which creates extra overhead.
Therefore, if string values are manipulated frequently, consider using the
StringBuilder class instead of the normal string type. The StringBuilder
class handles complex and varying string values in a more efficient manner.

 Use AddRange() when working with collections.


Adding many items to a collection can be slow when the Add() method is called
repeatedly. Adding an array of items by using the AddRange() method is much more
efficient.

 Care should be taken when throwing exceptions.


Throwing exceptions are very costly and should only be done in exceptional cases.
The use of exceptions as part of the normal application flow is not recommended.

© CTI Education Group


Unit 4 – Storing Data Page 42

 Minimize calls made across processes.


Minimize the number of calls made across the network in distributed applications. The
overhead for negotiating all the network-related protocols can become very costly.

 Use the Release configuration to compile an application.


Applications set to compile in Debug mode run slower since they include extra
debugging information. When an application needs to be deployed, set it to compile in
Release mode.

 Stored procedures should be used instead of SQL statements.


Stored procedures are used to run optimally on the server-side as far as data access
is concerned. Using stored procedures instead of SQL statements whenever possible
significantly improves performance.

 Keep all databases tuned and up-to-date.


Performance can be boosted by keeping the indexes of a database up to date.
Database-intense applications benefit greatly if this is done regularly.

 Use DataReader rather than DataSet.


When sequential, read-only access is required for a particular table, use DataReader
instead of DataSet. The DataReader creates a read-only, forward-only stream
whereas the DataSet is designed for random access. Wherever possible implement
DataReader to improve performance.

 Use of auto-generated commands must be considered carefully.


When manipulating data, auto-generated commands are provided, and can be used
for convenience. Unfortunately, these also incur overhead. Use of auto-generated
commands should be a trade-off between convenience and performance.

 Minimize use of transactions.


Transactions incur overhead and should be used sparingly. When transactions are
used, keep them as short-lived as possible.

 Improve the perception of performance.


The perception of performance by the user can also be influenced by adding simple
elements to an application, such as a splash screen during loading. This provides
feedback to the user, and enhances the overall effect of user-friendliness.

© CTI Education Group


Unit 4 – Storing Data Page 43

4.4.2 Exercises
1. Why should frequent boxing and unboxing be avoided?
2. When working with collections, which method should be used in
preference to the Add() method?
3. What should be used instead of a DataSet and why?

4.4.3 Revision questions


1. True/False: The StringBuilder class should be used when
concatenating complicated strings.
2. True/False: Transactions can be used excessively, because they
incur very little overhead.
3. True/False: Performance can be boosted by keeping a database’s
indexes up to date.

© CTI Education Group


Unit 4 – Storing Data Page 44

© CTI Education Group


Unit 4 – Storing Data Page 45

4.5 Attributes

At the end of this subsection you should be able to:

 Identify attributes.
 Use single and multiple attributes.
 Use attribute targets.
 Create custom attributes.

4.5.1 What are attributes?


In .NET, an attribute is an object which provides additional information about a class,
method, or field. Once an attribute has been associated with a class, method, or field, it
can be queried at runtime using reflection. Reflection is discussed in the next section.

There are two types of attributes:

 Attributes defined in the CLR (Common Language Runtime), i.e. existing attributes.
These are also known as intrinsic attributes.
 Attributes created by the programmer to add information to the program code. These
attributes are known as custom attributes.

4.5.2 Using a single attribute


To use a single attribute, simply place it above the element it is intended to represent.
Each attribute is surrounded by square brackets ([ ]), and may have parameters passed to
it, as shown by the following example:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace AttributesExample
7 {
8 public class Attributes
9 {
10 [Obsolete("Generating error...", true)]
11 static void ObsoleteMethod() { }
12 static void Main(string[] args)
13 {
14 ObsoleteMethod();
15 }
16 }
17 }

© CTI Education Group


Unit 4 – Storing Data Page 46

Figure 4.24 shows the error message which is displayed when attempting to run this
application:

Figure 4.24 – Error produced

An error message is printed notifying that the method is obsolete. Now change the true
value on line 10 to false. The result should look like Figure 4.25 below:

Figure 4.25 – Warning produced

The program runs, but this time a warning is generated instead of an error.

4.5.3 Using multiple attributes


Like single attributes, multiple attributes are also placed above the elements that they
represent. They are also surrounded by square brackets. Multiple attributes may be
placed within these brackets, separated by commas. They can be placed in separate
square brackets, below each other:

[Obsolete, Serializable]

OR

[Obsolete]
[Serializable]

The ConditionalAttribute (found in the System.Diagnostics namespace) is used


for the following example. This attribute specifies whether or not the element it represents
is compiled, depending on a certain condition. In this case, this condition is defined using
a pre-processor declaration.

1 #define CONDITION_TRUE
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6
7 namespace MultipleAttributesExample
8 {
9 class MultipleAttributes
10 {
11 [System.Diagnostics.ConditionalAttribute("CONDITION_TRUE")]
12 static void NextMethod()
13 {

© CTI Education Group


Unit 4 – Storing Data Page 47

14 Console.WriteLine("The NextMethod() is being executed!");


15 }
16
17 static void Main(string[] args)
18 {
19 NextMethod();
20 }
21 }
22 }

This is the output:

The NextMethod() is being executed!

 Comment out line1.


 Run the program again.

Nothing appears in the command prompt window. In other words, the condition was not
met, i.e. CONDITION_TRUE did not appear in the program, so NextMethod() method
was not executed and nothing is displayed in the output.

4.5.4 Using attribute targets


Many attributes can be found in the CLR (Common Language Runtime). Attributes can be
applied to interfaces, class members, classes, and assemblies. These are known as
attribute targets and they are listed below in Table 2:

Table 2 – Attribute targets


Member name Usage
Assembly Applied to the assembly itself.
Event Applied to an event.
Field Applied to a field.
Method Applied to a method.
Module Applied to a single module.
Parameter Applied to a parameter of a method.
Property Applied to a property (both set and get, if implemented).
ReturnValue Applied to a return value.

Attribute targets are implemented as follows:

[assembly: SomeAttribute]

4.5.5 Creating custom attributes


While the CLR provides many useful predefined attributes, circumstances may call for
functionality which is not provided by them. For this reason, custom attributes can be
created. Table 3 lists attributes that are used to create custom attributes.

© CTI Education Group


Unit 4 – Storing Data Page 48

Table 3 – Attributes
Member Description
All Applied to any of the following elements: assembly, class,
class member, delegate, enum, event, field, interface,
method, module, parameter, property, return value, or struct.
Class Applied to the instance of the class.
ClassMembers Applied to classes, structs, enums, constructors, methods,
properties, fields, events, delegates, and interfaces.
Constructor Applied to a given constructor.
Delegate Applied to the delegate method.
Enum Applied to an enumerator.
Interface Applied to an interface.
Struct Applied to a struct.

All attributes are actually classes which inherit from System.Attribute. As such, an
attribute can be defined as follows:

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7
8 namespace CustomAttributeExample
9 {
10 public class CustomAttribute : Attribute { }
11 }

Note how CustomAttribute class inherits from the Attribute class on line 10. Once
the attribute has been created, it can be used anywhere in the program:

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8
9 namespace CustomAttributeExample
10 {
11 public class CustomAttribute : Attribute { }
12 [CustomAttribute()]
13 public class TesterClass { }
14 }

The example shows how CustomAttribute is created and inherits the Attribute
class on line 11. The custom attribute CustomAttribute is then used on line 12 and will
represent the TesterClass class on line 13.

© CTI Education Group


Unit 4 – Storing Data Page 49

4.5.6 Exercises
1. Name the process which can be used to access attributes at
runtime.
2. Name the two types of attributes.
3. What are attribute targets?

4.5.7 Revision questions


1. Which one of the following is not an attribute target?
a. ClassMembers
b. ClassAttribute
c. All
d. Property

2. True/False: Single or multiple attributes can be used.

3. True/False: Custom attributes extend the System.Attribute


class.

© CTI Education Group


Unit 4 – Storing Data Page 50

© CTI Education Group


Unit 4 – Storing Data Page 51

4.6 Reflection

At the end of this subsection you should be able to:

 Understand what reflection is and for what it is used.


 Obtain information about a class and its members.
 Understand the basics of dynamically activated code and
Reflection.Emit.

4.6.1 Reflection
Reflection and attributes go hand in hand. Reflection only occurs during runtime. This is
done using classes in the Reflection namespace, as well as the System.Type and
System.TypedReference classes.

Reflection is commonly used in the following cases:

 Viewing metadata – used by tools that want to display metadata.


 Performing type discovery – allows the examination of the types in an assembly and
then allows either interaction with, or instantiation of, those types.
 Late binding of methods and properties – allows the programmer to invoke
properties and methods on objects which have been instantiated dynamically.
 Creating types at runtime (Reflection.Emit) – one of the most powerful functions
of reflection is its ability to create new types at runtime.

Figure 4.26 should help to clarify the inheritance hierarchy:

© CTI Education Group


Unit 4 – Storing Data Page 52

Figure 4.26 – Reflection inheritance hierarchy

Figure 4.26 begins with the assembly at the top of the hierarchy. The assembly is a
partially compiled code library which takes the form of an executable file. An assembly
may consist of one or more script files, referred to as modules. Each module can consist
of one or more types (i.e. class, delegate, enum, or struct). Each type may consist
of one or more events, fields, properties, and/or methods. The inheritance hierarchy
should be kept in mind when progressing through this section.

4.6.2 Obtaining information about a class and its members


Reflection is primarily used to obtain information about classes at runtime. The following
example shows how this can be done:

© CTI Education Group


Unit 4 – Storing Data Page 53

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Reflection;
6
7 namespace ReflectionExample
8 {
9 class ReflectionEx
10 {
11 static void Main(string[] args)
12 {
13 string inputString = "";
14 do
15 {
16 Console.WriteLine("Choose an option: (1, 2, " +
17 "3 or q)");
18 Console.WriteLine("1. System.String");
19 Console.WriteLine("2. System.Int32");
20 Console.WriteLine("3. System.Console");
21 Console.WriteLine("4. Quit (q)");
22
23 inputString = Console.ReadLine();
24
25 if (inputString == "1")
26 {
27 displayInfo(typeof(System.String));
28 }
29 else if (inputString == "2")
30 {
31 displayInfo(typeof(System.Int32));
32 }
33 else if (inputString == "3")
34 {
35 displayInfo(typeof(System.Console));
36 }
37 else
38 {
39 inputString = "q";
40 }
41 } while (inputString != "q");
42 }
43
44 static void displayInfo(Type type)
45 {
46 // Obtain information about the types of methods
47 MemberInfo[] m = type.GetMethods();
48 foreach (MemberInfo mem in m)
49 {
50 Console.WriteLine("Method: " + mem);
51 }
52
53 // Obtain information about the types of interfaces
54 m = type.GetInterfaces();
55 foreach(MemberInfo mem in m)
56 {
57 Console.WriteLine("Interfaces: " + mem);
58 }
59 // Obtain information about the types of fields
60 m = type.GetFields();
61 foreach(MemberInfo mem in m)

© CTI Education Group


Unit 4 – Storing Data Page 54

62 {
63 Console.WriteLine("Fields: " + mem);
64 }
65 }
66 }
67 }

The first thing to note in the above example is that System.Reflection has to be
imported (line 5) to be able to apply reflection. Lines 15 to 20 prints a menu from which
the user will have to select an option. Line 22 reads the input from the user and from line
24 to 41 the input is interpreted and checked so that necessary methods are performed.
These activities occur within a do…while loop (refer to Unit one).

The displayInfo() method on line 46 displays one of three options that may have been
selected by the user. It will display either method information by using GetMethods(),
interface information by using GetInterfaces(), or field information by using
GetFields().

The Type class is at the root of all reflection classes and is therefore the primary way to
access metadata. The typeof operator returns an object of the type Type. The
MemberInfo class is derived from the Type class and encapsulates information about the
class members. These include methods, properties, fields, and events. MemberInfo is
provided to discover the attributes of a member and to provide access to metadata.

4.6.3 Dynamically activating code and Reflection.Emit


Dynamic code activation is the ability to determine at runtime what code will be executed.
The Reflection.Emit API allows for a new assembly to be created dynamically. Using
such customised builders and generating MSIL (Microsoft Intermediate Language) code
enables programs to create a new program at runtime. These assemblies are dynamically
invoked or saved where they can be reloaded and invoked by other programs.

Dynamic code creation and activation is a complicated concept. A general knowledge of


the topic will suffice for examination purposes.

4.6.4 Exercises
1. How can reflection be used in late binding?
2. The “Type” level in the inheritance hierarchy can be a(n) _______,
_________, _________, or _________.

4.6.5 Revision questions


1. True/False: The GetFields() method is used to retrieve
information about a field.
2. True/False: The System.Reflection namespace has to be
specified at the top of the program to be able to use reflection.

© CTI Education Group


Unit 4 – Storing Data Page 55

4.7 File I/O

At the end of this subsection, you should be able to:

 Use the File and Directory classes.


 Use streams to read and write data to files.
 Encrypt and decrypt data using CryptoStreams.
 Change standard input and output.

4.7.1. File input and output


The root of all file input and output stems from the System.IO namespace. Input and
output refers to the reading and writing of data to files and streams. Classes found in the
System.IO namespace are used to perform basic operations such as creating, deleting,
and copying files.

4.7.2 Files and Directories


Four classes from the System.IO namespace are used to work with files and directories.
Table 4 below lists these classes as well as important methods within the particular class:

Table 4 – File and directory classes


Directory Class
Methods Function
CreateDirectory Creates a directory in a specified path. If the directory’s parent
does not exist, it is also created.
Delete Deletes an existing directory.
Exists Returns true if the specified directory exists, otherwise it returns
false.
GetDirectories Returns an array of strings containing all subdirectories of a
directory.
GetFiles Returns all the files in a directory.
Move Moves a specified directory and all of its subdirectories and files
to a new location.
DirectoryInfo Class
Methods Function
Create Creates a file in a specified directory. Same as Create in the
File and FileInfo classes.

© CTI Education Group


Unit 4 – Storing Data Page 56

File Class
Methods Function
Create Creates a file in a specified directory.
CreateText Creates a file and returns a StreamWriter object that can be
used to write text to that file.
AppendText Returns a StreamWriter object to a specific existing file. The
text will be appended to the end of the file. If the file does not
exist, AppendText creates one.
Exists Returns true if a file in a specific path exists, otherwise it returns
false. It only has a path and filename as parameters.
Copy Copies a file into another folder.
Move Moves a file to another directory.
Open Opens a file and returns the FileStream object.
OpenRead Opens a file as read-only and returns the FileStream object.
OpenText Opens a file and returns the StreamReader object.
OpenWrite Opens a file and returns the Stream object.
GetAttributes Obtains the file’s attributes and returns a bitwise combination.
SetAttributes Changes the attributes of a file.
FileInfo Class
Methods Function
Create Same as Create from the File class. It creates a file in a
specified directory.

Here are a few important facts to know when working with files and directories:

 Both the File and FileInfo classes can be used to create files. However, the
usage of each is slightly different:

// The File class:


FileStream fs = File.Create("C:/data/newFile.txt");
fs.Close();

// The FileInfo class:


FileInfo fileInfo = new FileInfo("C:/data/newFile.txt");
FileStream fs = fileInfo.Create();
fs.Close();

 Always close the FileStream object.


 When creating, appending, moving, or deleting a file or directory, two properties are
used: FileMode and FileAccess.
 The FileMode property can have one of the following values:
o Append
o Create
o Open
o OpenOrCreate
o Truncate

© CTI Education Group


Unit 4 – Storing Data Page 57

 The FileAccess property can have one of the following values:


o Read
o ReadWrite
o Write

The example below uses Open and Read:

FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);

4.7.3 Streams
The Stream class is primarily used to transfer data from one place to another. The
Stream class provides functionality to manipulate streams, but is itself an abstract class.
Subclasses such as FileStream, BufferedStream, and CryptoStream inherit from it
to provide specific functionality. Table 5 lists the most common methods of the Stream
class:

Table 5 – Common methods of the Stream class


Method Description
Close() Closes the Stream object and frees resources. The Stream object
must always be closed.
Read() Reads available data to array of bytes and returns an integer indicating
the number of bytes read. Zero is returned at the end of the stream.
Write() Writes an array of bytes into the stream. It does not return a value.

The FileStream class is used to read and write bytes to a file. FileStream objects are
frequently used in conjunction with BufferedStream objects, which can improve
performance. The example below creates a file and writes three bytes to it. If the file
already exists then the information stored in that file will be overwritten.

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.IO;
6
7 namespace FileStreamExample {
8 class Program
9 {
10 static void Main(string[] args)
11 {
12 FileStream fs = new FileStream("C:/newBytes.txt", FileMode.Create);
13 Byte[] bytes = new Byte[3];
14 bytes[0] = 50;
15 bytes[1] = 51;
16 bytes[2] = 52;
17 fs.Write(bytes, 0, 3);
18 fs.Close();
19 }
20 }
21 }

© CTI Education Group


Unit 4 – Storing Data Page 58

The Write() method on line 17 contains three parameters. The general syntax looks as
follows:

FileStream.Write(bytes[]array, int startPosition, int count)

The first parameter takes the bytes array. The second parameter indicates the position in
the array from which the bytes are retrieved, and the last parameter indicates how many
bytes must be read from the array.

4.7.4 Reading and writing


Table 6 lists the classes that are used to write and read to and from files:

Table 6 – Classes used for reading and writing


Class Description
StreamReader Inherits from the TextReader class and is used to read streams of
data.
StreamWriter Inherits from the TextReader class and is used to write data to a
stream.
BinaryReader Used to read binary data from a file.
BinaryWriter Used to write binary data to a stream.

4.7.4.1 StreamReader Class


The StreamReader class can be used to read one character at a time with the Read()
method or read one line at a time with the ReadLine() method. The ReadToEnd()
method can also be used to read an entire stream (i.e. the entire file) at once. In order for
the example below to work:

 Create a new text file in the file c:\Examples\.


 Enter the following text into it: “This text is read by a StreamReader object”.
 Create a new Console Application and name it StreamReaderExample.

The following example demonstrates how to use a StreamReader in a simple program.


Always remember to use the System.IO namespace when reading and writing data:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace StreamReaderExample
{
class Program
{
static void Main(string[] args)
{
StreamReader sr = new StreamReader("c:/StreamReader.txt");

© CTI Education Group


Unit 4 – Storing Data Page 59

string byLine = sr.ReadLine();

if (byLine != null)
{
Console.WriteLine(byLine);
byLine = sr.ReadLine();
}
else
{
Console.WriteLine("File is empty!");
}
sr.Close();
}
}
}

The output of the example looks as follows:

This text is read by a StreamReader object.

The BufferedStream class is used to wrap the Stream class and improve performance.
Note that the BufferedStream class is derived from the Stream class and therefore
inherits the methods and properties of the Stream class.

4.7.4.2 StreamWriter Class


The StreamWriter class has two important methods:

 Write() enables a single character, an array of characters, or a string to be written to


a file.
 WriteLine() accepts a string and adds an end-of-line character to the end of the
string.

 Create a new console application named StreamWriterExample.

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.IO;
6
7 namespace StreamWriterExample
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 FileStream fs = new FileStream("c:/Examples/StreamWriter.txt",
14 FileMode.Create);
15 BufferedStream bs = new BufferedStream(fs);
16 Console.WriteLine("File created...");
17 fs.Close();
18
19 StreamWriter sw = new
20 StreamWriter("c:/Examples/StreamWriter.txt");
21 Console.WriteLine("Writing to a file...");
22 sw.WriteLine("Using the StreamWriter to write data to this " +

© CTI Education Group


Unit 4 – Storing Data Page 60

23 "file");
24 sw.Close();
25 }
26 }
27 }

The output of this example looks as follows:

File created...
Writing to a file...

Line 13 creates a new text file on the c drive in the Examples folder. Remember to close
the FileStream object first (as done on line 17) before proceeding, otherwise the
application will cause an exception and the application will exit. Note the
BufferedStream object used on line 15.

In order to see the full extent of the example, go to the Examples folder and open the text
file. The text in swLine is displayed in the file.

4.7.4.3 BinaryReader Class


The BinaryReader class has two important methods: ReadByte() and
ReadString(). The ReadByte() method is used to read a byte and the
ReadString() method is used to read a string. The BinaryReader class is rarely
used, but it can prove useful in certain situations. The following example shows how this
class can be used:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace BinaryReaderExample
{
class Program
{
static void Main(string[] args)
{
BinaryReader br = new BinaryReader(File.OpenRead
("c:/BinaryReader.bin"));
Byte b = br.ReadByte();
string s = br.ReadString();
Console.WriteLine(b);
Console.WriteLine(s);
br.Close();
}
}
}

4.7.4.4 BinaryWriter Class


The BinaryWriter class provides a Write() method which is used to write data to a
stream.

© CTI Education Group


Unit 4 – Storing Data Page 61

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace BinaryWriterExample
{
class Program
{
static void Main(string[] args)
{
BinaryWriter bw = new BinaryWriter(File.Create("c:/BinaryWriter.bin"));
string str = "Hello";
Byte b = 10;
bw.Write(str);
bw.Write(b);
// Always remember to close the BinaryWriter.
bw.Close();
}
}
}

4.7.5 CryptoStreams
CryptoStreams are used to write encrypted data to a file and decrypt data read from a
file. The encryptor and decryptor need to use the same byte array to be able to decrypt
the message written. The CryptoStream class inherits from the Stream class and
contains the methods listed in Table 7.

Table 7 – CryptoStream methods


Method Description
Clear() Releases all the resources used by the CryptoStream.
Close() Closes the current stream and releases all resources.
Read() Reads a sequence of bytes from the current CryptoStream.
ReadByte() Reads a byte from a stream. Returns -1 if the end of the stream
is reached.
SetLength() Sets the length of the current stream.
Write() Writes a sequence of bytes to the current CryptoStream.
WriteByte() Writes a byte to the current position in the stream.

4.7.6 Standard I/O


In almost every example throughout this study guide, standard input and output has been
used. Standard I/O refers to the default input/output stream used by the operating system,
which in .NET is usually the Console. The ReadLine() method has been used to read
input from the keyboard, and the Write() and WriteLine() methods have been used
to display output on the console.

© CTI Education Group


Unit 4 – Storing Data Page 62

The following methods of the Console class can be used to change the location of the
input and output:

Console.SetIn(TextReader);
Console.SetIn(TextWriter);
Console.SetError(TextWriter);

The following example changes the standard error stream to a log file named
LogBobError.txt and the standard output to a file named OutFile.txt. The standard input
is received via the keyboard.

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.IO;
6
7 namespace StandardIOExample
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 Console.Out.WriteLine("Enter a few names:");
14
15 StreamWriter streamOut = new StreamWriter(new FileStream
16 ("c:/OutFile.txt", FileMode.Create, FileAccess.ReadWrite));
17
18 StreamWriter streamError = new StreamWriter(new FileStream
19 ("c:/LogBobError.txt", FileMode.Create));
20
21 Console.SetOut(streamOut);
22
23 Console.SetError(streamError);
24
25 String str = null;
26
27 do
28 {
29 str = Console.ReadLine();
30 Console.Out.WriteLine(str);
31
32 if (str.Equals("Bob"))
33 {
34 Console.Error.WriteLine("'Bob' was entered!");
35 }
36 } while (!str.Equals(""));
37
38 Console.Out.Close();
39 Console.Error.Close();
40 }
41 }
42 }

© CTI Education Group


Unit 4 – Storing Data Page 63

The Console.Out.WriteLine() method on line 13 uses the default output stream that
is printed to the console. All text input from line 15 onwards is written to the
OutFile.txt file. The program concludes when no text is entered and <ENTER> is
pressed. If “Bob” was one of the names entered, “’Bob’ was entered!” will be written to the
LogBobError.txt file.

The input and output in the command prompt should look as follows:

Enter a few names:


Angelique
Brian
Bob
Kyle
Carla
Luke

Press any key to continue . . .

Figure 4.27 shows what the OutFile.txt file looks like after the application is run:

Figure 4.27 – The OutFile.txt file

Figure 4.28 below shows what the LogBobError.txt file looks like:

Figure 4.28 – The LogBobError.txt file

© CTI Education Group


Unit 4 – Storing Data Page 64

4.7.7 Exercises
1. Which namespace is used for file input and output?

2. Name four options which can be used with the FileMode property.

3. What is the function of the Read() method of the StreamReader


class?

4. Create a Windows Form application which contains a File menu


with New, Save, and Exit menu items. The application must have
a large text box which takes up the rest of the form. When the user
clicks on the New menu item the text box must be cleared. When
the user clicks on the Save menu item a SaveFileDialog must
be used to choose the path and name of the file, and the contents
of the text box must be written to that file. The Exit menu item
must exit the application.

5. Create an application which displays information about a file


specified by the user. A backup of the file must then be created.

4.7.8 Revision questions


1. Which one of the following methods does not belong to the
Directory class?
a. GetFiles()
b. Delete()
c. Create()
d. CreateDirectory()

2. True/False: The FileStream object should always be closed.

3. True/False: The BinaryReader class uses the Read() method


to read a byte.

4. Which one of the following methods is not part of the


CryptoStream class?
a. ClearByte()
b. ReadByte()
c. Write()
d. WriteByte()

© CTI Education Group


Unit 4 – Storing Data Page 65

4.8 ADO.NET

At the end of this subsection you should be able to:

 Create a database.
 Create a connection to a database.
 Select and display data from a database.
 Manipulate data in a database.
 Populate a data source with DataSet.

4.8.1 Introduction to ADO.NET


ADO.NET is a library which allows interaction with data sources. For this course, a
database is used as the data source. The two databases used are Microsoft Access and
Microsoft SQL Server. This course uses Microsoft Access 2007 and Microsoft SQL Server
2008 to demonstrate all the relevant concepts.

4.8.2 ADO.NET overview


ADO.NET allows applications to interact with data sources such as a database. However,
the right information needs to be retrieved from the right data source, using the right
protocol. The ADO.NET libraries provide common methods of data source interaction so
that different data source types can be worked with in a similar manner. These Data
providers are named according to the data source type for their intended use. This
course uses only the OleDb Data Provider. Table 8 below lists the most common data
providers:

Table 8 – Data Providers


Data Provider Prefix Description
ODBC Data Provider Odbc Data Sources with an ODBC interface.
Normally older databases.
OleDb Data Provider OleDb Data Sources that expose an OleDb interface,
i.e. Access or Excel.
Oracle Data Provider Oracle For Oracle Databases.
SQL Data Provider Sql For interacting with Microsoft SQL Server.
Borland Data Provider Bdp Generic access to many databases such as
Interbase, SQL Server, IBM DB2, and Oracle.

Table 9 lists the core classes of the OleDb data provider:

© CTI Education Group


Unit 4 – Storing Data Page 66

Table 9 – Core classes of the OleDb Data Provider


Class Description
OleDbConnection Establishes a connection to a specific data source.
OleDbCommand Executes a command against a data source.
OleDbDataReader Creates a forward-only, read-only data stream form an OleDb
data source.
OleDbDataAdapter Populates a DataSet and resolves updates with the data
source.

10 shows the core classes of the SQL data provider:

Table 10 – Core classes of the SQL Data Provider

Class Description
SqlConnection A SqlConnection object represents a connection to a SQL
Server data source. It can be used together with SqlCommand
and SqlDataAdapter to increase performance when
connecting to a Microsoft SQL Server database.
SqlCommand A SqlCommand object executes commands at a SQL Server
database, e.g. ExecuteReader and ExecuteNonQuery.
These will be dealt with in more detail at a later stage.
SqlDataReader The SqlDataReader object creates a way of reading a
forward-only stream of rows from a SQL Server database. The
ExecuteReader (as mentioned above) is used in conjunction
with the SqlDataReader.
SqlDataAdapter The SqlDataAdapter object represents a set of data
commands and a database connection that are used to fill a
DataSet (this will be dealt with in more detail at a later stage)
and update a SQL Server database.

4.8.3 Creating the database using MS Access


 Open Microsoft Access (Start > All Programs > Microsoft Office)
 Create a new database called Salon.
 Create two tables. Call the first table Client and the second Appointment.
 Set up the fields as shown in Table 11 and Table 12.

NOTE
MS Access 2007 is used here to create the tables.

© CTI Education Group


Unit 4 – Storing Data Page 67

Table 11 – Client table in the Salon database


CLIENT
Field Name Type Constraints
UniqueID AutoNumber Primary Key, not null
Name Text Not null
Surname Text
Address Text
Telephone Text Not null

Table 12 – Appointment table in the Salon database


APPOINTMENT
Field Name Type Constraint
UniqueID Number Not null
Date Date/Time Not null
Time Date/Time Not null

The UniqueID value in the Appointment table refers to the UniqueID of the client for whom
the appointment was made. Therefore, a relationship must be created between the
UniqueID fields in each table. It is not necessary to enforce referential integrity for this
relationship. Make a note of where the database is saved because it will be needed when
specifying the path.

 Add some sample data to each table.


 Save the database file in a location where it will be easy to find later.

The completed Client table should look like Figure 4.29:

Figure 4.29 – Data added to the Client table

On the left-hand side of the table, next to the UniqueID field, there is a small +. Click on it
to expand the Appointment table (as in Figure 4.30). It is possible to expand the table in
this way because a relationship was created between the tables and they are linked by the
UniqueID field.

© CTI Education Group


Unit 4 – Storing Data Page 68

Figure 4.30 – Appointment table expanded within the Client table

The Appointment table should look like Figure 4.31:

Figure 4.31 – Data added to the Appointment table

4.8.4 Creating the database using Microsoft SQL Server


 Open SQL Server Management Studio (Start > All Programs > Microsoft SQL
Server 2008 > SQL Server Management Studio).
 Create a new database called Salon.
 Create two tables. Call the first table Client and the second table Appointment.
 Set up the fields as shown below.

USE master
GO

IF EXISTS (SELECT name FROM master.dbo.sysdatabases


WHERE name = 'Salon')
DROP DATABASE Salon
GO

CREATE DATABASE Salon


ON PRIMARY
(

© CTI Education Group


Unit 4 – Storing Data Page 69

-- this and below is the primary database creation


NAME ='Salon_data.MDF',
FILENAME = 'C:\Salon_data.sdf',
SIZE = 5MB,
FILEGROWTH = 10%
)
LOG ON
(
-- this and below is the log file creation
NAME ='Salon_log.ldf',
FILENAME = 'C:\Salon_log.ldf',
SIZE = 5MB,
FILEGROWTH = 10%
)
GO

USE Salon
GO

CREATE TABLE CLIENT


(
UniqueID INT NOT NULL IDENTITY (1,1),
Name VARCHAR(40) NOT NULL,
Surname VARCHAR(40) NOT NULL,
Address VARCHAR(90) NOT NULL,
Telephone VARCHAR(15) NOT NULL
PRIMARY KEY (UniqueID)
)
GO

CREATE TABLE APPOINTMENT


(
UniqueID INT NOT NULL REFERENCES Client(UniqueID),
Date DATETIME NOT NULL,
Time DATETIME NOT NULL
)
GO

 Press the Execute button in SQL Server Management Studio to execute the script file
and insert the tables.
 Create another script file which will insert sample data into the tables that have just
been created. The script file may look something like the one shown below.

USE Salon
GO

INSERT INTO CLIENT (Name, Surname, Address, Telephone)


VALUES ('Bob', 'Smith', '12 Peach street', '0114678422')
GO

INSERT INTO CLIENT (Name, Surname, Address, Telephone)


VALUES ('Brian', 'Scott', '12 Oleander street', '0825055972')
GO

 If you would like to see how the data was inserted into the tables, enter the following in
a new script file. This should not be anything new to you as this was explained in
detail during the SQL Server module.

© CTI Education Group


Unit 4 – Storing Data Page 70

USE Salon
GO
SELECT * FROM CLIENT
GO

The image shown in Figure 4.32 should be displayed at the bottom of the SQL Server
Management Studio:

Figure 4.32 – Data in the SQL table

4.8.5 Creating a connection to the database using MS Access


 Create a new Console Application and name it DatabaseExample.

Firstly add the database to the project.

 Click on Project > Add Existing Item… as shown in Figure 4.33:

Figure 4.33 – Adding an Access database to a project

A window appears where the path of the database must be selected. Make sure the file
type is changed to Data Files on the right-hand side of this window.

 Select the MS Access 2007 database (Salon.accdb) and select Add.

© CTI Education Group


Unit 4 – Storing Data Page 71

The Data Source Configuration Wizard window will appear as shown in Figure 4.34.

 Click the Cancel button.

No tables or views are selected here because we do not need to create a data source.

Figure 4.34 – Data Source Configuration Wizard window

The database will now appear on the right side of the screen in the Solution Explorer as
shown in Figure 4.35:

Figure 4.35 – Add Existing Item… dialog

© CTI Education Group


Unit 4 – Storing Data Page 72

 Modify the Program class to match the following:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Data;
6 using System.Data.OleDb;
7
8 namespace DatabaseExample
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 string connString = "Provider=Microsoft.ACE.OleDb.12.0;" +
15 "Data Source=../../Salon.accdb";
16 OleDbConnection conn = new OleDbConnection(connString);
17 conn.Open();
18 }
19 }
20 }

Take note of the connection string that is used in lines 14 and 15.

There are two new namespaces: System.Data and System.Data.OleDb. These must
be added in order to work with ADO.NET and databases. The connection string can also
include a user ID and password, but this is not necessary for a Microsoft Access database
unless it has been password-protected.

The connection string highlights one advantage of importing the database into the project.
If this had not been done, the absolute path to the database would need to have been
specified. However, because the database has been imported, a simpler, relative path
can be used.

NOTE Relative paths should be used whenever possible. It is difficult to move


applications that use absolute paths to different computers as they will only
work correctly if the application and the files which it uses or references are in
specific locations.

4.8.6 Creating a connection to the database using Microsoft SQL Server


When using a SQL database, ensure that the database was created on the computer on
which the application is being created. If this is not so, an error will occur. Take note that
a new using statement is required to work with SQL objects. This namespace is
Imports System.Data.SqlClient and it replaces the
Imports System.Data.OleDb namespace when using MS Access.

 Create a new Console Application and name it DatabaseExample2.


 Add the SQL database (Salon.mdb) that has already been created in the same way
that the MS Access 2007 database was added to the project. If permissions prevent
you from adding the database, go back to the script file and change the path so that
the database is created directly in the project folder.

© CTI Education Group


Unit 4 – Storing Data Page 73

 Modify the Program class to match the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace DatabaseExample2
{
class Program
{
static void Main(string[] args)
{
string connString = "Integrated Security=SSPI; " +
"Initial Catalog=Salon; " +
"Data Source=localhost";
SqlConnection sqlConn = new SqlConnection(connString);
sqlConn.Open();
}
}
}

There are some subtle changes in the connection string which are easy to spot. The
Initial Catalog in the connection string is the name of the database being used, and
the Data Source is the name of the PC on which you are working. To avoid errors with
the Data Source when moving the application to another computer, the localhost
keyword will be acceptable. This basically acts a replacement for the name of the PC.

4.8.7 Selecting data using MS Access


Selecting data requires a SQL query which specifies the data that must be selected from
the specified table. The following example creates a query and then executes it:

OleDbCommand cmd = conn.CreateCommand();


cmd.CommandText = "SELECT * FROM Client";
OleDbDataReader reader = cmd.ExecuteReader();

4.8.8 Selecting data using Microsoft SQL Server


Selecting data using Microsoft SQL Server is very similar to selecting data using MS
Access. The only thing that changes is the objects used, as shown in the code below:

SqlCommand cmd = sqlConn.CreateCommand();


cmd.CommandText = "SELECT * FROM CLIENT";
SqlDataReader reader = cmd.ExecuteReader();

OR

SqlCommand cmd = new SqlCommand("SELECT * FROM CLIENT", sqlConn);


SqlDataReader reader = cmd.ExecuteReader();

© CTI Education Group


Unit 4 – Storing Data Page 74

4.8.9 Displaying data


When a query is used to retrieve data from a database, it is not uncommon for the exact
number of records retrieved to be unknown. For this reason, it is often preferable to use a
loop to iterate through each of the records that are returned. Reading and displaying data
is done exactly the same in MS Access and Microsoft SQL Server.

while (reader.Read())
{
int uniqueID = (int)reader["UniqueID"];
string name = (string)reader["Name"];
string surname = (string)reader["Surname"];
string address = (string)reader["Address"];
string telephone = (string)reader["Telephone"];

Console.WriteLine("ID: {0} Name: {1} Surname: {2} Address: {3} " +


"Telephone: {4}", uniqueID, name, surname, address, +
telephone);
}

The OleDbDataReader and SqlDataReader provide an indexer which is used to


access data which has been retrieved from that database. The indexer is overloaded and
can accept either a string value (which specifies the column name to retrieve) or an
int value (which specifies the column index to retrieve). If an invalid column name or
index is specified, an exception will be thrown. If the column name differs from the one
provided, an error will occur. The following syntax is used to access data from an
OleDbDataReader or a SqlDataReader:

data-type variableName = (data-type)reader[field-name];

In addition to the index operator, the OleDbDataReader and SqlDataReader classes


provide various Get methods which can be used to obtain data without needing to unbox
it. These Get methods retrieve data from a specific column index.

int uniqueID = reader.GetInt16(0);


string name = reader.GetString(1);
string surname = reader.GetString(2);
string address = reader.GetString(3);
string telephone = reader.GetString(4);

All the data above was retrieved with knowledge of the data type. If the data type is
unknown, the GetValue() method is used instead of the GetInt16() or GetString()
methods:

Console.WriteLine("Name: " + reader.GetValue(1));

4.8.10 MS Access database example


So far, all the basic concepts of the database have been explained. Up to this point the
following concepts should be quite familiar: connecting to a database, retrieving data, and
displaying the retrieved data. All the previous smaller examples are now combined to form
the example shown below.

© CTI Education Group


Unit 4 – Storing Data Page 75

Remember that any exceptions that may occur must be caught (this will be included in all
subsequent examples). The OleDbException is caught in the example below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace DatabaseExample
{
class Program
{
static void Main(string[] args)
{
try
{
string connString = @"Provider=Microsoft.ACE.OleDb.12.0;
Data Source=Salon.accdb";
// Connection to the database.
OleDbConnection conn = new OleDbConnection(connString);
// Opening the database.
conn.Open();

OleDbCommand cmd = conn.CreateCommand();


// SQL query used to retrieve data.
cmd.CommandText = "SELECT * FROM Client";
OleDbDataReader reader = cmd.ExecuteReader();

// Loop that reads all records in the dbReader.


while (reader.Read())
{
// Assigns the data in each field to a variable.
int uniqueID = (int)reader["UniqueID"];
string name = (string)reader["Name"];
string surname = (string)reader["Surname"];
string address = (string)reader["Address"];
string telephone = (string)reader["Telephone"];

// Displays the retrieved data to the console.


Console.WriteLine("ID: {0}, Name: {1}, Surname: {2}, " +
"Address: {3}, Telephone: {4}", uniqueID, name, surname,
address, telephone);
}

conn.Close();
}
catch (OleDbException ole)
{
Console.WriteLine(ole.Message);
}
}
}
}

© CTI Education Group


Unit 4 – Storing Data Page 76

The outcome of the application above looks as follows:

ID: 1, Name: Angelique, Surname: Kolle, Address: 58 First Ave, Alberton North,
Telephone: 0735149000
ID: 2, Name: Brian, Surname: Scott, Address: 12 Peach Str, Primrose,
Telephone: 0825055972
ID: 3, Name: Kim, Surname: Crous, Address: 109 West Str, Johannesburg,
Telephone: 0765894258
ID: 4, Name: Bradley, Surname: Smith, Address: 23 Seventh Ave, Sandton,
Telephone: 0796584123
Press any key to continue. . .

In the code above, the @ symbol is used. This allows the connection string value to be
read as a whole. This means it is read as if it was never split by the line.

4.8.11 Microsoft SQL Server database example


The example shown below performs the exact same methods as the previous example. It
is shown here to demonstrate how the same operations would be done using SQL.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace SqlConnectionApplication
{
class Program
{
static void Main(string[] args)
{
string stringConn = @"Integrated Security=SSPI;
Initial Catalog=Salon;
Data Source=localhost";
SqlConnection sqlConn = new SqlConnection(stringConn);

try
{
sqlConn.Open();

SqlCommand cmd = new SqlCommand("SELECT * FROM CLIENT", sqlConn);


SqlDataReader reader = cmd.ExecuteReader();

while (reader.Read())
{
// Assigns the data in each field to a variable.
int uniqueID = (int)reader["UniqueID"];
string name = (string)reader["Name"];
string surname = (string)reader["Surname"];
string address = (string)reader["Address"];
string telephone = (string)reader["Telephone"];

// Displays the retrieved data to the console.


Console.WriteLine("ID: {0}, Name: {1}, Surname: {2}, " +
"Address: {3}, Telephone: {4}", uniqueID, name, surname,
address, telephone);
}

© CTI Education Group


Unit 4 – Storing Data Page 77

sqlConn.Close();
}
catch (SqlException se)
{
Console.WriteLine(se.Message);
}
}
}
}

The outcome of the above application looks as follows:

ID: 10, Name: Angelique, Surname: Kolle, Address: 58 First Ave, Alberton
North, Telephone: 0735149000
ID: 11, Name: Brian, Surname: Scott, Address: 12 Peach Str, Primrose,
Telephone: 0825055972
ID: 12, Name: Kim, Surname: Crous, Address: 109 West Str, Johannesburg,
Telephone: 0765894258
ID: 13, Name: Bradley, Surname: Smith, Address: 23 Seventh Ave, Sandton,
Telephone: 0796584123
Press any key to continue . . .

4.8.12 Field count


The OleDbDataReader and SqlDataReader classes contain a property called
FieldCount which keeps track of how many columns there are in any particular row.

The following example shows how this can be done using an OleDb connection:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 // Namespaces needed to work with ADO.NET.
6 using System.Data;
7 using System.Data.OleDb;
8
9 namespace DatabaseExample
10 {
11 class Program
12 {
13 static void Main(string[] args)
14 {
15 try
16 {
17 string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;
18 Data Source=../../Salon.accdb";
19 // Connection to the database.
20 OleDbConnection conn = new OleDbConnection(connString);
21 // Opening the database.
22 conn.Open();
23
24 OleDbCommand cmd = conn.CreateCommand();
25 // SQL query used to retrieve data.
26 cmd.CommandText = "SELECT * FROM Client";
27
28 OleDbDataReader reader = cmd.ExecuteReader();
29

© CTI Education Group


Unit 4 – Storing Data Page 78

30 // Loop that reads all records in the dbReader.


31 while (reader.Read())
32 {
33 // Assigns the data in each field to a variable.
34 int uniqueID = (int)reader["UniqueID"];
35 string name = (string)reader["Name"];
36 string surname = (string)reader["Surname"];
37 string address = (string)reader["Address"];
38 string telephone = (string)reader["Telephone"];
39
40 // Displays the retrieved data to the console.
41 Console.WriteLine("ID: {0}, Name: {1}, Surname: {2} " +
42 "Address: {3}, Telephone: {4}", uniqueID, name, surname,
43 address, telephone);
44 }
45 int fieldCount = reader.FieldCount;
46 Console.WriteLine();
47 Console.WriteLine("There are {0} columns!", fieldCount);
48 Console.WriteLine();
49
50 conn.Close();
51 }
52 catch (OleDbException odbe)
53 {
54 Console.WriteLine(odbe.Message);
55 }
56 }
57 }
58 }

Lines 45 to 48 have been added to the previous example. The output looks as follows:

ID: 1, Name: Angelique, Surname: Kolle, Address: 58 First Ave, Alberton North,
Telephone: 0735149000
ID: 2, Name: Brian, Surname: Scott, Address: 12 Peach Str, Primrose,
Telephone: 0825055972
ID: 3, Name: Kim, Surname: Crous, Address: 109 West Str, Johannesburg,
Telephone: 0765894258
ID: 4, Name: Bradley, Surname: Smith, Address: 23 Seventh Ave, Sandton,
Telephone: 0796584123

There are 5 columns!

Press any key to continue . . .

The only difference in the result is the addition of the last line that indicates how many
columns there are in the current row. The number of rows can be counted using a SQL
connection in exactly the same way as with the OleDb connection (as shown above). Use
the example in section 4.8.11 and add the FieldCount property.

4.8.13 Column names


Just as there is a way to determine how many columns exist in the current row, there is
also a way to determine the name of each column. The GetName() method can be used
to determine the name of any column given the column index. The example from the
previous section (4.8.12) is used with the GetName() method:

© CTI Education Group


Unit 4 – Storing Data Page 79

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 // Namespaces needed to work with ADO.NET.
6 using System.Data;
7 using System.Data.OleDb;
8
9 namespace DatabaseExample
10 {
11 class Program
12 {
13 static void Main(string[] args)
14 {
15 try
16 {
17 string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;
18 Data Source=../../Salon.accdb";
19 // Connection to the database.
20 OleDbConnection conn = new OleDbConnection(connString);
21 // Opening the database.
22 conn.Open();
23
24 OleDbCommand cmd = conn.CreateCommand();
25 // SQL query used to retrieve data.
26 cmd.CommandText = "SELECT * FROM Client";
27
28 OleDbDataReader reader = cmd.ExecuteReader();
29
30 // Loop that reads all records in the dbReader.
31 while (reader.Read())
32 {
33 // Assigns the data in each field to a variable.
34 int uniqueID = (int)reader["UniqueID"];
35 string name = (string)reader["Name"];
36 string surname = (string)reader["Surname"];
37 string address = (string)reader["Address"];
38 string telephone = (string)reader["Telephone"];
39
40 // Displays the retrieved data to the console.
41 Console.WriteLine("ID: {0}, Name: {1}, Surname: {2}, " +
42 "Address: {3}, Telephone: {4}", uniqueID, name, surname,
43 address, telephone);
44 }
45
46 int fieldCount = reader.FieldCount;
47 Console.WriteLine();
48 Console.WriteLine("There are {0} columns!", fieldCount);
49 Console.WriteLine();
50
51 string columnName = reader.GetName(1);
52 Console.WriteLine("The second column's name is: {0}",
53 columnName);
54 Console.WriteLine();
55
56 conn.Close();
57 }
58 catch (OleDbException odbe)
59 {
60 Console.WriteLine(odbe.Message);
61 }
62 }

© CTI Education Group


Unit 4 – Storing Data Page 80

63 }
64 }

Lines 51 to 54 have been added to the previous example. The output looks as follows:

ID: 1, Name: Angelique, Surname: Kolle, Address: 58 First Ave, Alberton North,
Telephone: 0735149000
ID: 2, Name: Brian, Surname: Scott, Address: 12 Peach Str, Primrose,
Telephone: 0825055972
ID: 3, Name: Kim, Surname: Crous, Address: 109 West Str, Johannesburg,
Telephone: 0765894258
ID: 4, Name: Bradley, Surname: Smith, Address: 23 Seventh Ave, Sandton,
Telephone: 0796584123

There are 5 columns!

The second column’s name is: Name

Press any key to continue . . .

The column names can be retrieved using a SQL connection in exactly the same way as
with the OleDb connection (as shown above). Use the example in section 4.8.11 and add
the GetName() property.

4.8.14 Manipulating data using MS Access


When data in the database needs to be changed, inserted, or deleted, different SQL
statements will need to be used. The ExecuteNonQuery() method is used to execute
SQL statements which do not return a value.

Please take note that although the INSERT, UPDATE, and DELETE statements follow one
after the other, they have to be executed separately. In order to achieve this, simply
comment out the two statements that are not being used at a particular time.

The following example shows how a record can be inserted into the database using an MS
Access connection:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace ManipulatingDataExample
{
class Program
{
static void Main(string[] args)
{
try
{
string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=..\..\Salon.accdb";
OleDbConnection conn = new OleDbConnection(connString);
conn.Open();

© CTI Education Group


Unit 4 – Storing Data Page 81

OleDbCommand cmd = conn.CreateCommand();


cmd.CommandText = @"INSERT INTO Client (Name, Surname, Address,
Telephone)VALUES('Bob', 'Kruger',
'123 Second Str, JHB', '0121548758')";

cmd.CommandText = @"UPDATE Client SET Address = '12 Ape Street'


WHERE (Name = 'Brian' AND Surname = 'Scott')";

cmd.CommandText = @"DELETE FROM Client WHERE (Surname = 'Smith')";

cmd.ExecuteNonQuery();

conn.Close();
}
catch (OleDbException ole)
{
Console.WriteLine(ole.Message);
}
}
}
}

Remember that when a database is added to a project, a copy of the database is made in
the project directory. Thus, any changes made to the database in the project will not be
reflected in the original; they will be reflected in the database attached to the project.

To be able to see what changes have occurred in the Salon database, the database can
be opened in Visual C#.

 Double-click on Salon.accdb in the Solution Explorer on the right side of the screen.

The Database Explorer will open on the left side of the screen where the Toolbox is
usually situated.

 Expand the Salon.accdb level by clicking the +.


 Expand the Tables level.

The Client and Appointment tables should now be visible.

 Right-click on the Client table and select the Retrieve Data option.

A new tab will open that displays all the data in the table. Although nothing was displayed
on the console, notice that a new record has been added, the second record’s address
has changed, and the fourth record has been removed.

From the perspective of the application, you can see that the DELETE and UPDATE
statements function in much the same way as the INSERT statement demonstrated in the
example above.

Always remember to establish the connection to the specified database and to close it
again when all desired operations are concluded.

© CTI Education Group


Unit 4 – Storing Data Page 82

4.8.15 Manipulating data using Microsoft SQL Server


Manipulating data using SQL is done in exactly the same way as in MS Access. The
example below inserts a new row into the Client table of the Salon database, deletes an
existing row, and updates a row in the database.

Please take note that although the INSERT, UPDATE, and DELETE statements follow one
after the other, they have to be executed separately. In order to achieve this, simply
comment out the two statements that are not being used at a particular time.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace SqlConnectionApplication
{
class Program
{
static void Main(string[] args)
{
string stringConn = @"Integrated Security=SSPI;
Initial Catalog=Salon;
Data Source=localhost";
SqlConnection sqlConn = new SqlConnection(stringConn);

try
{
sqlConn.Open();

SqlCommand cmd = sqlConn.CreateCommand();

cmd.CommandText = @"INSERT INTO Client (Name, Surname, Address,


Telephone)VALUES('Bob', 'Kruger',
'123 Second Str, JHB', '0121548758')";

cmd.CommandText = @"UPDATE Client SET Address = '12 Ape Street',


Telephone = '0735149000' WHERE
(Name = 'Brian' AND Surname = 'Scott')";

cmd.CommandText = "DELETE FROM Client WHERE (Surname = 'Smith')";

cmd.ExecuteNonQuery();
}
catch (SqlException ole)
{
Console.WriteLine(ole.Message);
}
finally
{
sqlConn.Close();
}
}
}
}

© CTI Education Group


Unit 4 – Storing Data Page 83

Notice that the table is modified just as it was in the previous example with the MS Access
database. To see the changes, open Microsoft SQL Server Management Studio and
select all the values in the table.

4.8.16 Data sets


A DataSet can be thought of as a database table which is stored in memory. The
DataSet component provides functionality to retrieve all the fields of the table that are
specified. The DataSet component makes it easier to edit and update information.

Once the result of a query has been loaded into a DataSet, the database connection can
safely be closed. This makes the DataSet component very resource-efficient, as it does
not require a continuous connection to the database. A side effect of this is that any
changes made to the contents of the DataSet will not be reflected in the database unless
an update is explicitly specified.

Figure 4.36 shows the steps in creating a DataSet:

DataSource DataSet

DataSource
DataSource reconnected
disconnected

Data changes
DataAdapter made in
dataset without
affecting data
source.

Figure 4.36 – Connection between the DataSource, DataAdapter, and DataSet

Figure 4.36 represents the connections between a data source, DataAdapter, and
DataSet. A connection is made to the data source, which is used by the DataAdapter
to fill the DataSet. Once the data has been retrieved, the DataAdapter will disconnect
from the data source and the connection can safely be closed. If the content of the
DataSet needs to be saved back to the data source after the connection has been
closed, it will be necessary to reconnect.

© CTI Education Group


Unit 4 – Storing Data Page 84

4.8.16.1 Populating a DataSet using MS Access


Before a DataSet can be filled, a connection needs to be made to the data source.
Once this is done, the DataAdapter can retrieve the necessary data and populate the
DataSet.

The example below connects to the MS Access database that has been manipulated
(4.8.14), retrieves data using the DataAdapter, and fills the DataSet:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Data;
6 using System.Data.OleDb;
7
8 namespace DataSetExample
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 try
15 {
16 string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;
17 Data Source=../../Salon.accdb";
18 OleDbConnection conn = new OleDbConnection(connString);
19 conn.Open();
20
21 // Creates an empty DataSet.
22 DataSet ds = new DataSet();
23
24 // Creates a DataAdapter that queries the database.
25 OleDbDataAdapter dba = new OleDbDataAdapter
26 ("SELECT * FROM Client", conn);
27
28 // DataSet is filled with the data retrieved by the
29 // DataAdapter query.
30 dba.Fill(ds, "Client");
31
32 // Creates a DataTable object.
33 DataTable dt = ds.Tables["Client"];
34
35 // Displays the data in the DataSet one row at a time.
36 foreach (DataRow client in dt.Rows)
37 {
38 Console.WriteLine("{1} {0}", client["Name"],
39 client["Surname"]);
40 }
41
42 Console.WriteLine();
43 }
44 catch (OleDbException ole)
45 {
46 Console.WriteLine(ole.Message);
47 }
48 }
49 }
50 }

© CTI Education Group


Unit 4 – Storing Data Page 85

Lines 16 to 19 establish and open the connection to the Salon database. An empty
DataSet is created on line 22, while the DataAdapter specifies the query sent to the
database on lines 25 and 26. Line 30 fills the DataSet. The DataTable object is
created on line 33 to add the DataSet. Lines 36 to 40 loop through the DataTable to
read all the rows present and displays each one as it is read.

As previously explained, any information changed will not be sent to the database. In
order to send changes to the database, an UPDATE statement must be used. The result of
the example will be:

Kolle Angelique
Scott Brian
Crous Kim
Kruger Bob

4.8.16.2 Populating a DataSet using SQL


Populating a DataSet using SQL is much the same as using MS Access.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace SqlConnectionApplication
{
class Program
{
static void Main(string[] args)
{
string stringConn = @"Integrated Security=SSPI;
Initial Catalog=Salon;
Data Source=localhost";

SqlConnection sqlConn = new SqlConnection(stringConn);

try
{
sqlConn.Open();

// Creates a DataAdapter that queries the database.


SqlDataAdapter dba = new SqlDataAdapter ("SELECT * FROM Client",
sqlConn);

// Creates an empty DataSet.


DataSet ds = new DataSet();

// DataSet is filled with the data retrieved by the


// DataAdapter query.
dba.Fill(ds, "Client");

// Creates a DataTable object.


DataTable dt = ds.Tables["Client"];

// Displays the data in the DataSet one row at a time.

© CTI Education Group


Unit 4 – Storing Data Page 86

foreach (DataRow client in dt.Rows)


{
Console.WriteLine("{1} {0}", client["Name"],
client["Surname"]);
}

Console.WriteLine();
}
catch (SqlException se)
{
Console.WriteLine(se.Message);
}
}
}
}

The result of the above example is as follows:

Kolle Angelique
Scott Brian
Crous Kim
Kruger Bob

Press any key to continue . . .

4.8.16.3 Manipulating data in a DataSet using MS Access


The data in a DataSet can be changed by adding new records, updating existing fields,
and deleting records.

Notice that the connection path is the same as in the example where new data was
inserted. In this example, the database is updated so the same connection path is
needed. When selecting data from the database, the normal path is not required. The
following example searches for existing data to update, adds a new record, and deletes a
record. The previous example is used with some changes:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Data;
6 using System.Data.OleDb;
7
8 namespace DataSetExample
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 try
15 {
16 string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;
17 Data Source=..\..\Salon.accdb";
18 OleDbConnection conn = new OleDbConnection(connString);
19 conn.Open();
20
21 // Creates an empty DataSet.
22 DataSet ds = new DataSet();

© CTI Education Group


Unit 4 – Storing Data Page 87

23 // Creates a DataAdapter that queries the database.


24 OleDbDataAdapter dba = new OleDbDataAdapter
25 ("SELECT * FROM Client", conn);
26 // DataSet is filled with the data retrieved by the DataAdapter
27 // query.
28 dba.Fill(ds, "Client");
29 // Creates a DataTable object.
30 DataTable dt = ds.Tables["Client"];
31
32 DataColumn[] cols = new DataColumn[1];
33 cols[0] = dt.Columns["name"];
34 dt.PrimaryKey = cols;
35
36 // OR USE THE FOLLOWING TO CREATE A PRIMARY KEY:
37 // dt.PrimaryKey = new DataColumn[] {dt.Columns[“name”]};
38
39 // Searches for the Angelique record and changes it to Ang.
40 DataRow angeliqueRow = dt.Rows.Find("Angelique");
41 angeliqueRow["name"] = "Ang";
42 // Creates a new row, sets the column’s values, and adds the
43 // record to the DataSet.
44 DataRow clientRow = dt.NewRow();
45 clientRow["name"] = "Martie";
46 clientRow["surname"] = "Laurens";
47 clientRow["address"] = "12 Peach Str";
48 clientRow["telephone"] = 0821235678;
49 dt.Rows.Add(clientRow);
50
51 // Displays the data in the DataSet one row at a time.
52 foreach (DataRow client in dt.Rows)
53 {
54 Console.WriteLine("{1} {0}", client["Name"],
55 client["Surname"]);
56 }
57
58 Console.WriteLine();
59
60 // Deletes the last record from the DataSet.
61 dt.Rows[4].Delete();
62
63 Console.WriteLine("After the last row has been deleted:");
64 Console.WriteLine();
65
66 // Displays the data in the DataSet one row at a time.
67 foreach (DataRow client in dt.Rows)
68 {
69 Console.WriteLine("{1} {0}", client["Name"],
70 client["Surname"]);
71 }
72
73 Console.WriteLine();
74 conn.Close();
75 }
76 catch (OleDbException ole)
77 {
78 Console.WriteLine(ole.Message);
79 }
80 }
81 }
82 }

© CTI Education Group


Unit 4 – Storing Data Page 88

Note that lines 16 to 30 are the same as in the previous example and continue again on
line 66, but lines 32 to 64 have been added.

An extra loop has been created to show what the table contains before the last record is
deleted and after the record has been deleted. Line 32 creates a DataColumn which can
store two values. Remember that when incrementing, start at zero. Line 33 stores names
within the first value. Line 34 makes the first value the primary key going forward. The
result will be as follows:

Kolle Ang
Scott Brian
Crous Kim
Kruger Bob
Laurens Martie

After the last row has been deleted:

Kolle Ang
Scott Brian
Crous Kim
Kruger Bob

Press any key to continue . . .

Notice that when the application is run, the first record is updated and the last record is a
new entry. The last record (the new entry) is then deleted.

4.8.16.4 Manipulating data in a DataSet using SQL


When manipulating data in a DataSet using SQL, the namespaces will differ from the
ones that are used when connecting to an MS Access database, and the connection string
will also differ (as shown in all the previous examples).

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Data;
6 using System.Data.SqlClient;
7
8 namespace SqlConnectionApplication
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 string stringConn = @"Integrated Security=SSPI;
15 Initial Catalog=Salon;
16 Data Source=localhost";
17
18 SqlConnection sqlConn = new SqlConnection(stringConn);
19
20 try
21 {
22 sqlConn.Open();
23
24 // Creates a DataAdapter that queries the database.

© CTI Education Group


Unit 4 – Storing Data Page 89

25 SqlDataAdapter dba = new SqlDataAdapter("SELECT * FROM Client",


26 sqlConn);
27
28 // Creates an empty DataSet.
29 DataSet ds = new DataSet();
30
31 // DataSet is filled with the data retrieved by the DataAdapter
32 // query.
33 dba.Fill(ds, "Client");
34
35 // Creates a DataTable object.
36 DataTable dt = ds.Tables["Client"];
37
38 DataColumn[] cols = new DataColumn[1];
39 cols[0] = dt.Columns["name"];
40 dt.PrimaryKey = cols;
41
42 // OR USE THE FOLLOWING TO CREATE A PRIMARY KEY:
43 // dt.PrimaryKey = new DataColumn[] {dt.Columns[“name”]};
44
45 // Searches for the Angelique record and changes it to Ang.
46 DataRow angeliqueRow = dt.Rows.Find("Angelique");
47 angeliqueRow["name"] = "Ang";
48
49 // Creates a new row, sets the column’s values, and adds the
50 // record to the DataSet.
51 DataRow clientRow = dt.NewRow();
52 clientRow["name"] = "Martie";
53 clientRow["surname"] = "Laurens";
54 clientRow["address"] = "12 Peach Str";
55 clientRow["telephone"] = 0821235678;
56 dt.Rows.Add(clientRow);
57
58 // Displays the data in the DataSet one row at a time.
59 foreach (DataRow client in dt.Rows)
60 {
61 Console.WriteLine("{1} {0}", client["Name"],
62 client["Surname"]);
63 }
64
65 Console.WriteLine();
66
67 // Deletes the last record from the DataSet.
68 dt.Rows[4].Delete();
69
70 Console.WriteLine("After the last row has been deleted:");
71 Console.WriteLine();
72
73 // Displays the data in the DataSet one row at a time.
74 foreach (DataRow client in dt.Rows)
75 {
76 Console.WriteLine("{1} {0}", client["Name"],
77 client["Surname"]);
78 }
79
80 Console.WriteLine();
81 }
82 catch (SqlException se)
83 {
84 Console.WriteLine(se.Message);
85 }
86 finally

© CTI Education Group


Unit 4 – Storing Data Page 90

87 {
88 sqlConn.Close();
89 }
90 }
91 }
92 }

The only lines in the code example which differ from the previous example are lines 14 to
26. Although lines 24 to 26 are very similar, remember that the OleDbDataAdapter
becomes the SqlDataAdapter when connecting to a SQL database. The output looks
exactly the same as the output from the previous example.

4.8.16.5 Updating the data source with the DataSet using MS Access
Use the OleDbCommandBuilder when performing a simple update to the database. The
example from section 4.8.16.3 is used but it contains a few modifications:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Data;
6 using System.Data.OleDb;
7
8 namespace DataSetExample
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 try
15 {
16 string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;
17 Data Source=..\..\Salon.accdb";
18 OleDbConnection conn = new OleDbConnection(connString);
19 conn.Open();
20
21 // Creates an empty DataSet.
22 DataSet ds = new DataSet();
23 // Creates a DataAdapter that queries the database.
24 OleDbDataAdapter dba = new OleDbDataAdapter
25 ("SELECT * FROM Client", conn);
26 // DataSet is filled with the data retrieved by the DataAdapter
27 // query.
28 dba.Fill(ds, "Client");
29 // Creates a DataTable object.
30 DataTable dt = ds.Tables["Client"];
31
32 DataColumn[] cols = new DataColumn[1];
33 cols[0] = dt.Columns["name"];
34 dt.PrimaryKey = cols;
35
36 // OR USE THE FOLLOWING TO CREATE A PRIMARY KEY:
37 // dt.PrimaryKey = new DataColumn[] {dt.Columns["name"]};
38
39 // Searches for the Angelique record and changes it to Ang.
40 DataRow angeliqueRow = dt.Rows.Find("Angelique");
41 angeliqueRow["name"] = "Ang";
42

© CTI Education Group


Unit 4 – Storing Data Page 91

43 // Creates a new row, sets the column’s values, and adds the
44 // record to the DataSet.
45 DataRow clientRow = dt.NewRow();
46 clientRow["name"] = "Martie";
47 clientRow["surname"] = "Laurens";
48 clientRow["address"] = "12 Peach Str";
49 clientRow["telephone"] = 0821235678;
50 dt.Rows.Add(clientRow);
51
52 OleDbCommandBuilder cmdBuilder = new OleDbCommandBuilder(dba);
53
54 dba.Update(ds, "Client");
55
56 // Displays the data in the DataSet one row at a time.
57 foreach (DataRow client in dt.Rows)
58 {
59 Console.WriteLine("{1} {0}", client["Name"],
60 client["Surname"]);
61 }
62
63 Console.WriteLine();
64 conn.Close();
65 }
66 catch (OleDbException ole)
67 {
68 Console.WriteLine(ole.Message);
69 }
70 }
71 }
72 }

The first thing to notice is that the Delete() method from the previous example has been
removed because it is not required in this example. Lines 52 to 54 in this example have
replaced the Delete() method from the previous example. The
OleDbCommandBuilder communicates with the DataAdapter, which creates a
connection with the database and the Update() method on line 54 changes the new
record which is created on lines 45 to 49. The output of the above example should look as
follows:

Kolle Ang
Scott Brian
Crous Kim
Kruger Bob
Laurens Martie

Press any key to continue . . .

When updating, deleting, selecting, or inserting data into a data source with a DataSet,
the commands have to be specified along with the parameters that must update the
database. The following code snippet displays how the Update() and Delete()
commands are used instead of the CommandBuilder with a DataSet when using an MS
Access database:

© CTI Education Group


Unit 4 – Storing Data Page 92

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Data;
6 using System.Data.OleDb;
7
8 namespace DataSetExample
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 try
15 {
16 string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;
17 Data Source=..\..\Salon.accdb";
18 OleDbConnection conn = new OleDbConnection(connString);
19 conn.Open();
20
21 // Creates an empty DataSet.
22 DataSet ds = new DataSet();
23 // Creates a DataAdapter that queries the database.
24 OleDbDataAdapter dba = new OleDbDataAdapter
25 ("SELECT * FROM Client", conn);
26 // DataSet is filled with the data retrieved by the DataAdapter
27 // query.
28 dba.Fill(ds, "Client");
29 // Creates a DataTable object.
30 DataTable dt = ds.Tables["Client"];
31
32 DataColumn[] cols = new DataColumn[1];
33 cols[0] = dt.Columns["name"];
34 dt.PrimaryKey = cols;
35
36 // UPDATE.
37 DataRow angeliqueRow = dt.Rows.Find("Angelique");
38 angeliqueRow["name"] = "Ang";
39
40 OleDbCommand upCmd = new OleDbCommand(@"UPDATE Client
41 SET surname = @surname
42 WHERE name = @name",
43 conn);
44
45 upCmd.Parameters.Add("@surname", OleDbType.VarChar, 20,
46 "Surname");
47 upCmd.Parameters.Add("@name", OleDbType.VarChar, 20, "Name");
48
49 dba.UpdateCommand = upCmd;
50
51 // DELETE.
52 dt.Rows[0].Delete();
53
54 OleDbCommand delCmd = new OleDbCommand(@"DELETE FROM Client
55 WHERE name = @name",
56 conn);
57
58 delCmd.Parameters.Add("@name", OleDbType.VarChar, 20, "Name");
59
60 dba.DeleteCommand = delCmd;
61

© CTI Education Group


Unit 4 – Storing Data Page 93

62 dba.Update(ds, "Client");
63
64 // Displays the data in the DataSet one row at a time.
65 foreach (DataRow client in dt.Rows)
66 {
67 Console.WriteLine("{1} {0}", client["Name"],
68 client["Surname"]);
69 }
70
71 Console.WriteLine();
72 conn.Close();
73 }
74 catch (OleDbException ole)
75 {
76 Console.WriteLine(ole.Message);
77 }
78 }
79 }
80 }

The previous example was used with some changes:

 Delete lines 43 to 54 from the previous MS Access example in this section and replace
them with lines 40 to 62 from this example.
 Comment out the section of code which will delete a record (lines 51 to 62).

This is done to see the effect of the UPDATE statement. The result should look as follows:

Kolle Ang
Scott Brian
Crous Kim
Kruger Bob
Laurens Martie

Press any key to continue . . .

The first record was updated to “Ang”.

 Uncomment lines 51 to 62.


 Comment out the section of code that updates the database (lines 36 to 49).

The output should look as follows:

Scott Brian
Crous Kim
Kruger Bob
Laurens Martie

Press any key to continue . . .

It is clear that the first record “Kolle Ang” was deleted. Please note that in order to run this
application again, the record will have to be recreated in the database. It is possible to run
the update and delete sections of code at the same time without having to comment out
any code, but then only the second output will be seen as and the first output is done in
the background.

© CTI Education Group


Unit 4 – Storing Data Page 94

Lines 45, 47, and 58 have a property called OleDbType. This is used to determine the
type of data that has to be entered into the database. In this case VarChar was used
which evaluates to a string. Any other data type can be specified here. The rest of the
code is quite self-explanatory.

4.8.16.6 Updating the data source with the DataSet using SQL
The examples shown in the previous section are shown again, but the parts that apply to
an MS Access database will be replaced with parts that apply only to SQL databases. The
first example uses CommandBuilder, whereas the second example uses the UPDATE
and DELETE methods.

 Edit the previous SQL example (section 4.8.16.4) as shown below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace SqlConnectionApplication
{
class Program
{
static void Main(string[] args)
{
string stringConn = @"Integrated Security=SSPI;
Initial Catalog=Salon;
Data Source=localhost";

SqlConnection sqlConn = new SqlConnection(stringConn);

try
{
sqlConn.Open();

// Creates an empty DataSet.


DataSet ds = new DataSet();
// Creates a DataAdapter that queries the database.
SqlDataAdapter dba = new SqlDataAdapter
("SELECT * FROM Client", sqlConn);

// DataSet is filled with the data retrieved by the DataAdapter


// query.
dba.Fill(ds, "Client");
// Creates a DataTable object.
DataTable dt = ds.Tables["Client"];

DataColumn[] cols = new DataColumn[1];


cols[0] = dt.Columns["name"];
dt.PrimaryKey = cols;

// OR USE THE FOLLOWING TO CREATE A PRIMARY KEY:


// dt.PrimaryKey = new DataColumn[] {dt.Columns["name"]};

// Searches for the Angelique record and changes it to Ang.


DataRow angeliqueRow = dt.Rows.Find("Angelique");

© CTI Education Group


Unit 4 – Storing Data Page 95

angeliqueRow["name"] = "Ang";

// Creates a new row, sets the column’s values, and adds the
// record to the DataSet.
DataRow clientRow = dt.NewRow();
clientRow["name"] = "Martie";
clientRow["surname"] = "Laurens";
clientRow["address"] = "12 Peach Str";
clientRow["telephone"] = 0821235678;
dt.Rows.Add(clientRow);

SqlCommandBuilder sqlBuilder = new SqlCommandBuilder(dba);

dba.Update(ds, "Client");

// Displays the data in the DataSet one row at a time.


foreach (DataRow client in dt.Rows)
{
Console.WriteLine("{1} {0}", client["Name"], client["Surname"]);
}

Console.WriteLine();

}
catch (SqlException se)
{
Console.WriteLine(se.Message);
}
finally
{
sqlConn.Close();
}
}
}
}

The output of the above example is as follows:

Kolle Ang
Scott Brian
Crous Kim
Kruger Bob
Laurens Martie

Press any key to continue . . .

Note that the same lines that were commented out in the previous example (section
4.8.16.5) must also be commented out here.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace SqlConnectionApplication
{
class Program
{

© CTI Education Group


Unit 4 – Storing Data Page 96

static void Main(string[] args)


{
string stringConn = @"Integrated Security=SSPI;
Initial Catalog=Salon;
Data Source=localhost";

SqlConnection sqlConn = new SqlConnection(stringConn);

try
{
sqlConn.Open();

// Creates an empty DataSet.


DataSet ds = new DataSet();
// Creates a DataAdapter that queries the database.
SqlDataAdapter dba = new SqlDataAdapter
("SELECT * FROM Client", sqlConn);
// DataSet is filled with the data retrieved by the DataAdapter
// query.
dba.Fill(ds, "Client");
// Creates a DataTable object.
DataTable dt = ds.Tables["Client"];

DataColumn[] cols = new DataColumn[1];


cols[0] = dt.Columns["name"];
dt.PrimaryKey = cols;

// OR USE THE FOLLOWING TO CREATE A PRIMARY KEY:


// dt.PrimaryKey = new DataColumn[] {dt.Columns["name"]};

// UPDATE.
DataRow angeliqueRow = dt.Rows.Find("Angelique");
angeliqueRow["name"] = "Ang";

SqlCommand upCmd = new SqlCommand(@"UPDATE Client


SET surname = @surname
WHERE name = @name",
sqlConn);

upCmd.Parameters.Add("@surname", SqlDbType.VarChar, 20, "Surname");


upCmd.Parameters.Add("@name", SqlDbType.VarChar, 20, "Name");

dba.UpdateCommand = upCmd;

// DELETE.
dt.Rows[0].Delete();

SqlCommand delCmd = new SqlCommand(@"DELETE FROM Client


WHERE name = @name",
sqlConn);

delCmd.Parameters.Add("@name", SqlDbType.VarChar, 20, "Name");

dba.DeleteCommand = delCmd;

dba.Update(ds, "Client");

// Displays the data in the DataSet one row at a time.


foreach (DataRow client in dt.Rows)
{
Console.WriteLine("{1} {0}", client["Name"], client["Surname"]);
}

© CTI Education Group


Unit 4 – Storing Data Page 97

Console.WriteLine();

}
catch (SqlException se)
{
Console.WriteLine(se.Message);
}
finally
{
sqlConn.Close();
}
}
}
}

The output of the above example is as follows (with the DELETE section commented out):

Kolle Ang
Scott Brian
Crous Kim
Kruger Bob
Laurens Martie

Press any key to continue . . .

 Uncomment the DELETE section and comment out the UPDATE section.

The example has the following output for the UPDATE section:

Scott Brian
Crous Kim
Kruger Bob
Laurens Martie

Press any key to continue . . .

Note that the SqlDbType property in the SQL connection replaces the OleDbType
property in the MS Access connections.

4.8.17 Brief overview of XML


XML stands for eXtensible Markup Language. XML is primarily used to pass information
between different programs, often via the internet. XML is classified as ‘extensible’
because it allows for user-defined markup elements. XML itself is a general specification
with which other languages (such as XHTML) can be defined. XML uses tags which are
similar to those used in HTML (HyperText Markup Language) and can also be used to
store information. Before moving on, some ground rules have to be explained, because
although they are quite straightforward, they are very strict:

 Every open tag must be closed, e.g. <tag></tag>.


 Empty elements can be specified as one tag, e.g. <tag/>.
 Attribute values must be enclosed in single or double quotes, e.g.
<tag attribute="value">.

© CTI Education Group


Unit 4 – Storing Data Page 98

 Elements must be properly nested, e.g. <tagA><tagB></tagB></tagA>.


 There can only be one root element or tag.
 Element names are case-sensitive.

There are five special characters which are used to define tags in XML. As such, these
characters cannot be used to define entity names or values. These need to be replaced
with an entity reference. The five pre-defined entity references are listed in Error!
Reference source not found.:
Table 13 – Special characters in XML
Special characters
Character Meaning Entity reference
< less than &lt;
> greater than &gt;
& ampersand &amp;
" apostrophe &apos;
' quotation mark &quot;

4.8.17.1 Reading data from a DataSet and writing it as XML using MS Access
It is possible to write an XML representation of data within a DataSet. The data can be
written with or without its schema information. The schema information contains the table
definition of the DataSet as well as the constraint definitions. It is then written in XML
Schema definition language (XSD).

The XML representation can be written to a file, a stream, an XmlWriter, or a string.


The GetXml() method of the DataSet class is used to retrieve the contents of DataSet
in an XML format:

String xmlData = ds.GetXml();

The GetXml() method returns the XML representation without schema information. In
order to include the schema information, the GetXmlSchema() method is used.

String xmlSchema = ds.GetXmlSchema();

The following example incorporates both the GetXml() and GetXmlSchema() methods:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace XMLDataSetExample
{
class Program
{
static void Main(string[] args)
{

© CTI Education Group


Unit 4 – Storing Data Page 99

try
{
OleDbConnection conn = new OleDbConnection(@"
Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=..\..\Salon.accdb");
conn.Open();

OleDbDataAdapter adap = new OleDbDataAdapter


(@"SELECT * FROM Client", conn);

DataSet ds = new DataSet();


adap.Fill(ds, "Client");

// The GetXML() method retrieves the data from the DataSet in an


// XML format.
String xmlData = ds.GetXml();

// The GetXMLSchema() method retrieves the XMLSchema from the


// dataset.
String xmlSchema = ds.GetXmlSchema();

// Prints the XMLSchema and XMLdata to the console.


Console.WriteLine("");
Console.WriteLine("*********");
Console.WriteLine(xmlSchema);
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("****");
Console.WriteLine(xmlData);

conn.Close();
}
catch (OleDbException ole)
{
Console.WriteLine("Error {0} occurred!", ole);
}
}
}
}

© CTI Education Group


Unit 4 – Storing Data Page 100

The resulting output of the above example is as follows:

4.8.17.2 Reading data from a DataSet and writing it as XML using SQL
The same XML methods that were used in the previous section (4.8.17.1) will be used in
the SQL connection:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace XMLDataSetExample
{
class Program
{

© CTI Education Group


Unit 4 – Storing Data Page 101

static void Main(string[] args)


{
string stringConn = @"Integrated Security=SSPI;
Initial Catalog=Salon;
Data Source=localhost";

SqlConnection sqlConn = new SqlConnection(stringConn);

try
{
sqlConn.Open();

SqlDataAdapter adap = new SqlDataAdapter


(@"SELECT * FROM Client", sqlConn);
DataSet ds = new DataSet();

adap.Fill(ds, "Client");

// The GetXML() method retrieves the data from the DataSet in an


// XML format.
String xmlData = ds.GetXml();

// The GetXMLSchema() method retrieves the XMLSchema from the


// dataset.
String xmlSchema = ds.GetXmlSchema();

// Prints the XMLSchema and XMLdata to the console.


Console.WriteLine("");
Console.WriteLine("*********");
Console.WriteLine(xmlSchema);
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("****");
Console.WriteLine(xmlData);
}
catch (SqlException ole)
{
Console.WriteLine("Error {0} occurred!", ole);
}
finally
{
sqlConn.Close();
}
}
}
}

© CTI Education Group


Unit 4 – Storing Data Page 102

The output of this example is as follows:

© CTI Education Group


Unit 4 – Storing Data Page 103

4.8.17.3 Reading data from an XML file into a DataSet


Data can be read from an XML file and inserted into a DataSet. The following example
reads an XML file and an XML schema file and displays the data contained within. The
first step is to create the two files.

 Create a new Text Document and call it GymMembers.


 Open the file.
 Click on File > Save As.
 Change the GymMembers.txt to GymMembers.xml and close the file.

A new xml file has been created in the same folder as the text file as shown in Figure 4.37:

Figure 4.37 – Creating an .xml file

 Right-click on the xml file and select Edit. The file will open like a text file.
 Enter the following code into the file.

<?xml version="1.0" standalone="yes"?>


<GymMembers>
<Item>
<Id>8901230858087</Id>
<Name>Angelique</Name>
<Age>19</Age>
</Item>
<Item>
<Id>8711042584569</Id>
<Name>Brian</Name>

© CTI Education Group


Unit 4 – Storing Data Page 104

<Age>21</Age>
</Item>
<Item>
<Id>9605124589658</Id>
<Name>Brad</Name>
<Age>12</Age>
</Item>
</GymMembers>

 Save and close the text file.


 Double-click on the xml file.

The file should open in Internet Explorer and it should look like the output shown in
Figure 4.38:

Figure 4.38 – The GymMembers.xml created

 Create the .xsd (XML schema) file in the same way that you created the .xml file.

The file will open in Microsoft Visual Web Developer. The following code can be entered
there:

<?xml version="1.0" standalone="yes"?>


<xs:schema id="MyGymMembers" xmlns=""
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-
microsoft-com:xml-msdata">
<xs:element name="GymMembers" msdata:IsDataSet="true" msdata:Locale="en-ZA">
<xs:complexType>

© CTI Education Group


Unit 4 – Storing Data Page 105

<xs:choice maxOccurs="unbounded">
<xs:element name="Item">
<xs:complexType>
<xs:sequence>
<xs:element name="Id" type="xs:decimal" minOccurs="0" />
<xs:element name="Name" type="xs:string" minOccurs="0" />
<xs:element name="Age" type="xs:int" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

 Create a new project in Visual C# 2008 Express Edition called ReadXmlExample.


 Copy the GymMembers.xml and the GymMembers.xsd files to the project’s
bin/Release/ folder.
 Change the Program class to ReadXmlWriteData and enter the following data:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace ReadXmlExample
{
class ReadXmlWriteData
{
static void Main(string[] args)
{
ReadXmlWriteData rxwd = new ReadXmlWriteData();
rxwd.MyXmlRead();
}

public void MyXmlRead()


{
try
{
/* Creates an empty DataSet */
DataSet dataset = new DataSet();

/* Reads the XMLSchema file */


dataset.ReadXmlSchema("GymMembers.xsd");

/* Reads the XML file */


dataset.ReadXml("GymMembers.xml");

/* Goes through each table in the DataSet, and then each row
printing the values for each record */
foreach (DataTable table in dataset.Tables)
{
Console.WriteLine("*****" + table.TableName + "*****");

foreach (DataRow row in table.Rows)


{
Console.WriteLine("{0}\t{1}\t{2}", row["Id"],
row["Name"], row["Age"]);

© CTI Education Group


Unit 4 – Storing Data Page 106

}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}

The output for the code above is as follows:

*****Item*****
8901230858087 Angelique 19
8711042584569 Brian 21
9605124589658 Brad 12

Press any key to continue . . .

Note that ReadXml and ReadXmlSchema methods are overloaded, so they can be used
to read from various sources.

4.8.13 Exercises
1. What is the function of the DataReader object?
2. Which two namespaces are used with ADO.NET?
3. What is the function of the OleDbDataReader object?
4. What is the function of the DataSet object?
5. What does the acronym XML stand for?
6. Create an application in which a user can enter the details of new
students using TextBox controls. Each student’s name, address,
age, gender, and telephone number must be included. These values
should be checked to ensure that they are the correct type before
they are inserted into the database.
7. Create another application which uses the same database. This
application must allow the user to search for students by their name
or gender. A ComboBox must be used to make the selection, and the
result must be displayed in a ListBox control.

4.8.14 Revision questions


1. True/False: A connection is imperative if data is to be retrieved from
a database.
2. True/False: A database cannot be added to the current project.
3. True/False: The FieldCount() method counts the number of
columns in the current row.
4. True/False: Every open tag in XML must be closed.
5. True/False: It is not possible to read data from a DataSet and write
it as XML.

© CTI Education Group


Unit 4 – Storing Data Page 107

Unit 4 Test your knowledge (Self-test)

The questions in this section are similar to those asked in the exam. Try answering these
questions and then check the answers with the instructor. The questions are taken from
the study guide and textbook. The questions comprise theory and application questions
which will be in multiple choice, multiple response, true/false, and selection formats. Allow
about 20 minutes for all the questions. Good luck!

Questions

True/False

1. True/False: User controls are non-standard controls created by the programmer.


2. True/False: The AddDays() method cannot be used to subtract from a date.
3. True/False: The technique used to deploy an application is called ClickOnce.
4. True/False: Images cannot be added to the project folder.
5. True/False: For efficiency, use the Add() method instead of the AddRange() method
when working with collections.

Multiple Choice

1. Which one of the following best describes the function of this piece of code?

using System;
using System.IO;

public class Test


{
public static void Main()
{
FileStream fs = new FileStream("TheFile.txt", FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);

for (int i = 0; i < 100; i++)


{
bw.Write(i);
}
}
}

a. The code writes the numbers 0 to 100 to a new file called TheFile.txt.
b. The code writes the numbers 1 to 100 to an existing file called TheFile.txt.
c. The code writes the numbers 0 to 99 in binary to a new file called TheFile.txt.
d. The code writes the numbers 1 to 99 in bytes to a new file called TheFile.txt.

© CTI Education Group


Unit 4 – Storing Data Page 108

2. Custom controls are referred to as ____________ in C#.


a. user controls
b. self-defined controls
c. undefined controls
d. new-developed controls

3. Which one of the following best describes this code snippet?

OleDbCommand cmd = connection.CreateCommand();


cmd.CommandText = "SELECT name FROM plants WHERE season='summer'";
OleDbDataReader read = cmd.ExecuteReader();

while (read.Read())
{
Console.WriteLine(read.GetString[0]);
}

a. The code will print out details of all the plants in the database that have a summer
season.
b. The code will print out names of all the plants in the database that have a summer
season.
c. The code will print out the name of the first plant in the database that has a
summer season.
d. The code will print out details of the last plant in the database that has a summer
season.

4. Which property of the FileInfo class is used to find out the size of a specific file?
a. Size
b. Length
c. FileSize
d. TotalBytes

5. Which namespace is used to find information about classes and types?


a. System.Reflection
b. System.IO
c. System.Attributes
d. System.Class

Multiple Response

1. Which three of the following should be considered when improving the performance of
an application using the .NET Framework?
a. Ensure the form is as small as possible.
b. Unnecessary boxing and unboxing.
c. Using the AddRange() method.
d. When concatenating and manipulating complex strings the StringBuilder class
should be used.
e. Keeping all code in one class instead of many.

© CTI Education Group


Unit 4 – Storing Data Page 109

2. Which three of the following are properties of the AttributeUsage class?


a. Inherited
b. Return
c. AllowMultiple
d. Value
e. ValidOn

3. Which three of the following are methods of the DateTime class?


a. AddDays()
b. Add()
c. AddMonths()
d. AddMilli()
e. AddMilliseconds()

4. Which three of the following are common uses of reflection?


a. Late binding
b. Viewing metadata
c. Performing type discovery
d. Adding metadata
e. Early binding

5. Which three of the following are methods of the Stream class?


a. Close()
b. Append()
c. Open()
d. Read()
e. Write()

© CTI Education Group


Unit 4 – Storing Data Page 110

© CTI Education Group


Unit 5 – ASP.NET Page 111

Unit 5 – ASP.NET

This unit introduces ASP.NET and the Visual Web Developer Express IDE.

This unit counts 10% towards part B of the C# mark, and there are 12 days to complete it.
The time and marks are scheduled as follows:

Reading 10 days
Exam preparation and exam 2 days 10%

© CTI Education Group


Unit 5 – ASP.NET Page 112

© CTI Education Group


Unit 5 – ASP.NET Page 113

5.1 ASP.NET Fundamentals

At the end of this subsection you should be able to:

 Understand the fundamental principles behind ASP.NET.

5.1.1 What is ASP.NET?


ASP.NET is a framework used for the development of applications which can be accessed
via the Internet. These applications are run on a server which generates XHTML
(eXtensible Hypertext Markup Language) pages that can be viewed in a Web browser. As
such, ASP.NET shares many similarities with systems such as PHP (Php Hypertext
Preprocessor) and JSP (Java Server Pages).

ASP.NET is the successor to Microsoft’s original ASP (Active Server Pages). ASP.NET
implements the Common Language Runtime (CLR). As such, it can execute code written
in any language in the .NET Framework, which includes both VB.NET and C#.

5.1.2 Server-side applications


As the name suggests, ASP.NET creates server-side applications. What this means is
that all operations and calculations are performed on the server, and then the resulting
Web page is displayed to the user. When an event is triggered (such as when the user
clicks on a button), the code for that event is executed on the server. The server will then
generate a response in the form of a new page. This new page may, or may not, be the
same as the original page.

This concept may seem somewhat confusing at this point; it will be far easier to
understand with some practical experience.

5.1.3 Exercises
1. Name two other systems which share similarities with ASP.NET.
2. What does PHP stand for?
3. What does ASP stand for?

5.1.4 Revision questions


1. True/False: ASP.NET creates client-side applications.
2. True/False: ASP.NET implements the Common Language Runtime.
3. True/False: C# is the only language which can use ASP.NET.

© CTI Education Group


Unit 5 – ASP.NET Page 114

© CTI Education Group


Unit 5 – ASP.NET Page 115

5.2 Microsoft Visual Web Developer Express Edition IDE

At the end of this subsection you should be able to:

 Install and use Visual Web Developer Express Edition.

5.2.1 Installing Visual Web Developer Express Edition


Before working with ASP.NET, it is necessary to install Microsoft Visual Web Developer
2008 Express Edition. This IDE is part of the same family of integrated development
environments as Visual C# 2008 Express Edition. The necessary disk will be provided
with this guide.

 Insert the Visual Studio Express Editions disk into the DVD-ROM drive.

In Windows Vista, a dialog appears which asks if the disc must be auto-played ‘setup.hta’.

 Click Run setup.hta.


 Select Visual Web Developer 2008 Express Edition from the list.
 Follow the instructions to complete the installation.

5.2.2 Running Visual Web Developer Express Edition


In Windows Vista:

 Click Start.
 Open All Programs.
 Select Microsoft Visual Web Developer 2008 Express Edition.

© CTI Education Group


Unit 5 – ASP.NET Page 116

5.2.3 The Visual Web Developer interface


The Visual Web Developer interface is shown in Figure 5.1:

Figure 5.1 – The Visual Web Developer Interface

The Visual Web Developer Express interface functions in much the same way as the other
Visual Studio Express environments.

5.2.4 Creating a new project


The procedure used to create a new project in Visual Web Developer is very similar to the
one used in Visual C# Express.

 Select File from the main menu bar.


 Select New Web Site.

© CTI Education Group


Unit 5 – ASP.NET Page 117

The dialog shown in Figure 5.2 will open:

Figure 5.2 – The ‘New Web Site’ dialog

 In the Templates list, ensure that ASP.NET Web Site is selected.


 In the Language drop down box, ensure that Visual C# is selected.
 In the Location box, replace the default website name with an appropriate name. For
the following example, the name MyWebSite will be used. Only the end of the
address (which is used as the name of the project) will need to be modified, unless the
website needs to be stored elsewhere on the hard drive.

Figure 5.3 – Setting the name of a new website

 Click OK.

© CTI Education Group


Unit 5 – ASP.NET Page 118

The default page shown in Figure 5.4 should be seen:

Figure 5.4 – The default page

The XHTML code displayed in the window will be familiar to those who understand HTML
code. However, knowledge of this code is not necessary to work with the IDE. Visual
Web Developer Express, much like Visual C# Express, provides a Design view which is
used to create the interface visually.

© CTI Education Group


Unit 5 – ASP.NET Page 119

 To switch to the Design view, click the Design tab in the bottom left-hand corner (as
shown in Figure 5.5.)

Figure 5.5 – The design tab

The Design view will be blank initially. This is because the Web page does not have any
content yet.

 Click anywhere inside the window and type the text “Hello, World!”
 Now save the project (File > Save All or <Ctrl> + <Shift> + <S>).

The Web application will be run for this first time.

 Click Debug > Start Debugging (Shortcut: <F5>)

The dialog displayed in Figure 5.6 should now be seen:

Figure 5.6 – Debugging not enabled

By default, ASP.NET Web pages are run without debugging. This is because debugging
uses up additional system resources which can slow the server down. However, in a
development or testing environment running the application in debugging mode is
essential.

 Ensure that “Modify the Web.config file to enable debugging.” is selected.


 Click OK.

© CTI Education Group


Unit 5 – ASP.NET Page 120

Depending on the browser settings, the dialog presented in Figure 5.7 may, or may not, be
seen:

Figure 5.7 – Script Debugging Disabled

This dialog indicates that script debugging is disabled in the Internet Explorer browser.
This is not a problem.

 Check the “Don’t show this dialog again” checkbox.


 Click Yes.

The Web page should now open in Internet Explorer as shown in Figure 5.8:

Figure 5.8 – Hello, World!

© CTI Education Group


Unit 5 – ASP.NET Page 121

A new icon will be displayed in the right hand side of the taskbar. This icon is shown in
Figure 5.9:

Figure 5.9 – ASP.NET Development Server

This icon indicates that Visual Web Developer Express is currently running a Web server.
This server will not automatically close unless:

a. Visual Web Developer Express is closed,


b. The icon is right-clicked and Stop is selected from the menu, or
c. Stop Debugging (keyboard shortcut: <Shift> + <F5>) is selected from the Debug
menu in Visual Web Developer Express.

5.2.5 Editing a page in the Design view


When a page is open in the Design view, the toolbar at the top of the window, as shown in
Figure 5.10, can be seen:

Figure 5.10 – The editing toolbar

This toolbar strongly resembles those used by other editing applications such as Microsoft
Office and OpenOffice. The functionality is also much the same. For example, to change
the alignment of text (or any other content), the Justification button can be used, as
shown in Figure 5.11.

Figure 5.11 – Justification options

Similarly, Figure 5.12 demonstrates how the font can be changed using the drop-down
menus:

© CTI Education Group


Unit 5 – ASP.NET Page 122

Figure 5.12 – Changing the font

To change the background colour of a Web page:

 Select the document itself by clicking in any empty part of the document.
 Click the Background Color button.

A dialog will be displayed which allows a background colour to be selected. If the


Background Color button is clicked when anything else is selected, then the selection’s
background colour will be changed independently of the rest of the document.

Similarly, the Foreground Color button allows the foreground colour to be changed. In
most cases the term ‘foreground’ refers to the text.

To change the Title (i.e. what is displayed in the title bar of the Web browser) of a Web
page:

 Ensure that the document is selected.


 Modify the Title property using the Properties window (on the lower right-hand side
of the screen).

An appropriate title should be given to every page created.

 Spend some time experimenting with the different options to gain experience with
editing Web page documents in Visual Web Developer Express.

5.2.6 CodeBehind pages


CodeBehind pages are what bring an ASP.NET page to life. They contain the event-
handlers and other code that make an ASP.NET page work.

In the past, CodeBehind pages had to be created manually. However, with the advent of
Visual Web Developer, these pages are now automatically created for every page.
CodeBehind pages written in C# have the extension .cs.

To access a CodeBehind page:

 Open the Solution Explorer.


 Click the plus sign next to the name of the Web page (Default.aspx by default).
 Double-click on the CodeBehind file. This file will have the same name as the page to
which it belongs. Thus for the default page the CodeBehind file is called
Default.aspx.cs.

© CTI Education Group


Unit 5 – ASP.NET Page 123

In this guide, CodeBehind pages will be used frequently to provide functionality for
ASP.NET pages.

5.2.7 Exercises
1. Briefly explain the concept of a CodeBehind page.
2. Which keyboard shortcut is used to run an ASP.NET project?
3. Which view is used to create ASP.NET pages using a visual
interface?

5.2.8 Revision questions


1. True/False: CodeBehind pages are automatically created by
Visual Web Developer 2008.
2. True/False: The Visual Web Developer Express Web server will
always close when the Web browser is closed.
3. True/False: Visual Web Developer Express requires that a user
must have an understanding of how HTML works in order to create
ASP.NET pages.

© CTI Education Group


Unit 5 – ASP.NET Page 124

© CTI Education Group


Unit 5 – ASP.NET Page 125

5.3 ASP.NET: Events and controls

At the end of this subsection you should be able to:

 Add, use, and handle events with ASP.NET controls.

5.3.1 ASP.NET Controls


Just like Visual C# applications, ASP.NET pages use controls to interact with the user.
There are many types of controls, such as text labels, timers, buttons, and list boxes.
Many of these controls are very similar (and in some cases, identical) to their Visual C#
counterparts.

5.3.1.1 Adding a control to a ASP.NET page


To add a control (for example, a Button):

 Ensure that the Toolbox is open (if it is not, click View > Toolbox).
 If necessary, switch the editor window to the Design view.

NOTE Controls can still be added (and modified) in the Source view. Those
comfortable with HTML concepts are free to do so. However, this course will
only cover the use of the Design view.

 Click on the desired control in the Toolbox and drag the control to the desired position
as shown in Figure 5.13.

Figure 5.13 – Adding a control

There is a slight difference between standard Visual C# applications and ASP.NET


applications. Instead of the control being placed exactly where it is dragged to on the
form, the control will be placed in the nearest available space in the layout. This is
because, unlike a standard Visual C# application, an ASP.NET page is a dynamic
document.

© CTI Education Group


Unit 5 – ASP.NET Page 126

Take a look at the Button control (Figure 5.14) that was just added, in detail:

Figure 5.14 – A selected control

The Button control should be selected. If it is not, it can be selected it by clicking on it.

The text asp:button#Button1 will be seen. This text indicates two things:

1. The control is an asp:button control.


2. The ID of the control is Button1.

The ID of a control is used to keep track of that control, and so that it may be referred to
later when writing code. As with a standard Visual C# application, always rename the
controls to a unique, descriptive name (via the ID property).

5.3.1.2 Resizing a control


When a control is selected, three small blocks and a border around the control should be
seen. These blocks are tools which can be used to resize the control. To use them,
simply click on one and drag it. The blocks on the right and bottom sides of the control are
used to expand or contract those sides; the one on the bottom right is used to expand or
contract both sides at the same time.

5.3.1.3 Control properties


ASP.NET controls use properties which control how they look and function. Properties
can be modified by using the Properties window, which is shown by default in the bottom
right-hand side of the screen.

Properties were defined and explained in units 1 and 2 and these are much the same as
those shown in Figure 5.15. Properties may be of any type (i.e. int, string, collections,
any object). For example, the ID property of a control will expect a string value, while
the Visible property takes a bool value).

© CTI Education Group


Unit 5 – ASP.NET Page 127

Figure 5.15 – The Properties window

The first property of any control that should be modified is the ID property. This property
has the same purpose as the Name property in a standard Visual C# application. In this
case, the control will be renamed to TestButton.

In the Properties window:

 Scroll down until the (ID) field is visible.


 Replace Button1 with TestButton.
 Press the <Enter> key.

Observe the change in the editor window as shown in Figure 5.16:

Figure 5.16 – TestButton

Notice that the ID has changed to TestButton.

The next property which will be changed is the Text property. This property controls the
text which is displayed on the button.

 Change the Text property from Button to Test.

© CTI Education Group


Unit 5 – ASP.NET Page 128

There are many ASP.NET controls, each of which has their own unique functionality and
properties. However, there are several properties which are common to most, if not all,
controls and these are displayed in Table 13:

Table 13 – Common ASP.NET properties


Name Data Type Description
(ID) string Specifies the name of the control.
Text string Specifies what text is displayed on the control.
TabIndex int When the <Tab> key is pressed in a Web
browser, the next control will be selected. This
property sets the order in which controls are
selected (i.e. if this control has a value of 0 and
is selected, when the user presses the <Tab>
key, the control which has a TabIndex of 1 will
be selected)
BackColor, string
Specifies what colour to use for the specified
BorderColor, (HTML colour code)
item (i.e. background, border, text).
ForeColor
Font Multiple This specifies what font to use, whether it is
bold, italic, underlined, and/or struck out as well
as specifying what font size to use.
Enabled bool Specifies whether or not the control is enabled.
A disabled control will be greyed out and will not
fire events.
ToolTip string Specifies what text to display when the mouse
hovers over the control.
Visible bool Specifies whether or not the control is visible to
the user.
Height, int Specifies the height and width of the control in
Width pixels.

5.3.2 ASP.NET events


As with Visual C# applications, events are used to add functionality to ASP.NET controls.

5.3.2.1 Adding an event-handler to a control


 Create a new website project in Visual Web Developer Express and call it EventTest.
 Add three controls to the document: a TextBox called userNameTextBox, a Label
called greetingLabel, and a Button called greetingButton. Arrange them, and
modify their properties such that they look like the screenshot in Figure 5.17:

© CTI Education Group


Unit 5 – ASP.NET Page 129

Figure 5.17 – EventTest

Now to add an event-handler to the Button:

 Double-click on the Button in the Design view.


 Type the following code into the event-handler:

protected void greetingButton_Click(object sender, EventArgs e)


{
greetingLabel.Text = "Greetings, " + userNameTextBox.Text + "!";
}

 Now save and run the application (press <F5>).


 Enter a user name into the TextBox, and click the Greet Me! Button. The result
should be similar to Figure 5.18:

Figure 5.18 – EventTest

This example demonstrates the similarities between ASP.NET and regular C#


applications.

5.3.2.2 ASP.NET code


The code, in its complete form, for the previous example should look like the following:

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using System.Data;

public partial class _Default : System.Web.UI.Page

© CTI Education Group


Unit 5 – ASP.NET Page 130

{
protected void Page_Load(object sender, EventArgs e)
{

protected void greetingButton_Click(object sender, EventArgs e)


{
greetingLabel.Text = "Greetings, " + userNameTextBox.Text + "!";
}
}

The class above (most of which has automatically been generated by Visual Web
Developer Express) is derived from System.Web.UI.Page which represents an
ASP.NET page. As with Visual C# forms, this class is defined as being partial. The
rest of the class is defined in the .aspx document itself.

5.3.2.2.1 Page_Load
Another event-handler defined as Page_Load can be seen inside the class declaration.
This is an event that belongs to the page itself (as opposed to a control) and is called
when the ASP page is loaded. This event-handler is generally used to set up the page as
necessary, such as to load information from a database or text file, check to see if a user
is logged in, or dynamically set the content of lists and other controls.

5.3.2.3 Adding different types of event-handlers to controls


Sometimes it will be necessary for code to execute even if the user has not clicked a
button. For example, there may be two lists on a page. If options in the second list must
change depending on a selection made in the first list, an OnSelectedIndexChanged
event could be used. Alternatively, if the contents of a TextBox must be checked without
waiting for the user to click a button, a TextChanged event can be used.

To add any event-handler to a control:

 Select the control in the Design view.


 In the properties window, click the Events button as shown in Figure 5.19.

© CTI Education Group


Unit 5 – ASP.NET Page 131

Figure 5.19 – Event properties

 Double-click the desired event (in this case, TextChanged).


 Type in the necessary code.
For this example, copy the code from the greetingButton_Click event-handler
and paste it into the userNameTextBox_TextChanged event-handler.
 Run the application, and then enter some text into the TextBox.
 Once the <Enter> key has been pressed (which indicates to the ASP.NET page that
the typing is now finished), the event-handler will be called and the text for the
greetingLabel control will be changed.

5.3.3 Common events


Table 14 lists events that could conceivably happen with any control (common events):

Table 14 – Common events


Name Description
Init This event is triggered on all controls once they have all been initialized.
PreRender This event is triggered after:
a) The page has loaded and
b) All controls which use data-binding have been bound
Load This event is triggered once the page has been loaded.
Unload This event is triggered when the page is closed.
DataBinding This event is triggered before the PreRender event is called on any
controls. It is triggered at the same time as data is bound to the control
(should the control use data-binding).

© CTI Education Group


Unit 5 – ASP.NET Page 132

Most controls have events which are specific to them. The events listed in Table 14 are,
however, common to all controls.

5.3.4 More on ASP controls


In this section, several ASP.NET controls which are commonly used will be looked at in
detail. It is expected that the use and operation of all these controls is understood. Thus,
create a test project and experiment with each of the controls as they are covered. Always
remember to change the default control names to something unique and descriptive.

5.3.4.1 Label controls


Label controls are used to display text on a Web page in ASP.NET. Label controls are
generally used to display text which might change during the execution of the application.

Text in a Label can be changed by modifying the Text property of the Label control.
Not only may the text be changed but the font colour, background colour, font, and visibility
can all be altered as well through the respective properties.

5.3.4.2 TextBox controls


The TextBox control can be used either as a text field (one line) or as a text area (more
than one line). This is controlled via the TextMode property.

5.3.4.2.1 TextBox control properties


The TextBox control properties are listed in Table 15.

Table 15 – TextBox control properties


Name Description
Text Specifies (or returns) the text currently displayed in the control.
TextMode Specifies whether the TextBox is SingleLine (default),
MultiLine, or Password. If set to Password, the characters which
the user enters will only be visible as dots.
Rows Specifies the number of rows the TextBox contains. Only has an
effect when the TextMode is set to MultiLine.
Columns Specifies the number of columns that the TextBox must contain; each
character takes up one column. Only has an effect when TextMode is
set to MultiLine.
ReadOnly Specifies whether or not the field may be edited.
MaxLength Specifies the maximum number of characters the TextBox will accept.
Wrap Specifies whether or not the text should wrap to the next line when the
edge of the TextBox is reached. If set to false, the text continues
on the same line. Only has an effect when TextMode is set to
MultiLine.

© CTI Education Group


Unit 5 – ASP.NET Page 133

Figure 5.20 shows some of the properties being applied to a TextBox control:

Figure 5.20 – TextBox controls with varying property values

5.3.4.3 DropDownList controls


DropDownList controls allow the user to select a single value from a list. When a
DropDownList control is added to an ASP page, the image displayed in Figure 5.21
should be seen:

Figure 5.21 – DropDownList creation

If this menu is hidden and needs to be accessed again, simply click the small arrow button
on the right hand side of the control (the same button can be used to hide the menu if it is
already visible). There are three options available here:

5.3.4.3.1 Choose Data Source…


This option is intended to be used with data binding. This will be covered in detail later.

5.3.4.3.2 Edit Items…


This option will allow items in the list to be edited. When Edit Items… is selected, the
dialog shown in Figure 5.22 will be presented. This dialog allows addition, modification,
and removal of items from the list. The interface is fairly self-explanatory: the Add and
Remove buttons are used to add or remove items from the list. To change the text of the
item, select it in the list and modify the Text property which will be displayed on the right.
The Value property will automatically change to match the text property, but it can also be
changed to a different value if desired.

© CTI Education Group


Unit 5 – ASP.NET Page 134

Figure 5.22 - Adding items to a DropDownList

Once the changes have been made, click the OK button to confirm the changes. If it is
necessary to revert to the previous state (i.e. before the dialog was opened), click Cancel.

5.3.4.3.3 Enable AutoPostBack


Most ASP.NET controls have a property called AutoPostBack. If this property is set to a
value of false, then the control will not be able to trigger events. The reverse is true: if
the property has a value of true, then it will trigger any associated events. Some
controls (such as a Button) have AutoPostBack set to true by default, but many do
not. The DropDownList is one such control.

If it is necessary to perform an operation such as validating data, or modifying other


controls, then AutoPostBack must be set to true. This property can be manually
changed using the Properties window, as shown in Figure 5.23.

Figure 5.23 – The AutoPostBack property

© CTI Education Group


Unit 5 – ASP.NET Page 135

Figure 5.24 shows how a DropDownList control looks:

Figure 5.24 – DropDownList control in action

5.3.4.3.4 DropDownList control properties


Table 16 below shows some of the DropDownList control properties.

Table 16 – DropDownList properties


Name Description
SelectedItem.Text Retrieves the Text property of the currently selected item.
SelectedValue Retrieves the Value property of the currently selected item.
SelectedIndex Sets or retrieves the index of the currently selected item. As
with arrays, the first index is 0.

5.3.4.4 RadioButtonList controls


A RadioButton is a control which allows the user to make a single selection from a
number of choices. As such, a single RadioButton control makes no logical sense.
Instead, a RadioButtonList control is used. This control creates a group of
RadioButton controls which are all linked to one another, so that only one can be
selected at a time. This also makes it easier to determine which RadioButton has been
selected.

When a RadioButtonList is added to an ASP.NET page, the same menu which was
used to work with the DropDownList control will be shown (and can also be shown again
later). The functionality is identical in both cases.

Figure 5.25 below shows what the RadioButton controls / RadioButtonList control
looks like in action:

© CTI Education Group


Unit 5 – ASP.NET Page 136

Figure 5.25 – RadioButtonList control in action

5.3.4.4.1 Modifying the appearance of a RadioButtonList:


By default, a RadioButtonList organises the items in a tabular format. The way in
which the table is constructed can be changed by modifying the RepeatColumns,
RepeatDirection and RepeatLayout properties.

It should also be noted that (as with almost any visual control) there are properties to
modify the font, background colour, and foreground colour.

5.3.4.4.2 RadioButtonList control properties:


The RadioButtonList control has the SelectedItem.Text, SelectedValue and
SelectedIndex properties, which are identical in functionality to those used with a
DropDownList.

5.3.4.5 CheckBox controls


A CheckBox control is similar to a RadioButton control, although the user may select
more than one value (from a group) at a time, as well as having the ability to deselect.
Unlike radio buttons, it is not uncommon to find a solitary check box on a form, such as the
one shown in Figure 5.26.

Figure 5.26 – A CheckBox control

5.3.4.5.1 CheckBox control properties


Table 17 shows the CheckBox control properties:

Table 17 – Checkbox control properties


Name Description
Checked Sets or retrieves the Checked state of the CheckBox. If the
property has a value of true, then the check box is checked. If the
property is false, then the check box is not checked.
AutoPostBack Set this property to true if the CheckBox needs to trigger events.

© CTI Education Group


Unit 5 – ASP.NET Page 137

5.3.4.6 CheckBoxList controls


There is often a need to use several related check boxes in the same location on a page.
In these situations, it is preferable to use a CheckBoxList control as it allows multiple
check boxes (and any selections the user might make) to be treated as a group.

The items in the CheckBoxList can be edited in exactly the same way as items in a
RadioButtonList or DropDownList would be edited. However, because the user can
select multiple values (as shown in Figure 5.27), the way in which values are determined
differs from all the controls explained previously.

Figure 5.27 – A CheckBoxList control in action

To determine whether a particular check box is checked the Items property of the
CheckBox control itself needs to be accessed. For example, to determine if the first box is
checked, the following code would be used (note that the Selected property is used in
place of the Checked property):

if (myCheckListBox.Items[0].Selected)
{
// Execute some code.
}

Likewise, if it is necessary to check the first box (without the user clicking on it), the
following code can could be used:

myCheckListBox.Items[0].Selected = true;

5.3.4.6.1 CheckListBox control properties


The CheckListBox control has the same properties (shown in Table 18) as the
RadioButtonList control, although they function differently:

© CTI Education Group


Unit 5 – ASP.NET Page 138

Table 18 – CheckListBox control properties


Name Description
SelectedItem.Text Retrieves the Text property of the currently selected item
with the lowest index.
SelectedValue Retrieves the Value property of the currently selected item
with the lowest index.
SelectedIndex Sets or retrieves the index of the currently selected item with
the lowest index. As with arrays, the first index is 0.
Note: If this property is used to set the selected index, all
other checked items will be unchecked.
Items Retrieves the collection of items in the list.

5.3.4.7 Button controls


Button controls are generally used to submit data on the form to the server so that it can
work with it. However, they can be used for many other purposes as well. There are three
types of Button controls, as shown in Table 19:

Table 19 – Button control types


Name Description
Button A standard Button.
LinkButton This Button works just like a standard Button, but it looks like a
normal hyperlink.
ImageButton This Button works just like a standard Button, but it displays an
image instead of text.

Figure 5.28 – The three Button control types

In order to set which image an ImageButton control uses, the ImageUrl property needs
to be used. However, before specifying which image to use, the image must be added to
the website project.

© CTI Education Group


Unit 5 – ASP.NET Page 139

To add an image to the website project:

 Open the Website menu.


 Click Add Existing Item.
 Using the file dialog, browse to the location of the desired image.
 Select the image and click Add.

The image is copied into the website directory and will now show up in the list when
specifying which image to use for the ImageButton control’s ImageUrl property. Note
that this procedure can be used to add images to the website for any purpose.

As with any other control, should the size of an ImageButton need to be changed (i.e.
scale the image up or down), simply change Height and/or Width properties of the
ImageButton.

5.3.4.8 HyperLink controls


The HyperLink looks the same as a LinkButton. However, the way in which it
functions is somewhat different. While the LinkButton functions in the same way as
other button controls, a HyperLink control directs the user’s Web browser to a specified
URL.

5.3.4.8.1 HyperLink control properties


Table 20 shows the HyperLink control properties:

Table 20 – HyperLink control properties


Name Description
Text This is the text displayed by the control.
ImageUrl This is the path to an image which can be displayed by the control.
If left blank, the control will display the text specified by the Text
property.
NavigateUrl This is the URL to which the Web browser must navigate when the
HyperLink control is clicked.

5.3.4.9 Panel controls


Panel controls are used as containers for other controls. A panel may or may not be
visible to the user (i.e. it may or may not be possible to tell the difference between the
panel and the rest of the page).

Panel controls (like all controls) have a property called Visible, which sets whether or
not the panel can be seen. When a panel is hidden, all of the controls displayed within it
are hidden as well.

© CTI Education Group


Unit 5 – ASP.NET Page 140

5.3.4.9.1 Panel control properties


Table 21 shows the Panel control properties:

Table 21 – Panel control properties


Name Description
Visible Specifies whether or not the panel (and all controls within it) are
visible or not.
BackImageUrl Specifies the path to an image which is used as a background
image.
Scrollbars Specifies whether scrollbars should be used. This can be set to
None, Horizontal, Vertical, Both or Auto. If set to Auto,
then scrollbars will appear on each side of the panel as necessary.
Wrap Specifies whether or not controls and text within the panel should
wrap to the next line, much the same as with a TextBox control.
HorizontalAlign Specifies how controls should be aligned within the panel, i.e.
centred, justified, etc.

5.3.4.10 Calendar controls


Calendar controls are used to allow the user to select a date using a visual interface.
Figure 5.29 displays a Calendar control:

Figure 5.29 – Calendar control

Calendar controls are very customisable. By modifying one of the many properties of a
Calendar control, a calendar which matches the theme of the Web pages can be created
quite simply. Several pre-designed templates can also be selected using the Auto
Format… option which can be found in the Calendar Tasks menu. As with several other
control types, the Tasks menu can be opened by clicking on the small arrow button on the
top right-hand side of the control as shown in Figure 5.30:

© CTI Education Group


Unit 5 – ASP.NET Page 141

Figure 5.30 – Calendar Tasks

Event-handlers can be created to handle the SelectionChanged event for this control if
it is necessary to perform any operation when the user selects a date.

5.3.4.10.1 Calendar control properties


Table 22 shows the Calendar control properties:

Table 22 - Calendar control properties


Name Description
SelectedDate Sets or retrieves the selected date.
SelectedDates Retrieves a collection of selected dates.
FirstDayOfWeek Sets the day which should be used as the start of each week in
this control.
SelectionMode Sets whether the user is able to select individual dates, weeks, or
entire months.
VisibleDate Sets which date should be visible in the control when it is loaded.
If not set, then the current date will be used.

5.3.4.11 HTML Tables


While there is a Table control available in ASP.NET, it cannot be created easily using
only the Design view. A brief discussion on the use of HTML tables to create pleasant,
user-friendly layouts is given below.

To add an HTML Table to the Web page:


 In the Toolbox, scroll down to the HTML section.
 Select Table and drag it on to the page.

This creates a default table with three rows and three columns. The area within the table
cells can be worked in the same way as anywhere else in the document, including the
addition of controls. To resize a column or row, simply click on the border and drag it in
the desired direction.

© CTI Education Group


Unit 5 – ASP.NET Page 142

Columns and rows can be added or removed. To do this, simply right click inside a table
cell. This brings up a menu which allows for insertion of new rows or columns, deletion of
the table, selection of different parts of the table, or modification of parts of the table. The
options available in this menu are fairly self-explanatory. For example, clicking on the
Insert > Column to the Left option adds a new table column to the left of the currently
selected cell.

HTML tables created in Visual Web Developer are by default set to take up the entire
available width. This can be changed by modifying the Style property of the table.

NOTE Those who have previous experience creating HTML Tables might be more
comfortable creating them in the Source view.

Figure 5.31 shows the menu which is displayed when right-clicking inside a table cell:

Figure 5.31 – Right-clicking in a table cell

Figure 5.32 shows how a table can be used to create a professional looking layout (in this
case, for a user registration form).

© CTI Education Group


Unit 5 – ASP.NET Page 143

Figure 5.32 – Using HTML tables to create form layouts

Knowledge of how to create and modify HTML tables will be expected for both the exams
and project, so experiment with them until a measure of comfort with their use in Web
pages is attained.

5.3.5 Exercises
1. Briefly explain the benefits of using an HTML table in an ASP.NET
page.
2. Briefly explain how the AutoPostBack property works.
3. Briefly explain what an ASP.NET control is.

5.3.6 Revision questions


1. True/False: Visual Web Developer Express provides functionality
for creating ASP tables visually.
2. True/False: Panel controls are commonly used to show and hide
groups of controls simultaneously.
3. True/False: Items in a CheckBoxList can only be selected by the
user. They cannot be selected using code, or pre-selected using
the Design view.

© CTI Education Group


Unit 5 – ASP.NET Page 144

© CTI Education Group


Unit 5 – ASP.NET Page 145

5.4 Validating data: Validation Controls

At the end of this subsection you should be able to:

 Understand the need for data validation.


 Use validation controls.

5.4.1 Validation
On many websites (especially those with active content, such as PHP or ASP.NET), data
needs to be obtained from the users for purposes of registration, confirmation, etc.
However, there is no guarantee that the user will always enter the required information,
nor is there any guarantee that it will be entered correctly. For this reason, entered data
should always be validated. There are many methods of validation, such as checking to
see if the user has left a certain field blank, to more complicated checks such as
determining if a date or email address is valid.

5.4.2 ASP.NET Validation controls


When server-side languages were first created, data validation was performed strictly on
the server side. While this was effective, if validation failed (i.e. the user entered invalid
data), the page would have to be sent to the client again and this took up unnecessary
time.

ASP.NET introduced a new concept: validation controls. These controls, which can be
added to ASP.NET websites much like any other controls, validate data on the client side,
before the data is sent to the server. If necessary, data can be further validated on the
server (for example, on a login page where the username and password need to be
checked against entries in a database). Each validation control validates a specific control
on the page.

There are six ASP.NET validation controls, as shown in Table 23:

Table 23 – ASP.NET validation control types


Name Description
RequiredFieldValidator Ensures that the user has entered a value, or
selected a value, for the specified control.
CompareValidator Compares the value from the user against
another value.
RangeValidator Checks that the value entered by a user falls
within a specified range.

© CTI Education Group


Unit 5 – ASP.NET Page 146

RegularExpressionValidator Compares a value entered by the user against a


regular expression.
CustomValidator Intended to be used to create customised
validation controls.
ValidationSummary This defines how, where, and what must be
done with the validation errors that may have
occurred on the page.

5.4.3 Using validation controls


To add a validation control to a page:

 In the Toolbox, scroll down to the Validation subsection.


 Select the desired validation control where the message should be displayed (this
message will only be displayed if validation fails).

Validation controls appear to the user as error messages (which are only shown should
the data validation fail), so place them accordingly. To set a control to be validated, the
ControlToValidate property needs to be set to the ID of that control. To set which text
is displayed if an error occurs, modify the ErrorMessage property. As with labels, the
font and colour can be changed as required.

 Create a new project. This project will be used for the rest of this section.

5.4.3.1 The RequiredFieldValidator control


The RequiredFieldValidator control is the easiest of the validation controls to use.
For the following example the initial stage of a user registration form (shown in Figure
5.33) has been created:

 An HTML table with four columns (one is used as a space between the textboxes and
their descriptions) has been used to create the layout.
 One TextBox control is called NameTextBox and the second SurnameTextBox.
 The two RequiredFieldValidators have had their ControlToValidate
properties set to the ID of the appropriate control. They have also had their
ErrorMessage and ForeColor properties changed.
 The ID for the Submit Button has been changed to SubmitButton. The
SubmitButton does not need any event-handlers in order to trigger validation.

Figure 5.33 – RequiredFieldValidators

© CTI Education Group


Unit 5 – ASP.NET Page 147

 By way of experiment, add an OnClick event-handler to the SubmitButton.


 Make the event-handler change the text of SubmitButton to “Success”.

protected void SubmitButton_Click(object sender, EventArgs e)


{
SubmitButton.Text = "Success";
}

 Now run the page and click the Submit button without entering any data.

Notice from Figure 5.33 that only the RequiredFieldValidator error messages are
visible. This is because nothing is sent to the server until validation has been completed.

Figure 5.34 shows how the form looks after data has been entered and SubmitButton
has been clicked:

Figure 5.34 – RequiredFieldValidators after data has been entered

5.4.3.2 The CompareValidator control

5.4.3.2.1 Comparing the value in a control against a specific value


The CompareValidator checks to see if the user has entered a certain value. In many
websites, this control would be used in conjunction with a computer-generated image to
determine whether or not the user is human (i.e. not a software robot filling the form with
random data). For the purposes of this example, a sample image will be used. The user
is asked to enter the text they see in the image. Figure 5.35 shows an example of a
CompareValidator in action.

Figure 5.35 – A CompareValidator in action

© CTI Education Group


Unit 5 – ASP.NET Page 148

In the above example:

 The image is an Image control with its ImageUrl property set to use the sample
image. The text in the image is Qx4B2P.
 The CompareValidator control has its ControlToValidate property set to
imageVerificationTextBox, and its ValueToCompare property set to Qx4B2P.

5.4.3.2.2 Comparing the value in one control with the value in another
In addition to comparing the input by the user against a specific value, the
CompareValidator control can also be used to check to see if the value in one control
matches the value in another. This is commonly used to get the user to confirm a data
field, such as an email address or password.

Figure 5.36 shows how a CompareValidator can be used to compare control values:

Figure 5.36 – A CompareValidator used to compare control values

The ControlToCompare property is used in this case. The validation control compares
the value of its ControlToValidate against the value of its ControlToCompare to
determine if they are the same.

5.4.3.3 The RangeValidator control


The RangeValidator control is used to check if the user has entered a value which falls
between a specific range of numbers. For example, it might be necessary to have the
user enter a number between 1 and 100 and if any other number is entered, the validation
should fail.

A RangeValidator control can compare values of various data types, namely: String,
Integer, Double, DateTime, and Currency. The data type which the control is
checking is specified by its Type property.

© CTI Education Group


Unit 5 – ASP.NET Page 149

The range which the control uses is specified by its MinimumValue and MaximumValue
properties.

In the following example (Figure 5.37), the Type for RangeValidator has been set to
Integer, the MinimumValue has been set to 13 and the MaximumValue has been set
to 110:

Figure 5.37 – A RangeValidator in action

5.4.3.4 The RegularExpressionValidator control


This control compares a value entered by the user against a regular expression. These
are most commonly used to ensure that the user has entered a valid email address,
password (should the password have a required format), telephone numbers, identity
numbers, and credit card numbers.

The ValidationExpression property specifies the regular expression that should be


used by this control. Any regular expression can be used here (such as the one used in
Unit 3). Visual Web Developer provides a list of pre-defined regular expressions which
can also be used. To access this list, click the button to the right of the property field. The
Regular Expression Editor (Figure 5.38) will be seen.

© CTI Education Group


Unit 5 – ASP.NET Page 150

Figure 5.38 – The Regular Expression Editor

Figure 5.39 shows how a RegularExpressionValidator can be used to check if an


email address is valid:

Figure 5.39 – A RegularExpressionValidator in action

5.4.3.5 The CustomValidator control


The CustomValidator control is different from the other validation controls. Instead of
using a pre-defined validation method, this control has been created to define custom
validation methods.

 Start by adding the following to the form:

© CTI Education Group


Unit 5 – ASP.NET Page 151

Figure 5.40 – CustomValidator

The controls in Figure 5.40 have been added to the form between the Age and Image
verification fields (refer to Figure 5.41). The values in the CheckBoxList have added
using the Edit Items… dialog, and the CustomValidator has not had its
ControlToValidate property set. A CheckBoxList control cannot be validated
using standard validation methods and an Exception will be thrown if this is attempted.
The solution is to use a custom validation procedure.

To define the validation procedure:

 Double-click on the CustomValidator control in the Design view.


 Code the procedure as usual. For this example, use the following code:

protected void NewsletterValidator1_ServerValidate(object source,


ServerValidateEventArgs args)
{
// Count the number of selections made.
int selectedCount = 0;
for (int loop = 0; loop < NewsletterCheckBoxList.Items.Count; loop++)
{
if (NewsletterCheckBoxList.Items[loop].Selected)
{
selectedCount++;
}
}

// If 2 or more selections have been made, validation successful


// invalid otherwise.
args.IsValid = selectedCount >= 2;
}

 Now save and run the Web page.

Note that if args.IsValid is false, the error message will be displayed to the user. If it
is true, no message will be displayed. When this Web page is run and the user selects
fewer than two newsletters to subscribe to, then the error message will be displayed.
However, it is also evident that the button text still changes to Success, even though
validation for the CustomValidator failed. This is because CustomValidators are
evaluated server-side (unlike other validation controls), which means that the page is sent
to the server and event-handlers are processed. However, ASP.NET does account for
this.

© CTI Education Group


Unit 5 – ASP.NET Page 152

The Page object (which is part of every ASP.NET page) contains a property called
IsValid. This property has a value of true only if every validation control in the page
successfully validates their data. If any data fails validation, the IsValid property will be
false. This property can be checked at any time to determine whether or not the page
has passed validation.

 Modify the SubmitButton control’s event-handler so that it looks like the following:

protected void SubmitButton_Click(object sender, EventArgs e)


{
if (Page.IsValid)
{
SubmitButton.Text = "Success";
}
}

Figure 5.41 shows the result:

Figure 5.41 – CustomValidator in action

Note that any server-side validation (i.e. the CustomValidator control) will not be
performed until all other validation is successful.

© CTI Education Group


Unit 5 – ASP.NET Page 153

5.4.3.6 The ValidationSummary control


The ValidationSummary control allows the Web page to show a user exactly which
validation failed in a specific place. It is particularly useful for long forms where the user
might have to spend time scrolling up or down looking for fields which have been entered
incorrectly.

This control is very easy to use, since all that needs to be done is to insert it into the form
in the desired location (which will usually be above the form), and specify its HeaderText
property. The HeaderText property specifies which text should be displayed before
listing any validation errors.

Figure 5.42 shows a ValidationSummary control in action:

Figure 5.42 – ValidationSummary in action

Should it be necessary to only display errors in the ValidationSummary control (and not
anywhere else), then each of the other validation control’s Display properties must be

© CTI Education Group


Unit 5 – ASP.NET Page 154

set to None. The error messages will then not be displayed on the page, but will still set to
the ValidationSummary control.

5.4.3.7 A final note on validation controls


Something that is often overlooked when working with validation controls is that they only
perform the operation for which they are designed. Bear in mind that all fields which are
not optional require RequiredFieldValidators, even those which already have
other validation controls.

Having more than one validation control for a specific field can throw the page layout out of
alignment. To fix this, set the Display properties for each control to Dynamic. Naturally,
this problem does not occur if the errors are only displayed in a ValidationSummary
control (i.e. the Display property for the control is already set to None).

Figure 5.43 shows the form (in Design view) with RequiredFieldValidators added for
each field except for the CheckBoxList.

Figure 5.43 – Design view for the final form

© CTI Education Group


Unit 5 – ASP.NET Page 155

5.4.4 Exercises
1. Briefly describe the reasons for data validation.
2. Describe two uses for a CompareValidator control.
3. Which property is used to determine if all the data on a page was
successfully validated?

5.4.5 Revision questions


1. True/False: All validation controls are evaluated on the client-side.
2. True/False: A RequiredFieldValidator is not necessary for a
required field which is already validated by a
RegularExpressionValidator.
3. True/False: CustomValidator controls are evaluated server-side.

© CTI Education Group


Unit 5 – ASP.NET Page 156

© CTI Education Group


Unit 5 – ASP.NET Page 157

5.5 Data-binding

At the end of this subsection you should be able to:

 Use data-binding with list and GridView controls.


 Understand and use the IsPostBack property.

5.5.1 What is data-binding?


Up to this point, if it has been necessary to set the contents of a control, the only way to do
this has been to edit the Items property for that control (i.e. using the Edit Items… option
from that control’s task menu). While this is a perfectly acceptable solution for most cases,
what if it is necessary to set the contents dynamically? This is where data-binding comes
in. Data-binding allows the contents of certain types of controls to be set dynamically at
runtime. The principle involves binding the control to a specific source of data (hence
the name). The data source is generally a Collection, although there are exceptions.

5.5.2 Data-binding in practice

5.5.2.1 Data-binding lists


The following list controls support data-binding:

 ListBox
 DropDownList
 RadioButtonList
 CheckBoxList

 Create a new project. This project will be used to experiment with data-binding.
 Add a CheckBoxList control to the default page. Give the ID a value of
TestCheckBoxList.
 Open the CodeBehind page and type the following code in the Page_Load event-
handler:

protected void Page_Load(object sender, EventArgs e)


{
ArrayList TestArrayList = new ArrayList();
TestArrayList.Add("Item One");
TestArrayList.Add("Item Two");
TestArrayList.Add("Item Three");
TestArrayList.Add("Item Four");
TestArrayList.Add("Item Five");
TestCheckBoxList.DataSource = TestArrayList;
TestCheckBoxList.DataBind();
}

© CTI Education Group


Unit 5 – ASP.NET Page 158

 Import the System.Collections namespace.


 Save and run the project. Figure 5.44 shows the contents of the CheckBoxList
control:

Figure 5.44 – A data-bound CheckBoxList

As can be seen, data-binding is very easy to use. All that needs to be done is to get the
data into a collection, and then bind it to the desired list control.

5.5.2.2 PostBack
 Add a Button control to the page.
 Save and run the project.
 Check a few items in the list and click the Button.

Notice how the selections that have been made are lost. This is because, technically, the
list is cleared and recreated each time the page is reloaded. Fortunately, ASP.NET has
functionality which can be used to avoid this.

 Modify the Page_Load event-handler so that it looks like the following:

protected void Page_Load(object sender, EventArgs e)


{
if (!Page.IsPostBack)
{
ArrayList TestArrayList = new ArrayList();

TestArrayList.Add("Item One");
TestArrayList.Add("Item Two");
TestArrayList.Add("Item Three");
TestArrayList.Add("Item Four");
TestArrayList.Add("Item Five");

TestCheckBoxList.DataSource = TestArrayList;
TestCheckBoxList.DataBind();
}
}

 Save and run the project.

Now, if selections are made in the list and the Button is clicked, those selections will not
be removed because the list is no longer recreated each time the page is reloaded.

© CTI Education Group


Unit 5 – ASP.NET Page 159

As seen from the above example, the Page object contains a property called
IsPostBack. This property will return false the first time a page is loaded; thereafter it
will return true. This property can therefore be used to check if it is necessary to load
any data and perform data-binding and not have to worry that the code will be called
multiple times.

5.5.3 Data-binding and classes


In much in the same way as a Collection of type string may be bound to a control, it is
possible to bind a collection of objects to a control. Before this can be done, it is
necessary to explore how custom classes are added to ASP.NET projects.

5.5.3.1 Adding a class to an ASP.NET project


 Open the Website menu.
 Click Add New Item…
 Select Class in the list and give it an appropriate name (for this example, Product).

The dialog shown in Figure 5.45 should now be seen:

Figure 5.45 – App_Code dialog

This dialog asks if the programmer wants to place the class source code file (.cs) in the
App_Code directory. Placing a class in this directory makes it accessible in any of the
pages for the website.

 Click Yes.
 Now code the class as per usual. For this example, use the following code:

/*
* The 'Product' class
* Description: A class which stores basic information about a product.
*/
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;

© CTI Education Group


Unit 5 – ASP.NET Page 160

using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public class Product


{
protected int id;
protected string desc;
protected double price;

public Product(int id, string desc, double price)


{
this.id = id;
this.desc = desc;
this.price = price;
}

public int Id
{
get
{
return id;
}
set
{
id = value;
}
}

public string Description


{
get
{
return desc;
}
set
{
desc = value;
}
}

public double Price


{
get
{
return price;
}
set
{
price = value;
}
}
}

This code creates a very basic Product class which can be used to store information
about one specific product. This class can now be used with data-binding.

© CTI Education Group


Unit 5 – ASP.NET Page 161

5.5.3.2 Binding a class to a control


 Return to the Default.aspx.cs tab.
 Modify the Page_Load event-handler such that it looks like the following:

protected void Page_Load(object sender, EventArgs e)


{
if (!Page.IsPostBack)
{
// Create an ArrayList of Product objects.
ArrayList TestArrayList = new ArrayList();

TestArrayList.Add(new Product(1, "Hat", 49.95));


TestArrayList.Add(new Product(2, "Shoes", 89.95));
TestArrayList.Add(new Product(3, "Jacket", 129.95));
TestArrayList.Add(new Product(1, "Gloves", 29.95));

// Set which property to display.


TestCheckBoxList.DataTextField = "Description";

// Data-bind.
TestCheckBoxList.DataSource = TestArrayList;
TestCheckBoxList.DataBind();
}
}

 Save and run the project. The result should look as follows (Figure 5.46):

Figure 5.46 – A CheckBoxList bound to an ArrayList of Products

As can be seen from the above example, binding a collection of objects to a list is very
similar to binding a collection of type string. The main difference is in the use of the
DataTextField property for the TestCheckBoxList control. This property specifies
which of the object’s properties must be bound to the control.

5.5.4 Data-bound controls


In addition to list controls, there are several other ASP.NET controls which support data-
binding. In actuality, many of these controls were designed from the ground up to work
with data-binding. These controls are intended to work with data which is generated at
runtime, such as reading from databases, files, or displaying calculated data.

The data-bound controls covered in this guide are summarised in Table 24:

© CTI Education Group


Unit 5 – ASP.NET Page 162

Table 24 – Data-bound controls


Name Description
GridView Displays data in a tabular format and supports sorting columns,
paging through data, as well as editing and deleting of individual
records.
DataList Displays data in a flow or column layout.
Repeater Displays data using a user-defined template.
ListView Similar to DataList and Repeater controls, but selection,
insertion, editing, and deleting of data are supported.
DetailsView Displays a single record at a time from a data source. Also
supports selection, insertion, editing, and deleting of data.
FormView Displays a single record at a time from a data source using a user-
defined template. Also supports selection, insertion, editing, and
deleting of data.

All of these controls can be found in the Toolbox in the Data section.

5.5.4.1 GridView
The GridView control is a powerful control used to display data in a tabular format.
Columns are automatically generated based on the data source for the GridView. When
a GridView control is added to a page, the GridView Tasks menu will be shown. This
menu functions in much the same way as Tasks menus previously covered. However, the
options presented here are different, as shown in Figure 5.47:

Figure 5.47 – GridView Tasks menu

The first option, Auto Format… allows a template to be chosen (from a list) which
specifies how the control should look. Should more control be needed over the
appearance of the GridView control, its properties can also be modified.

The second option, Choose Data Source: allows a data source to be chosen from a list of
sources which have already been added to the website, such as a database or XML file.
However, at this point the list will be empty.

© CTI Education Group


Unit 5 – ASP.NET Page 163

 Before continuing, try adding a GridView control to the page and binding it to the
TestArray. The table displayed in Figure 5.48 should be seen:

Figure 5.48 – Data-bound GridView

The third option in the Tasks menu, Edit Columns… opens a dialog called the Fields
dialog (Figure 5.49).

Figure 5.49 – Fields dialog

This is tool is similar to the Edit Items dialog which is available for list controls, but it is far
more powerful. By default, a GridView control will automatically generate columns based
on the data source to which it has been bound. In situations where the exact structure of
the data source is not known, these automatically generated columns will most likely be
sufficient. However, programmers and designers will usually want to specify their own
layouts.

Continuing with the product list, it might not, for example, be necessary for the Id column
to be visible. In this case, the auto-generation of columns would need to be disabled.

 Remove the check in the Auto-generate fields check box (in the lower left-hand side
of the Fields dialog).

© CTI Education Group


Unit 5 – ASP.NET Page 164

Now, because the fields are no longer generated automatically, the Description and Price
columns must be generated manually (or else the GridView control will have nothing to
display). There are many types of fields (columns in a GridView control) to choose from.
Table 25 shows some of these fields and what they are used for:

Table 25 - GridView control field types


Name Description
BoundField This is the most commonly used field. These fields are bound to a
property or column in the data source. This will be displayed as
text.
CheckBoxField This is a field which contains a CheckBox.
HyperLinkField This field type will display a HyperLink.
ImageField This field type will display an Image.
ButtonField This field type contains a Button.
CommandField This field type contains a command.
TemplateField This field type is used to create custom fields when the other field
types do not offer the necessary functionality.

Using the above fields can become quite complicated, especially for those who have not
used them before.

The Description and Price fields are both text and should thus both be of the
BoundField type.

 In the Fields dialog, select BoundField and click Add.

The field properties will now be seen on the right-hand side of the dialog. These
properties are used to customise the appearance and functionality of the BoundField.

Table 26 highlights the properties which will be used:

Table 26 – BoundField properties


Name Description
HeaderText The text displayed in the header cell for this field. This property
is often used to make field headers easier to understand (e.g. if
the data source has a complicated field name, this property
could be used to display it as a simpler, more user-friendly
header).
DataField Specifies which property or column of the data source to bind to
this field.
DataFormatString Specifies a format for the data to be displayed in. This uses the
same standard as the string formatting shown in Unit Two.

© CTI Education Group


Unit 5 – ASP.NET Page 165

 Enter the following values for the first BoundField:


o HeaderText : Item Description
o DataField : Description
o Leave DataFormatString blank.

 Create another BoundField and give it the following properties:


o HeaderText: Item Price
o DataField: Price
o DataFormatString: R{0}

 Close the Fields dialog.


 Click OK.
 Save and run the application. It should look like the table in Figure 5.50:

Figure 5.50 – GridView with customised fields

The fourth option in the Tasks menu, Add New Column… is a simplified version of the
Fields dialog which is used to add a new column. This dialog is particularly useful for
creating more advanced fields, such as the HyperLinkField or ImageField types, as
it vastly simplifies the process by highlighting important properties.

The last option, Edit Templates, switches the GridView control into template editing
mode. The templates which can be edited define how (a) empty cells look and (b) how the
paging interface looks (should the GridView control use paging. Paging is used to split
large quantities of data into more manageable sections (pages)). To return to the normal
mode, open the Tasks menu and click End Template Editing.

NOTE From this point on, all data-bound controls in examples will be auto-formatted,
using the Professional style where possible. Any format style may be used,
but ensure that it is always eye pleasing and that it fits in with theme for the
rest of the website.

5.5.4.2 Other data-bound controls


The other data-bound controls do not support being bound to a collection in the same way
as list controls and the GridView control. Instead they must be attached to data sources
such as databases and XML files. These controls will be covered in the next section.

© CTI Education Group


Unit 5 – ASP.NET Page 166

5.5.5 Exercises
1. Name three data-bound controls.
2. Describe two ways of binding a data source to a control.
3. Give two reasons why auto-generation of GridView fields is not
always desirable.

5.5.6 Revision questions


1. True/False: Controls can only be data-bound to collections such as
an ArrayList.
2. True/False: The DataSource property defines which property or
column of the data source to bind to a field.
3. True/False: The DataFormatString property uses the same
standard as string formatting.

© CTI Education Group


Unit 5 – ASP.NET Page 167

5.6 Using databases with ASP.NET

At the end of this subsection you should be able to:

 Data-bind database content to data-bound controls.


 Create templates for data-bound controls, both visually and using
the Source view.
 Manually connect to a database, execute queries and/or
commands, and work with retrieved data.

5.6.1 Databases
In Unit 4, opening and using database connections was covered. This knowledge will now
be put into practical use with ASP.NET.

5.6.1.1 Adding a Microsoft Access 2007 Database to a website


Firstly, a database will need to be created.

 Create a new CollegeDatabase database in MS Access 2007.


 Create a Learner table as shown in Figure 5.51:

Figure 5.51 – The Learner table

 Create a new website and call it DatabaseTestAccess2007.


 In the Solution Explorer, right click on the App_Data folder.
 Click Add Existing Item…
 Browse to the location of the database.
 Click Add.

© CTI Education Group


Unit 5 – ASP.NET Page 168

The database will now be displayed in the Solution Explorer (Figure 5.52).

Figure 5.52 – The Solution Explorer after a database has been added

The database has now been copied into the working folder for the website.

NOTE
The original database will not be modified should any changes be made.

5.6.1.2 Selecting data from an MS Access 2007 database


For the time being, a GridView control will be used as it is the easiest of the data-bound
controls to work with.

 Add a GridView control and call it grdLearners.


 Click the > next to the GridView control.
 In the Choose Data Source: dropdown list select the <New data source…> option.

The window shown in Figure 5.53 will appear:

Figure 5.53 – Adding a data source

© CTI Education Group


Unit 5 – ASP.NET Page 169

 Select the Database option.


 Enter an ID for the data source. It can be left as the default.
 Click OK.

The window shown in Figure 5.54 will appear:

Figure 5.54 – Configuring the data source

 Click on the New Connection button.

The window shown in Figure 5.55 will appear:

Figure 5.55 – Adding a connection to the data source

© CTI Education Group


Unit 5 – ASP.NET Page 170

 Select the Data source (in this case, the Microsoft Access Database File (OLE DB)
will suffice).
 Click the Browse button to select the database that has been copied to the App_Data
folder in your project.
 Click OK.

The Configure Data Source window shown in Figure 5.53 will appear again.

 Click Next >.

When the next Configure Data Source window asks Do you want to save the
connection in the application configuration file?, click Yes, save this connection as:
defaultName.

The window shown in Figure 5.56 will appear:

Figure 5.56 – Changing the SELECT statement

This dialog is used to configure exactly what data the GridView control should display.
The interface may be used to select which fields should be displayed (and in what order),
or a custom SQL statement can be created (which will generally be used for more
complicated queries or in most situations in which the database needs to be modified.).
For this example, the interface will be used.

 In the Columns window, click the check box next to * (remember that, in SQL, the
asterisk symbol (*) indicates that all the columns in a table must be selected).

© CTI Education Group


Unit 5 – ASP.NET Page 171

Notice how the SQL statement is created in the lower portion of the screen, in the
SELECT statement: window. In most situations, simply displaying the contents of a table
is not desirable – it will almost always be necessary to display more specific data. The
SQL statement that is generated here (which changes depending on the options and
conditions that are selected) will define what data is available to be worked with.

 Click Next >.

A window will now be shown which will allow the query to be tested to see whether or not
the results are as expected.

 Click Test Query.

The window shown in Figure 5.57 will appear:

Figure 5.57 – Test the SELECT query statement

 Click Finish.

This example shows how easy it is to connect to a database and display information in
ASP.NET.

Remember that the data source can always be modified as necessary by selecting it in the
design view and expanding its Tasks menu (Figure 5.58):

© CTI Education Group


Unit 5 – ASP.NET Page 172

Figure 5.58 – The AccessDataSource Tasks menu

 Click on the > next to the GridView control.


 Click on the Auto Format option to change the design of the GridView control (as
shown in Figure 5.59).

Figure 5.59 – Changing the design of the GridView control

 Select Professional from the list of schemes.


 Click OK.
 Press <Ctrl> + <F5> to save and run the Web page.

Figure 5.60 shows what the GridView control will look like when it is run:

Figure 5.60 – GridView control in action

© CTI Education Group


Unit 5 – ASP.NET Page 173

5.6.1.3 Selecting data from a MS SQL database


When binding data to a control using a SQL database, the data source is added in almost
the identical way as it is when adding an MS Access 2007 data source.

 Create a new website and call it DatabaseTestSql.


 Add a GridView control to the Default.apsx page and call it grdLearners.
 Follow the same steps up to Figure 5.57.
 Change the data source to Microsoft SQL Server (Figure 5.61).

Figure 5.61 – Adding a SQL Server database

 Click OK.

The Add Connection window will appear as shown in Figure 5.62:

Figure 5.62 – Adding a SQL connection to the data source

© CTI Education Group


Unit 5 – ASP.NET Page 174

Two things have to be entered on this window: the server name and the database name.

 The server name is the server on which your MS SQL Server Management Studio is
running. This can be seen when the SQL Server Management is opened
(Figure 5.63).

Figure 5.63 – Server name

As soon as the server name is entered, the database name text box will be enabled.

 Click on the arrow next to the Select or enter a database name: dropdown list which
will give you a list of databases that exist in the specific server. Ensure that the
database has been created on the PC on which you are working.
 Click OK.

The same window as shown in Figure 5.56 (previous section) will appear.

 Click Next >.


 The dialog to save the connection in the configuration file will appear again. Select
Yes and click Next >.
 Select *.
 Click Next >.
 Select Test Query in the next window.
 Click Finish.
 Change the design of the GridView as done in the previous example by using the
Auto Format… option.
 Press <Ctrl> + <F5> to save and run the Web page.

The output will be as follows (Figure 5.64):

© CTI Education Group


Unit 5 – ASP.NET Page 175

Figure 5.64 – Binding data from a SQL database to a GridView control

5.6.2 Data-bound controls


The various data-bound controls will now be covered using MS Access 2007 and MS SQL
Server.

5.6.2.1 Repeater control


The Repeater control is used to display information from a data source using templates.
Figure 5.65 shows a Repeater added to the page:

Figure 5.65 – Adding a Repeater control

As can be seen, Visual Web Developer has no visual functionality for editing templates
used by a Repeater control. As such, it will be necessary to create these templates in
Source view.

5.6.2.1.1 Binding data from a MS Access 2007 database to a Repeater control


 Return to the DatabaseTestAccess2007 example created earlier.
 Add a Repeater control to the Default.aspx page and name it TestRepeater.
 Add the data source to the Repeater control in exactly the same way as it was added
to the GridView control.
 Ensure that the Repeater control is selected before switching to the Source view.

© CTI Education Group


Unit 5 – ASP.NET Page 176

The following should now be seen (Figure 5.66):

Figure 5.66 – Repeater control source code

This code should seem reasonably familiar to those with HTML experience. Fortunately
for those without such experience, Visual Web Developer implements a powerful code
completion feature in the Source view. Simply begin typing a tag (indicated by an opening
triangular bracket ‘<’), and a list of tags will be presented from which a selection can be
made.

As can be seen, if an item is selected in the Design view, it will also be selected in the
Source view. This can be useful to help find a specific control without wading through lots
of unfamiliar code. A template will now be created for the repeater control so that data
from the database can be displayed in the desired format.

 Deselect the code.


 Click at the end of the first tag (line 34 in Figure 5.66).
 Press the <Enter> key.
 Begin typing a new tag ‘<’.

The following should now be seen (Figure 5.67):

Figure 5.67 – Adding an item template

 Select ItemTemplate from the list and press the <Enter> key.
 Close the ItemTemplate tag ‘>’.

Visual Web Developer will automatically provide a closing tag for the ItemTemplate.
Anything typed between the opening and the closing tags will be used for every item in the
data source.

© CTI Education Group


Unit 5 – ASP.NET Page 177

 Modify the code to look like the following:

<asp:Repeater ID="TestRepeater" runat="server"


DataSourceID="CollegeDatabaseDataSource">
<ItemTemplate>
Learner Name : <%# DataBinder.Eval(Container.DataItem, "Name") %>
<%# DataBinder.Eval(Container.DataItem, "Surname") %> <br />
</ItemTemplate>
</asp:Repeater>

A brief explanation of how the code works follows:

 All code in between the <ItemTemplate> and </ItemTemplate> tags is in


XHTML, unless it is enclosed in data-binding code rendering tags (‘<%# ‘ and ‘%>’).
 Code in between the data-binding code rendering tags is executed and displayed.
 For this kind of data-binding, the DataBinder class’ Eval method is used, which
searches through the data source for a matching field and displays it.
 The code outside of the code rendering tags is rendered in HTML. So in this case, the
result is: Student Name: {name} {surname} <br />
 In XHTML, <br /> indicates a line break.

 Save and run the project.

It should look like Figure 5.68:

Figure 5.68 - Repeater in action

While the above example is very basic, it does give an idea of what is possible with a
Repeater control. The XHTML code inside the Repeater control can be as complex (or
as simple) as necessary; it is perfectly possible, for example, to have a complex HTML
table which neatly formats the output.

Those without any HTML coding experience might want to try creating the layout in design
view, selecting it, copying it, and pasting it between the <ItemTemplate> and
</ItemTemplate> tags. All that then needs to be done is to add the data-binding
statements in the correct places. For an example, see Figure 5.69 (Please note that this
example only shows the first 3 items displayed by the Repeater).

The following is the code used to generate Figure 5.69:

© CTI Education Group


Unit 5 – ASP.NET Page 178

<asp:Repeater ID="TestRepeater" runat="server">


<ItemTemplate>
<table style="width: 250 px; background-color: #999999; border: 1pt solid
black;">
<tr>
<td class="style1">
Learner Name:
</td>
<td class="style2">
<%# DataBinder.Eval(Container.DataItem, "Name") %>
<%# DataBinder.Eval(Container.DataItem, "Surname") %>
</td>
</tr>
<tr>
<td class="style3">
Student Number:
</td>
<td class="style4">
<%# DataBinder.Eval(Container.DataItem, "StudentNumber") %>
</td>
</tr>
<tr>
<td class="style1">
Learner DoB:</td>
<td class="style2">
<%# DataBinder.Eval(Container.DataItem, "DateOfBirth") %>
</td>
</tr>
</table>
<br />
</ItemTemplate>
</asp:Repeater>

The Repeater control should appear as follows (Figure 5.69 only shows the first three
items):

Figure 5.69 – The Repeater control in action

© CTI Education Group


Unit 5 – ASP.NET Page 179

The various styles (e.g: style1, style2, style3) used in the above example were
created automatically by the Visual Web Developer Express IDE.

5.6.2.1.2 Binding data from a SQL database to a Repeater control


Adding data from a SQL database to a Repeater control is very similar to adding data
from an MS Access database.

 Return to the DatabaseTestSql website that was created previously.


 Add a Repeater control to the page and call it TestRepeater.
 Add the data source to the Repeater control in exactly the same way that it was
added to the GridView control.
 Make sure that the Repeater control is selected and go to the Source view.
 Add the exact same ItemTemplate to the code as in the previous example (section
5.6.2.1.1).
 Save and run the Web page.

The output should look like the image shown in Figure 5.70:

Figure 5.70 – Repeater control in action using SQL

5.6.2.1.3 Other templates


In the previous example, one template - an ItemTemplate - has been created. It is
possible to create more templates, as shown in Table 27:

Table 27 – Template types


Name Description
HeaderTemplate This template is used to define an item which is
displayed before any other content.

© CTI Education Group


Unit 5 – ASP.NET Page 180

AlternatingItemTemplate This template is used to define what every other row


should look like. This is used when it is necessary to
alternate, for example, the background colour for every
second item.
SeperatorTemplate This template is displayed between each item.
FooterTemplate This template is used to define what is displayed after all
the other elements have been rendered.

5.6.2.2 DataList control


The DataList control functions in much the same way as a Repeater control. In fact, it
can even be used to produce exactly the same output. However, the DataList control
provides additional functionality, such as the ability to change the tiling direction (i.e. the
items can be displayed next to each other, as opposed to underneath each other) as well
as allowing a variable number of columns to be displayed.

5.6.2.2.1 Binding data from an MS Access 2007 database to a DataList control


 Modify the previous Repeater example so that its opening and closing tags look as
follows:

<asp:DataList ID="TestDatabase" runat="server"


RepeatDirection=Horizontal RepeatColumns=3>
</asp:DataList>

The code between the starting and closing tags remains the same as shown below.
Notice that this is the same as binding data to a Repeater control.

<asp:DataList ID="TestList" runat="server"


RepeatDirection=Horizontal RepeatColumns=3 style="text-align: center">
<HeaderTemplate>
Learner List
</HeaderTemplate>
<FooterTemplate>
Copyright 2008 ADO College
</FooterTemplate>
<ItemTemplate>
<table style="width: 250 px; background-color: #999999; border: 1pt solid
black;">
<tr>
<td class="style1">
Learner Name:
</td>
<td class="style2">
<%# DataBinder.Eval(Container.DataItem, "Name") %>
<%# DataBinder.Eval(Container.DataItem, "Surname") %>
</td>
</tr>
<tr>
<td class="style3">
Student Number:
</td>
<td class="style4">
<%# DataBinder.Eval(Container.DataItem, "StudentNumber") %>
</td>

© CTI Education Group


Unit 5 – ASP.NET Page 181

</tr>
<tr>
<td class="style1">
Learner DoB:</td>
<td class="style2">
<%# DataBinder.Eval(Container.DataItem, "DateOfBirth") %>
</td>
</tr>
</table>
<br />
</ItemTemplate>
</asp:DataList>

 Add a data source in exactly the same way in which one was added to the GridView
and Repeater controls.
 Select the Auto Format… option and change the design to Professional.
 Save and run the Web page.

The output should look like the image shown in Figure 5.71:

Figure 5.71 – The DataList control in action using MS Access 2007

It should be noted that, with a DataList, it is possible to edit any and all templates in the
Design view. Figure 5.72 shows how the header and footer templates can be modified:

© CTI Education Group


Unit 5 – ASP.NET Page 182

Figure 5.72 - DataList templates

And the result (Figure 5.73):

Figure 5.73 - DataList with both a header and a footer

It is also possible to create data-bound fields within a template. This is done by adding
any control (for example, a Label) and using the attached Tasks Menu. The Edit
Databindings… option will display a dialog which can be used to select which field to
data-bind. When creating a DataList control, this is generally an easier method than
writing code.

NOTE Any data-binding which has been created using the Source view will not be
visible in the Design view. However, it will be there when the page is
rendered.

© CTI Education Group


Unit 5 – ASP.NET Page 183

 Try modifying the DataList control created in this section such that it uses Label
controls (created in the Design view) to display the information about each learner. It
will be necessary to remove any code displayed in between code-render tags to
achieve this effect.

5.6.2.2.2 Binding data from an MS SQL database to a DataList control


Adding data to a DataList control using a SQL database is similar to adding data to a
Repeater control using a SQL database.

 Return to the DatabaseTestSql website that was created previously.


 Add a DataList control to the page and call it TestList.
 Add a SQL database as a data source in exactly the same way in which it has been
done up to this point.
 Select the DataList control and go to the Source view.
 Add the following code to the DataList control code:

<asp:DataList ID="TestList" runat="server"


RepeatDirection=Horizontal RepeatColumns=3>
<ItemTemplate>
<table style="width: 250 px; background-color: #999999; border: 1pt solid
black;">
<tr>
<td class="style1">
Learner Name:
</td>
<td class="style2">
<%# DataBinder.Eval(Container.DataItem, "Name") %>
<%# DataBinder.Eval(Container.DataItem, "Surname") %>
</td>
</tr>
<tr>
<td class="style3">
Student Number:
</td>
<td class="style4">
<%# DataBinder.Eval(Container.DataItem, "StudentNumber") %>
</td>
</tr>
<tr>
<td class="style1">
Learner DoB:</td>
<td class="style2">
<%# DataBinder.Eval(Container.DataItem, "DateOfBirth") %>
</td>
</tr>
</table>
<br />
</ItemTemplate>
</asp:DataList>

 Change the design to Professional using the Auto Format… option.


 Save and run the Web page.

© CTI Education Group


Unit 5 – ASP.NET Page 184

The output should look like the image shown in Figure 5.74:

Figure 5.74 – The DataList control in action using SQL

It should be noted that with a DataList control, it is possible to edit any and all templates
in the Design view. Figure 5.75 shows how the header and footer templates can be
modified:

Figure 5.75 – DataList templates

© CTI Education Group


Unit 5 – ASP.NET Page 185

The result is shown in Figure 5.76:

Figure 5.76 – DataList with both a header and footer

It is also possible to create data-bound fields within a template. This is done by adding
any control (for example, a Label) and using the attached DataList Tasks menu. The
Edit Databindings… option will display a dialog which can be used to select which field to
data-bind. When creating a DataList control, this is generally an easier method than
writing code.

NOTE Any data-binding which has been created using the Source view will not be
visible in the Design view. However, it will be there when the page is
rendered.

 Try modifying the DataList controls created in this section such that it uses Label
controls (created in the Design view) to display the information about each learner. It
will be necessary to remove any code displayed in between code-render tags to
achieve this effect.

5.6.2.3 ListView control


The ListView control has much in common with the DataList and Repeater controls.
However, it also provides functionality which allows users to edit, insert and delete data,
as well as sort and page through that data. This functionality does not require the
programmer to write any additional code.

© CTI Education Group


Unit 5 – ASP.NET Page 186

5.6.2.3.1 Binding data from an MS Access 2007 database to a ListView control


 Return to the DatabaseTestAccess2007 example.
 Add a new ListView control to the page.
 Create a data source as shown in section 5.6.1.2.

For the previous examples in this section, a read-only data source has been used.
However, as it is now necessary to show the full functionality of the ListView control, a
new data source will need to be created.

 Create a new data source, following the same steps as in 5.6.1.2 (using the
ListView, rather than a GridView).

When you reach the Configure Data Source window (shown in Figure 5.77), the settings
will change to accommodate inserting, updating, and deleting.

Figure 5.77 – Specifying the SQL query statement

 Select the Specify a custom SQL statement or stored procedure option.


 Click Next >.

© CTI Education Group


Unit 5 – ASP.NET Page 187

The window shown in Figure 5.78 will appear:

Figure 5.78 – Adding SQL query statements

A custom SELECT, UPDATE, INSERT, and DELETE statement has to be inserted next.

 Enter the following statement into the SELECT text box:

SELECT * FROM Learner

 Click on the Query Builder… button.

This option allows the query statement to be tested to see whether or not it is correct
before continuing.

 Enter the following statement into the UPDATE text box:

UPDATE Learner
SET Name = ?, Surname = ?, DateOfBirth = ? WHERE (StudentNumber = ?)

 Enter the following statement into the INSERT text box:

INSERT INTO Learner(Name, Surname, DateOfBirth, StudentNumber)


VALUES (?, ?, ?, ?)

 Enter the following statement into the DELETE text box:

DELETE FROM Learner WHERE (Name = ?) AND (Surname = ?)

 Click Next >.

© CTI Education Group


Unit 5 – ASP.NET Page 188

The window shown in Figure 5.79 will appear:

Figure 5.79 – Testing the query

 Click Test Query to see whether or not the correct values are being selected from the
database and table.
 Click Finish.
 Click on the > next to the ListView control.
 Select the Configure ListView… option.

© CTI Education Group


Unit 5 – ASP.NET Page 189

The window shown in Figure 5.80 will appear:

Figure 5.80 – Configuring the ListView control

 Select Professional in the Select a Style section.


 Check the Enable Editing, Enable Inserting, and Enable Deleting check boxes.
 Click OK.

Additional parameters must now be set in order for the DELETE statement to work.

 With the ListView control selected, edit the DataKeyNames property in the
Properties window (Figure 5.81).

Figure 5.81 – DataKeyNames property

© CTI Education Group


Unit 5 – ASP.NET Page 190

 Click on the … button.


 Add the StudentNumber parameter the Selected data fields list (Figure 5.82).

Figure 5.82 – Data Fields Collection Editor

 Click OK.

Next, two Data Source settings must be changed.

 Click on the SqlDataSource below the ListView control.


 In the Properties window, select the DeleteQuery property’s … button (Figure 5.83).

Figure 5.83 – DeleteQuery property

© CTI Education Group


Unit 5 – ASP.NET Page 191

The window shown in Figure 5.84 should appear:

Figure 5.84 – Command and Parameter Editor

 Ensure that the DELTE statement is exactly as shown in Figure 5.79 above.
 Add the Parameters to the list. These parameters must be exactly the same as the
parameters in the DELETE command box.
 Click OK.

Over and above changing the DeleteQuery property of the Data Source, the
UpdateQuery property also has to be changed.

 In the Properties window, select the UpdateQuery property (Figure 5.85).

Figure 5.85 – UpdateQuery property

© CTI Education Group


Unit 5 – ASP.NET Page 192

The window shown in Figure 5.84 (previously shown) should appear.

 Add all the parameters which are present in the query statement, i.e. Name,
Surname, DateOfBirth, and StudentNumber.

When dealing with both deleting and updating, it is vitally important that the correct
parameters are added to the DataKeyNames property of the ListView control. They
must be the parameters that are in the WHERE clause of both the DELETE and UPDATE
query.

If the WHERE clause of the UPDATE statement had to change from StudentNumber to
Name and Surname, an error would occur because the DELETE statement will use the
Name and Surname, but it does not exclusively specify these parameters in the DELETE
query.

 Press <Ctrl> + <F5> to save and run the website.

 Use the Delete, Edit, and Insert options to see how they work.

In the example, a new record, “Brian Scott”, has been added; the existing record, “Arnold
Ernest”, has been changed to “Arnold Paul Ernest”; and the existing record, “Raymond
Nesingwary”, has been deleted. The ListView control will be displayed as shown in
Figure 5.86:

Figure 5.86 – ListView control in action

5.6.2.3.2 Binding data from an MS SQL database to a ListView control


 Return to the DatabaseTestSql example.
 Add a new ListView control to the page.
 Create a data source as shown in section 5.6.1.3.

Once again, when you reach the Configure Data Source window (shown in Figure 5.78),
the settings have to change to accommodate inserting, updating, and deleting. These
settings will be exactly the same as in the previous section (5.6.2.2.1).

© CTI Education Group


Unit 5 – ASP.NET Page 193

 Enter the following statement into the SELECT text box:

SELECT * FROM Learner

 Click on the Query Builder… button.

This option allows the query statement to be tested to see whether or not it is correct
before continuing.

 Enter the following statement into the UPDATE text box:

UPDATE Learner
SET Name = @Name, Surname = @Surname, DateOfBirth = @DateOfBirth WHERE
(StudentNumber = @StudentNumber)

 Enter the following statement into the INSERT text box:

INSERT INTO Learner(Name, Surname, DateOfBirth, StudentNumber)


VALUES (@Name, @Surname, @DateOfBirth, @StudentNumber)

 Enter the following statement into the DELETE text box:

DELETE FROM Learner WHERE (StudentNumber = @StudentNumber)

 Click Next >.

The remaining steps after entering the query commands are exactly the same as they are
with the MS Access 2007 database. When you are finished creating the data source,
proceed as follows:

 Change the DataKeyNames property of the ListView control as done in the


previous example.

There is no need to change the DeleteQuery and UpdateQuery properties of the data
source because the SQL database adds this automatically.

 Change the design of the ListView control to Professional using the Configure
ListView option.
 Save and run the Web page.

The same records, as in the previous example, have been inserted, edited, and deleted.

© CTI Education Group


Unit 5 – ASP.NET Page 194

The output is shown in Figure 5.87:

Figure 5.87 – The ListView control in action using SQL

5.6.2.4 DetailsView control


The DetailsView control has much in common with the ListView control. The main
difference between the two is that a DetailsView control always works with one record
at a time, as opposed to displaying multiple records simultaneously.

5.6.2.4.1 Binding data from an MS Access 2007 database to a DetailsView control


 Return to the DatabaseTestAccess2007 example.
 Add a new DetailsView control to the page.
 Follow the same procedure used in the ListView control to add an MS Access 2007
database to the DetailsView as a data source. Remember to include the INSERT,
UPDATE, and DELETE query statements.
 Change the DataKeyNames property of the DetailsView control (as it was done
with the ListView control).
 Change the DeleteQuery and UpdateQuery properties of the Data Source.
 Click the checkboxes next to Enable Paging, Enable Inserting, Enable Editing, and
Enable Deleting (Figure 5.88).
 Use AutoFormat to set the style to Professional (Figure 5.80).
 Save and run the project.

© CTI Education Group


Unit 5 – ASP.NET Page 195

Figure 5.88 – DetailsView control options

The result should look as follows (Figure 5.89):

Figure 5.89 – A DetailsView control in action

5.6.2.5.2 Binding data from an MS SQL database to a DetailsView control


 Return to the DatabaseTestSql example.
 Add a new DetailsView control to the page.
 Create a data source as shown in section 5.6.1.3. Remember to add the INSERT,
UPDATE, and DELETE query statements.
 Change the DataKeyNames property of the DetailsView control.
 Click the checkboxes next to Enable Paging, Enable Inserting, Enable Editing, and
Enable Deleting.
 Use Auto Format… to set the style of the DetailsView control.
 Save and run the project.

© CTI Education Group


Unit 5 – ASP.NET Page 196

The result should look as follows (Figure 5.90):

Figure 5.90 – A DetailsView control in action using SQL

5.6.2.5 FormView control


The FormView control is identical in functionality to the DetailsView control, with one
difference: instead of providing a pre-defined layout, the FormView control is intended to
work with user-defined templates (in much the same way as Repeater and DataList
controls).

 Follow exactly the same steps that were used to add data to a DetailsView control
in the previous section. Remember to add the SELECT, INSERT, UPDATE, and
DELETE query commands.
 Change the DataKeyName property of the FormView control.
 Change the DeleteQuery and UpdateQuery properties of the data source.

The FormView control will automatically create a basic template based on the data source
set. The default template, using the Professional style, is shown in Figure 5.91:

Figure 5.91 – A FormView control in action

The templates used by a FormView control can be created visually (like a DataList
control) or by writing source code (like a Repeater control). The FormView control will
work identically whether or not an Access or SQL database is used. If you want to create
a FormView control using SQL, it will be done in exactly the same way as adding data to a
DetailsView control.

© CTI Education Group


Unit 5 – ASP.NET Page 197

5.6.3 Accessing a database without using data-binding


Data-binding is a convenient, easy-to-use method of database access. However, it is
sometimes necessary to access data which may not necessarily be displayed to the user.
For example, it might be necessary to check a username and password against entries in
a database, but naturally it would not be appropriate to display this information in a table.

In this kind of situation, it is necessary to manually connect to the database, execute a


query or command, and read the result (if there is one). The procedure for this is much
the same as that covered in Unit 4.

The following example shows how data can be retrieved from an MS Access 2007
database:

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
// Import the System.Data.OleDb namespace.
using System.Data.OleDb;

public partial class _Default : System.Web.UI.Page


{
// Declare a database connection.
OleDbConnection conn;

protected void Page_Load(object sender, EventArgs e)


{
ConnectToDatabase();

// Use the ExecuteQuery method we have defined.


OleDbDataReader result = ExecuteQuery("SELECT * FROM Learner");

// If there is a result.
if (result != null)
{
// Read the next item.
while (result.Read())
{
// Add the current record’s name column.
TestListBox.Items.Add(result["Name"].ToString());
}
}

DisconnectDatabase();
}

// Method which creates a database connection and opens it.


private void ConnectToDatabase()
{
conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;

© CTI Education Group


Unit 5 – ASP.NET Page 198

Data Source=" +
Request.PhysicalApplicationPath +
"App_Data\\CollegeDatabase.accdb");

conn.Open();
}

// Method which disconnects from the database.


private void DisconnectDatabase()
{
conn.Close();
}

// Method which is used to execute a query which has no result.


// i.e. INSERT, DELETE, UPDATE.
private bool ExecuteCommand(String query)
{
try
{
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = query;
cmd.ExecuteNonQuery();
// Returning true indicates success.
return true;
}
catch (OleDbException odbe)
{
// Returning false indicates failure.
return false;
}
}

// Method which executes a query and returns the result (if any).
private OleDbDataReader ExecuteQuery(String query)
{
try
{
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = query;
return cmd.ExecuteReader();
}
catch (OleDbException odbe)
{
return null;
}
}
}

The above example selects the entire Learner table from the database, and displays all
the values in the Name column in a ListBox control called TestListBox. Convenience
methods have been created which connect to the database, disconnect from it, and
execute both queries and commands.

The PhysicalApplicationPath (from the Request object) has been used to ensure
that the database will always work regardless of the location of the website as a whole.
The Request object stores information about a client request. This object will be covered
in more detail in section 5.7.2.3.

© CTI Education Group


Unit 5 – ASP.NET Page 199

An OleDbDataReader always points to one row at a time, accessible through the index
operator. The Read() method moves the data reader to the next row and returns true if
there are any more records to read, and returns false if no more records are found.

In some situations (unlike the above example), it might be necessary to find a specific
record rather than a list. In this case, a while loop would not be necessary. All that
would need to be done is to check that a result was returned, and then the value can be
assigned or worked with as necessary.

The following example shows how data can be retrieved from an MS SQL database:

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
// Import the System.Data.OleDb namespace.
using System.Data.SqlClient;

public partial class _Default : System.Web.UI.Page


{
// Declare a database connection.
SqlConnection sqlConn;

protected void Page_Load(object sender, EventArgs e)


{
ConnectToDatabase();

// Use the ExecuteQuery method we have defined.


SqlDataReader result = ExecuteQuery("SELECT * FROM Learner");

// If there is a result.
if (result != null)
{
// Read the next item.
while (result.Read())
{
// Add the current record’s name column.
TestListBox.Items.Add(result["Name"].ToString());
}
}

DisconnectDatabase();
}

// Method which creates a database connection and opens it.


private void ConnectToDatabase()
{
sqlConn = new SqlConnection("Integrated Security=SSPI; " +
"Initial Catalog=CollegeDatabase; " +
"Data Source=localhost");

sqlConn.Open();

© CTI Education Group


Unit 5 – ASP.NET Page 200

// Method which disconnects from the database.


private void DisconnectDatabase()
{
sqlConn.Close();
}

// Method which is used to execute a query which has no result.


// i.e. INSERT, DELETE, UPDATE.
private bool ExecuteCommand(String query)
{
try
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = query;
cmd.ExecuteNonQuery();
// Returning true indicates success.
return true;
}
catch (SqlException ex)
{
// Returning false indicates failure.
return false;
}
}

// Method which executes a query and returns the result (if any).
private SqlDataReader ExecuteQuery(String query)
{
try
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = query;
return cmd.ExecuteReader();
}
catch (SqlException ex)
{
return null;
}
}
}

5.6.4 Exercises
1. List two differences between the DataList control and the
Repeater control.
2. In which folder does ASP.NET look for data sources by default?
3. Give a reason why a manual connection to a database would be
used rather than using data-binding?

© CTI Education Group


Unit 5 – ASP.NET Page 201

5.6.5 Revision questions


1. True/False: The difference between a FormView and a
DetailsView control is that the FormView control is intended to
work with templates.
2. True/False: Data-binding which is created in the Source view will
also be visible in the Design view.
3. True/False: The <% %> tags are specifically used for data-binding.

© CTI Education Group


Unit 5 – ASP.NET Page 202

© CTI Education Group


Unit 5 – ASP.NET Page 203

5.7 ASP.NET Objects

At the end of this subsection you should be able to:

 Use multiple pages in an ASP.NET website


 Use the Application, Response, Request, Session and
Server objects.
 Use cookies and session variables.

5.7.1 Multiple pages


All the examples in this unit thus far have been contained in a single page. However,
almost all actual Web pages (regardless of the language used to create them) use multiple
page designs. While it is entirely possible to fit a functional website onto a single page
(showing and hiding panels as necessary), it is not generally desirable to do so, as it is
easier (and better) to have specialized pages, each with their own code.

5.7.1.1 Adding new pages to a website


Adding a new page to an ASP.NET website is easy.

 Open the Website menu.


 Click Add New Item…
 Select Web Form from the list.
 Enter a name for the new page. This example will use the name Page2.aspx.

The new page will now be visible in the Solution Explorer. To open it for editing, double-
click on it.

 Add a Label control to each of the two pages.


 Set the Text property of the Label controls to “This is page 1” and “This is page 2”
respectively.

5.7.1.2 Creating navigation via hyperlinks


Pages in a website are only useful to the user if they are accessible. As such, the user
must be provided with a way to reach these pages. This functionality is most commonly
provided by hyperlinks, which in ASP.NET are represented by the HyperLink control.

 Add a HyperLink control to the first page (Default.aspx).


 Set the Text property of the HyperLink control to “Page 2”.
 Click the … button to the right of the NavigateUrl property.

© CTI Education Group


Unit 5 – ASP.NET Page 204

The following dialog will now be visible (Figure 5.92):

Figure 5.92 – The Select URL dialog

This dialog is used to select to which URL a hyperlink points.

 Browse to the location of Page2.aspx and select it.


 Click OK.
 Save and run the project.

When clicked, the HyperLink control should redirect the user’s Web browser to
Page2.aspx.

NOTE The Select URL dialog generates a relative path to the file (i.e. how to get to
the file from the location of the current page). This is convenient because if
the website is moved from one location to another, the links will still function
(which would not be the case if the links pointed to an absolute location).
Should the HyperLink control need to point to a location outside the current
website, then an absolute path should be specified (for example,
http://www.cti.co.za/).

As with Label controls, HyperLink controls can have their appearance changed via their
properties.

5.7.1.3 User control Templates


When using multiple pages in an ASP.NET website, it is important to maintain consistency.
This means that every page should use the same layout and the same menu system.
However, this can lead to a problem. For example, take a website with a complicated
menu system which has been copied into every page. The developer has made an error,
and one of the hyperlinks does not work correctly. To correct this error, the developer
must now go through each page individually and fix it. Fortunately, there are several ways
around this, each of which has their own benefits and limitations.

© CTI Education Group


Unit 5 – ASP.NET Page 205

For this course, one such method will be explored, namely user control templates. This
involves creating a user (custom) Web control which contains the item required on every
page. In this case, a Header control will be created.

 Start a new project.


 Open the Website menu.
 Click Add New Item…
 Select Web User Control from the list.
 Enter a name for the control. This example will use the name Header.ascx.
 In the Header.ascx file, create a header for the Web pages. The procedure for this is
identical to that used to create any other page.

The following (Figure 5.93) is a sample of how the header control could look:

Figure 5.93 – An example of a header control

In this example, each of the buttons is in fact a Hyperlink control with style parameters
set to the following (i.e. a HyperLink style has been created):

.HyperLink
{
border: 1pt solid black;
background-color: #999999;
padding: 5px;
width: 100px;
text-align: center;
letter-spacing: 3px;
}

It is not necessary to provide functionality for the HyperLink controls in this example.
However, in an actual Web application, this will of course be necessary.

To add the user control to a page, simply drag the file from the Solution Explorer onto the
page. As this control is intended to be a header for every page in the website, it would
need to be added to each and every page. However, any modifications made to the
control, and which can only be made in the control file itself, will be reflected in all the
documents. This can save a lot of time and ensures that pages are consistent with one
another.

© CTI Education Group


Unit 5 – ASP.NET Page 206

5.7.2 ASP.NET objects


ASP.NET has several objects which are useful when creating dynamic content. These
objects are:

 The Application object


 The Response object
 The Request object
 The Server object
 The Session object

These objects can all be accessed in any ASP.NET page.

5.7.2.1 Application object


The Application object is primarily used to store data which can then be used
throughout the entire Web application. This data is stored in the form of a user-defined
variable which can be accessed by any page in the application. In addition, this data is
shared between all users, so if more than one person browses the website, the value is
the same for each one of them. The following code shows how an Application variable
can be created, modified, and removed:

// Add a new application variable.


Application.Add("CopyrightText", "Copyright © by CTI Education Group, " +
"Februrary 2009.");

// Add a new application variable _OR_ modify an existing one.


Application["CopyrightText"] = "Copyright © by CTI Education Group, " +
"February 2009.";

// Access an application variable.


CopyrightLabel.Text = Application["CopyrightText"].ToString();

// Remove an application variable.


Application.Remove("CopyrightText");

5.7.2.2 Response object


The Response object is used to control what is sent back to the client from the server.
The page which will be sent to the client is buffered (stored) in this object before it is sent
to the client. This buffer is not read-only and can still be modified before it is sent to the
client. The Response object has several useful methods as shown in Table 28:

Table 28 – Response object methods


Name Description
Redirect Redirects the user’s Web browser to the specified Web page.
SetCookie Used to set up a cookie on the user’s computer which can be
referenced at a later stage. Cookies are covered in more depth in
Section 5.7.3.

© CTI Education Group


Unit 5 – ASP.NET Page 207

WriteFile Writes the contents of a specified file to the current Web page.
This file can contain any text, including HTML data.
Write Writes the specified String to the current Web page. This String can
contain any text, including HTML data.

5.7.2.3 Request object


The Request object is used to store details about the client’s request, i.e. the information
which is sent to the server when a page is requested. These details are stored in
properties which are shown in Table 29:

Table 29 – Request object properties


Name Description
ApplicationPath Retrieves the applications path on the server.
E.g., on the page:
http://localhost:49273/ASPObjects/Default.aspx
this would return /ASPObjects
Browser Returns information about the browser capabilities of the
client. To obtain the name of the client’s browser,
retrieve the Browser (i.e.
Request.Browser.Browser)
Cookies Gets a collection of cookies sent by the client. Cookies
are covered in more depth in Section 5.7.3.
PhysicalApplicationPath Retrieves the physical location of the website on the
local computer.
QueryString Retrieves the query string for the current page. (e.g.
on the page
http://localhost:49273/ASPObjects/Default.aspx?variable
1=value1&variable2=value2, will return
variable1=value1&variable2=value2).
An individual part of the string may be accessed by
specifying the name as follows:
Request.QueryString["variable1"].
This returns value1.
Url Retrieves the entire address for the current page,
including the query string.
UserHostAddress This returns the IP address of the remote client.
UserHostName This returns the DNS address of the remote client.
UserLanguages This returns an array which stores the client language
preferences.

5.7.2.4 Server object


The Server object has several useful methods (shown in Table 30), and is primarily used
for error-handling and URL encoding:

© CTI Education Group


Unit 5 – ASP.NET Page 208

Table 30 – Server object properties


Name Description
UrlEncode Converts a string into a format which can be used in a browser
by replacing all illegal characters (spaces and other special
characters) with ones which are acceptable in a URL.
UrlDecode Converts a string which has been encoded with UrlEncode()
back into its original format.
GetLastException Returns the last Exception which occurred on this server.

Additionally, the Server class provides the MapPath() method which can be used to
convert a relative path into an absolute path at runtime. This is particularly useful for Web
services, which do not have access to the Request object, and thus cannot use the
PhysicalApplicationPath property.

5.7.2.5 Session object


The Session object functions in much the same way as the Application object.
However, the Session object is (a) temporary, and (b) specific to each user. This means
that data stored in a Session object is only accessible in pages generated for that
specific user. Any other user will have a Session object of their own with different values.
The data in a Session object is lost when the user disconnects, i.e. their session ends.

5.7.3 Session variables and cookies

5.7.3.1 Using cookies to store information between sessions


Cookies are used to store data on a client’s computer both during and between sessions.
They are commonly used to store login information so that the user does not have to re-
enter their details every time they visit a website.

An example of a login page will now be created. This page will use cookies to determine if
a user is logged in or not.

 Create a new project.


 In Default.aspx, create the layout of a login system. It should look something like the
image displayed in Figure 5.94:

© CTI Education Group


Unit 5 – ASP.NET Page 209

Figure 5.94 – The Login page

 Place a Label to the left of the Login Button with no text. This Label will be used to
display any error messages.
 Now create a second page, called Home.aspx. It should look like the image in Figure
5.95:

Figure 5.95 – The Home page

No additional content will be added for this home page as it is simply being used it to test
the login system. Now write the functionality for this system.

The database which will be used for this example is called UserDatabase.mdb, and it
contains the User table as shown in Figure 5.96:

Figure 5.96 – The User table

© CTI Education Group


Unit 5 – ASP.NET Page 210

 Create the above database and table, and then import it into the project in the
App_Data directory.

Because this example will potentially be accessing the database from multiple pages, a
class will be created to handle interactions with the database. This will help to cut down
on repetitive code.

 Add a new class to the website called UseDatabase.


 Enter the following code for this class:

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.OleDb;

public class UseDatabase


{
OleDbConnection conn;
string databasePath = "";

public UseDatabase(string databasePath)


{
this.databasePath = databasePath;
}

// Method which creates a database connection and opens it.


public void ConnectToDatabase()
{
conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=" + databasePath);

conn.Open();
}

// Method which disconnects from the database.


public void DisconnectDatabase()
{
conn.Close();
}
// Method used to execute query which has no result: INSERT, DELETE, UPDATE.
public bool ExecuteCommand(String query)
{
try
{
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = query;
cmd.ExecuteReader();
// Returning true indicates success.
return true;
}
catch (OleDbException odbe)
{

© CTI Education Group


Unit 5 – ASP.NET Page 211

// Returning false indicates failure.


return false;
}
}

// Method which executes a query and returns the result (if any).
public OleDbDataReader ExecuteQuery(String query)
{
try
{
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = query;
return cmd.ExecuteReader();
}
catch (OleDbException odbe)
{
return null;
}
}
}

 Add an event-handler to the Login button (loginButton) in Default.aspx.


 Enter the following code for the event-handler:

protected void loginButton_Click(object sender, EventArgs e)


{
// Create a new instance of the UseDatabase class.
UseDatabase useDb = new UseDatabase(Request.PhysicalApplicationPath +
"App_Data\\UserDatabase.accdb");

// Construct a query string using the values from the text boxes.
string queryString = "SELECT * FROM [User] WHERE EmailAddress = '";
queryString += emailAddressTextBox.Text + "' AND Password = '";
queryString += passwordTextBox.Text + "';";

// Connect.
useDb.ConnectToDatabase();

// Check for matches.


OleDbDataReader dbReader = useDb.ExecuteQuery(queryString);

// If there are rows in the result, then the check was successful.
if (dbReader != null && dbReader.HasRows)
{
// Set up the cookies.
HttpCookie loggedInCookie = new HttpCookie("LoggedIn", "true");
Response.Cookies.Add(loggedInCookie);

// Redirect the user to the next page.


Response.Redirect("Home.aspx");
}
else
{
// Display the error message.
ErrorLabel.Text = "Incorrect user name or password!";
}

// Disconnect.
useDb.DisconnectDatabase();
}

© CTI Education Group


Unit 5 – ASP.NET Page 212

 Now save and run the project.

If an incorrect email address or password is entered, the error message will be displayed
in the error label (ErrorLabel). However, if the user enters a valid email address and
password, then the cookies will be set and the user will be redirected to the next page.

Now that the facility to log in exists, it is necessary to create code which checks whether or
not the user is logged in and responds appropriately. A user that opens the Login page
while logged in, should be redirected to the Home page. Conversely, an attempt to access
the Home page while not logged in, should redirect the user to the Login page. Note that it
is always important to ensure that a cookie has a value before attempting to read it, in
order to prevent exceptions being thrown.

 Enter the following code into the Page_Load event-handler for the Login page:

protected void Page_Load(object sender, EventArgs e)


{
if (Request.Cookies["LoggedIn"] != null
&& Request.Cookies["LoggedIn"].Value == "true")
{
Response.Redirect("Home.aspx");
}
}

 Enter the following code into the Page_Load event-handler for the Home page:

protected void Page_Load(object sender, EventArgs e)


{
if (Request.Cookies["LoggedIn"] == null ||
(Request.Cookies["LoggedIn"] != null &&
Request.Cookies["LoggedIn"].Value != "true"))
{
Response.Redirect("Default.aspx");
}
}

All that remains is to create the functionality for the Log out button.

 Add the following event-handler to the logoutButton control:

protected void logoutButton_Click(object sender, EventArgs e)


{
if (Response.Cookies["LoggedIn"] != null)
{
HttpCookie loggedInCookie = new HttpCookie("LoggedIn", "false");
Response.SetCookie(loggedInCookie);

Response.Redirect("Default.aspx");
}
}

 Save and run the project.


 Enter one of the email addresses and passwords from the User table (Figure 5.94).
 Now change the address bar so that it points to Default.aspx instead of Home.aspx
(but leaving the rest of the address intact) and press the <Enter> key.

© CTI Education Group


Unit 5 – ASP.NET Page 213

The login screen should be shown again, which is not what was intended. This is because
Web browsers such as Internet Explorer cache Web pages (i.e. store them so that they do
not need to be downloaded from the Internet again). However, the browser can be forced
to refresh the page.

 Press the <F5> key to refresh the page.

The browser should be redirected to the Home.aspx page because, according to the
cookies stored on the computer, the user is still logged in.

 Click on the Log out button.

The browser will be redirected to the Default.aspx page.

 Now change the address bar so that it points to Home.aspx instead of Default.aspx
(but leaving the rest of the address intact) and press the <Enter> key.
 Refresh the page by pressing the <F5> key.

The browser will be redirected to the Default.aspx page because, according to the
cookies stored on the computer, the user is not logged in.

5.7.3.1.1 Cookie Expiration dates


If the Web browser is closed and the project is run again, the user will no longer be logged
in. This is because, by default, cookies are Session cookies. This means that they only
store data until the Web browser is closed. The way in which this can be avoided is to set
an Expiration date for each of the cookies as they are created.

 Add the following line of code to the event-handler for the loginButton, just before
the cookie is added to the Response.Cookies collection:

loggedInCookie.Expires = System.DateTime.Now.AddDays(7);

The above code gives the cookie an expiry date of exactly one week from the time at
which it was created.

 Save and run the project.


 Log in to the website, and then close the browser.
 Now run the project again.

The browser will be automatically redirected to the Home.aspx, because the user is still
logged in.

5.7.3.2 Using Session variables to store information between pages


There is often data which must be stored between pages. Sometimes this data has come
from a database, and it could technically be retrieved from the database every time it is
needed. However, this is usually not an efficient solution.

© CTI Education Group


Unit 5 – ASP.NET Page 214

One way in which this data can be stored is by using Session cookies, as shown in
section 5.7.3.1. However, cookies can only store string values. Session variables, on
the other hand, can store values of any type in the .NET Framework.

Session variables are stored in the Session object, as discussed in section 5.7.2.5.

Figure 5.97 is an example which shows how basic Session variables can be used for
Default.aspx:

Figure 5.97 – Default.aspx

The HyperLink control on Default.aspx (Figure 5.97) has its NavigateUrl property
set to Page2.aspx.

Default.aspx.cs:

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;

public partial class _Default : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)
{
Session["aString"] = "A string value";

ArrayList stringArrayList = new ArrayList();


stringArrayList.Add("An");
stringArrayList.Add("ArrayList");
stringArrayList.Add("stored");
stringArrayList.Add("in");
stringArrayList.Add("a");
stringArrayList.Add("session");
stringArrayList.Add("variable");

Session["anArrayList"] = stringArrayList;
}
}

Page2.aspx.cs:

using System;
using System.Collections;
using System.Configuration;
using System.Data;

© CTI Education Group


Unit 5 – ASP.NET Page 215

using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class Page2 : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)
{
TestLabel.Text = (string)Session["aString"];

TestListBox.DataSource = Session["anArrayList"];
TestListBox.DataBind();
}
}

After the HyperLink on Default.aspx has been clicked, Page2.aspx should look like the
image in Figure 5.98:

Figure 5.98 – Page2.aspx

5.7.4 Exercises
1. What syntax is used to create or modify a Session variable?
2. When will cookies be removed from the client system?
3. For what is the Application object primarily used?

5.7.5 Revision questions


1. True/False: Cookies can be used to store Session data in
string format.
2. True/False: The Request object is used to store the current page
before it is sent back to the client.
3. True/False: The only way to navigate through an ASP.NET website
is via a HyperLink control.

© CTI Education Group


Unit 5 – ASP.NET Page 216

© CTI Education Group


Unit 5 – ASP.NET Page 217

5.8 Distributing ASP.NET applications

At the end of this subsection you should be able to:

 Use the Copy Website functionality of Visual Web Developer


Express 2008 to deploy a website.

5.8.1 Copying an ASP.NET website from one location to another


The ultimate aim of any ASP.NET website is to be deployed onto a Web server which will
then be accessible either online or through a local network, depending on the purpose of
the application. In order to achieve this, the website needs to be copied from the location
in which it was developed to the location from which it will run. There are several ways in
which this can be achieved:

1. Placing the files on a disk or other storage medium and physically taking them to the
Web server.
2. Copying the files to the Web server via HTTP (using a server management tool).
3. Copying the files to the Web server via FTP (File Transfer Protocol).

The first option is very rare; since Web servers are almost always situated external to the
premises (and often the company) using them.

The second option is more common. Many hosting providers offer tools (and these are
sometimes built using ASP.NET) which can be used to manage a Web server, up to and
including, uploading files through HTTP. Microsoft Internet Information Services (IIS) can
also transfer files through HTTP.

The third option is the most common. The files are transferred after a connection is made
to the Web server via FTP using either:

(a) Specialised software or


(b) Windows Explorer)

Visual Web Developer provides several built-in methods of copying a website from one
location to another. Select the Website  Copy Website… option from the menu.
Selecting this menu option opens a new window, as shown in Figure 5.99:

© CTI Education Group


Unit 5 – ASP.NET Page 218

Figure 5.99 – Copy Website

In this window, the files and directories of the website are listed on the left-hand side.
When connected to the desired location, the files and folders of that location will be
displayed in the right. The buttons in the middle of the panel allow files to be moved
across, either individually, or all at once.

To connect to a remote location:

 Click the Connect button at the top of the window.

© CTI Education Group


Unit 5 – ASP.NET Page 219

The Open Web Site dialog will be displayed (Figure 5.100):

Figure 5.100 – Open Web Site

There are four options listed on the left of this dialog:

 File System
o This option allows a location on the current computer to be specified.
 Local IIS
o This option allows a locally-hosted IIS server to be specified. This requires
Microsoft Internet Information Services to be installed on the local computer.
 FTP Site
o This option allows a remote FTP site to be specified.
 Remote Site
o This option allows a remote IIS server to be specified.

 Ensure that File System is selected.


 Browse to the desired new location on the computer. The folder icon in the top-right
hand side of the dialog can be used to create new folders.
 Click Open.

This will close the dialog.

 Select all the files in the left-hand side of the window.


 Click the right-arrow button in the middle of the window.

All of the files in the source website have now been copied to the destination site.

© CTI Education Group


Unit 5 – ASP.NET Page 220

5.8.2 Exercises
1. List two ways in which a website can be deployed.
2. IIS stands for what?
3. FTP stands for what?
4. Using all the knowledge covered in this unit, create a database
which stores information about learners in a tertiary college. This
database must store the learners’ names, surnames, date of birth,
and current course. A website must be created which will display
these names in a layout that is both professional and easy to read.
This information must only be accessible to users once they have
logged in via a login screen. User information (i.e. usernames and
passwords) must also be stored in the database.

5.8.3 Revision questions


1. True/False: Windows Explorer can be used to transfer files via
FTP.
2. True/False: Many hosting providers offer tools which can be used to
upload files through HTTP.
3. True/False: Copying files to a Web server via a physical medium
(such as a USB flash drive or CD-ROM) is common practice.

© CTI Education Group


Unit 5 – ASP.NET Page 221

Unit 5 Test your knowledge (Self-test)

The questions in this section are similar to those asked in the exam. Try these questions
and then check the answers with the instructor. The questions are taken from the study
guide and textbook and will be made up of theory and application questions in multiple
choice, multiple response, true/false, and selection formats. Allow about 25 minutes for all
the questions. Good luck!

Questions

Multiple choice

1. Which one of the following data-bound controls cannot have its templates created
visually?
a. DataList
b. Repeater
c. FormView
d. GridView

2. Which one of the following controls is rarely used on its own?


a. RadioButton
b. RadioButtonList
c. CheckBox
d. CheckBoxList

3. Which one of the following properties of a Calendar control can be used to set which
date is shown on the control when the page is loaded?
a. SelectedDate
b. SelectedDates
c. VisibleDate
d. SelectionMode

4. Which keyboard shortcut is used to stop a Visual Web Developer Express server from
running?
a. <F5>
b. <Shift> + <F5>
c. <Alt> + <F5>
d. <Ctrl> + <F5>

© CTI Education Group


Unit 5 – ASP.NET Page 222

5. Which of the following properties is common to all controls, and should always have its
value changed from the default?
a. ID
b. Text
c. DataSource
d. Style

True/False

1. True/False: The Request.QueryString property will return 5 when the following


address is used: http://localhost:5836/Login.aspx?mode=5

2. True/False: Validation controls will throw an exception if their ControlToValidate


property is not set.

Multiple response

1. Which three of the following are methods of the Response object:


a. WriteFile()
b. Transfer
c. SetCookie
d. Redirect
e. UrlEncode

2. Which three of the following are valid options for the TextMode property of a
TextBox control?
a. Single
b. Multiple
c. SingleLine
d. Password
e. MultiLine
f. PasswordLine

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 223

Unit 6 - .NET Distributed Computing

This unit covers topics such as XML data manipulation, .NET Remoting, XML Web
Services, and Windows Services.

Unit 6 counts 80% towards part B (units 4, 5, and 6) of your C# mark, and there are 14
days to complete it. The time and marks are scheduled as follows:

Reading and Project 10 days


Exam preparation and exam 2 days 45%
Practical exam 2 days 30%

The exams will cover units 1 to 6. Therefore, their weight will count 75% towards the C#
mark for part B. The project counts 5% towards that mark.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 224

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 225

6.1 Introduction

At the end of this subsection, you should be able to:

 Understand the basics of the following topics:


o XML
o SOAP
o XML Web Services
o WSDL
o UDDI

The following topics will be explored in detail below:

 XML (eXtensible Markup Language)


 SOAP (Simple Object Access Protocol)
 XML Web Services
 WSDL (Web Services Description Language)
 UDDI (Universal Description, Discovery, and Integration)

6.1.1 XML (eXtensible Markup Language)


XML is a specification which can be used to create markup languages within documents
containing structured information. This structured information contains content and an
indication of what role the content plays. The content can be words or pictures. A markup
language is a mechanism to identify structures within a document.

It is very important to understand why XML was created. It was created so that richly
structured documents can be used over the Web. It is similar to HTML but has a different
purpose. XML describes data whereas HTML presents that data in a visual form. As
outlined in Unit 4, pieces of information are described within XML document tags. This
enables applications to interpret data accurately.

The following example demonstrates an XML document is its simplest form. Start by
creating a new XML document:

 Go to the desired folder.


 Right click on the window and select New.
 Select Text Document.
 Name it Example1 and change the extension to .xml (i.e. open the text file, go to
Save As, remove the .txt extension, and enter .xml).
 Right click on Example1.xml and select Edit.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 226

 Enter the following code into the file:

<book>
<title>Visual C# 2008</title>
<author>James Foxall</author>
<publisher>SAMS</publisher>
</book>

From the example above it is evident that James Foxall is the author of Visual C# 2008.
This data would have been quite confusing without the XML markup to make the
distinctions.

 Close the notepad.


 Double-click on Example1.xml.

Figure 6.1 should be displayed:

Figure 6.1 – XML document containing data

Although the example runs without errors, it is not very satisfactory as it does not do much.
XML is mainly used to transmit data from one domain to another. A program is created at
each end which is designed to interpret the XML document and to make use of the data.

6.1.2 SOAP (Simple Object Access Protocol)


SOAP is a simple mechanism that governs the format and processing rules of a SOAP
message. It also has basic control of communication between applications and accepts
SOAP messages in order to exchange information along a SOAP message path.

SOAP consists of the following four parts:

 The envelope
 The encoding rules
 The RPC representation
 The SOAP message

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 227

6.1.2.1 The envelope


The envelope is really a SOAP message which is essentially an XML document. This
message consists of an envelope (which must be present), a header (which is optional),
and a body (which must be present). The envelope is at the root of the message; the
header is used to add features to the message; the body contains the actual message that
must be transmitted.

6.1.2.2 The encoding rules


Encoding rules determine the standard way of representing data in a message. There are
many rules, but these are not covered in this course. For more information go to
http://schemas.xmlsoap.org/soap/encoding/.

6.1.2.3 The RPC representation


RPC stands for Remote Procedure Call. A remote procedure call refers to a situation
where one application calls a procedure on another application. These applications can
be on the same computer, but in most circumstances this will not be the case.

In .NET, SOAP can be used to perform Remote Procedure Calls. As such, SOAP
contains an RPC Representation which defines a convention that can be used to represent
remote procedure calls and responses.

6.1.2.4 The SOAP message


A SOAP message contains HTTP which makes sure it is ready to be transmitted across
this medium. The recipient gathers information from the header and the body to find out
more about the method call.

Figure 6.2 shows a typical representation of a SOAP message.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 228

Figure 6.2 – Structure of a SOAP message

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 229

The next example is a simple SOAP message.

1 <SOAP:Envelope xmlns=http://schemas.xmlsoap.org/soap/envelope/>
2 <SOAP:Body>
3 <m:heyThere xmlns:m="http://www.osborne.com/"/>
4 </SOAP:Body>
5 </SOAP:Envelope>

The SOAP message always starts with the envelope element defined on line 1. The URL,
(xmlns=http://schemas.xmlsoap.org/soap/envelope), specifies the location for
further definitions. Line 2 is the start of the message body. Line 3 is the method call. It is
given a name and the namespace is specified. Lines 4 and 5 simply close the envelope
and body tags.

The example below shows exactly what the layout would look like if the envelope, the
header, the body, and the fault are present in a SOAP message.

<SOAP:Envelope xmlns:http://schemas.xmlsoap.org/soap/envelope/
soap:encodingStyle=http://schemas.xmlsoap.org/soap/encoding/>
<SOAP:Header>
<!--
Header information goes here, e.g.
<t:Transformation xmlns:t="URL"></t:Transformation>
-->
</SOAP:Header>
<SOAP:Body>
<!--
The body goes here, e.g.
<m:heyThere xmlns:m="URL" />
-->
<SOAP:Fault>
<!--
Fault information, e.g.
<faultcode>SOAP:Server</faultcode>
<faultstring>Server Error</faultstring>
-->
</SOAP:Fault>
</SOAP:Body>
</SOAP:Envelope>

The <SOAP:Fault> tag is used to specify details about a fault using <faultcode> and
<faultstring> tags.

6.1.2.5 SOAP in HTTP


The advantage of binding SOAP to HTTP is the ability to use the formal layout and
flexibility of SOAP with the extra features of HTTP. SOAP and HTTP have the same
request and response structure and they can therefore tie up easily.

HTTP acts as a transmission channel when using SOAP to send a method call within an
XML document. The steps in the process are described below:

 The client uses the specified URL to identify the server.


 The client connects to the server using the HTTP.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 230

 An HTTP request is sent to the server. A SOAP request is contained within the HTTP
request.
 The SOAP request is bound to HTTP.

The header of a SOAP HTTP looks like this:

1 POST /objectURI HTTP/1.1


2 HOST: www.someWebsite.com
3 SOAPMethodName: namespace:IItem#getItem
4 Content-Type: text.xml
5 Content-Length: xxxx

The method that will be called from the server is specified as getItem. The SOAP
document that the data can be retrieved from would look something like this:

1 <?xml version="1.0"?>
2 <SOAP:Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
3 <SOAP:Body>
4 <m:getItem xmlns:m="namespace:IItem">
5 <name>toy car</name>
6 </m:getItem>
7 </SOAP:Body>
8 </SOAP:Envelope>

The element m:getItem on line 4 matches the SOAPMethodName on line 3 in the


previous code snippet in the HTTP header.

Figure 6.3 is a diagrammatic presentation of the message process outlined above:

Figure 6.3 – The SOAP message process

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 231

6.1.3 XML Web Services


XML Web services expose functionality to Web users through a standard Web protocol.
This protocol consists of SOAP. XML Web services provide a way for an application to
communicate with a website. Lastly, XML Web services are registered so that potential
users can find them without any problems.

Figure 6.4 – Web services process

Figure 6.4 above shows how the client (consumer) makes a request to a directory service,
to find out what the location of the required Web service is. Once the location is returned,
the client proceeds to make a remote call to the server (provider). The server processes
the request and returns the result to the client.

6.1.4 WSDL (Web Services Description Language)


The Web Services Description Language (WSDL, pronounced “wizdle”) is an XML based
language and is used as a model for describing Web services. WSDL incorporates XML
and an XML schema (i.e. they are part of a WSDL document). The availability of functions
is checked first by a client program that reads the WSDL by connecting to the Web
service. Embedded within the WSDL is the XML Schema which may contain any special
data types. SOAP can then be used by the client program to call one of the functions
listed in the WSDL.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 232

The following elements can be found in a WSDL document:

 Types: The different data types used in the Web Service are defined here.
 Message: The actual message is described here.
 PortType: This part defines a set of operations and their related messages.
 Binding: Protocol details are described by binding elements.
 Service: A set of related ports are grouped here.

6.1.5 UDDI (Universal Description, Discovery, and Integration)


UDDI is described by http://msdn.microsoft.com/ as “the yellow pages of Web services”. A
UDDI directory is an XML file that describes a business and the services it offers.

Here are some other facts about UDDI:

 UDDI is a directory for storing information about Web services.


 UDDI is a directory of Web service interfaces described by WSDL.
 UDDI communicates via SOAP.
 UDDI is built into the Microsoft .NET platform.

The UDDI Business Registry system consists of three directories:

 UDDI white pages: This is the basic information such as the company name, address,
and phone numbers.
 UDDI yellow pages: This is the detailed business data.
 UDDI green pages: This is the information about the key business processes of the
company. This includes the operating platform, supported programs, purchasing
methods, shipping and billing requirements, and other high-level business protocols.

Figure 6.5 shows the process of discovering and using a Web Service as seen from the
consumer’s point of view:

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 233

Figure 6.5 – Finding and using an XML Web Service

6.1.6 Exercises
1. Name the three components of the UDDI Business Registry.
2. For what does XML stand?
3. Name the three components of a SOAP message.
4. What is a SOAP message wrapped with?
5. For what does WSDL stand?

6.1.7 Revision questions


1. True/False: UDDI is a directory for storing information about Web
services.
2. True/False: WSDL documents are written in XML.
3. True/False: A SOAP request may use protocols other than HTTP.
4. True/False: Encoding rules determine the standard way of
representing data in a message.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 234

6.2 XML data

At the end of this subsection, you should be able to:

 Access an XML file.


 Understand and use XPath.

6.2.1 Introduction
In .NET, XML support is contained in the System.Xml namespace and includes objects
that can be used to parse, validate, and manipulate XML. XML data can be read, written,
and validated using objects in this namespace. Additionally, the System.Xml namespace
provides access to XPath, which is used to navigate and query data contained in an XML
document.

6.2.2 Accessing an XML file


Accessing an XML file is a very simple task in .NET. Two different methods of accessing
XML files are provided by the .NET framework. Start by creating an XML file as follows:

 Create a new XML file as described in the previous section.


 Name this file data.xml.
 Enter the following code into the file:

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


<Roots>
<Root>
<Name>Weather Service</Name>
<Description>Latest weather information</Description>
<Website>http://www.weatherserv.ws</Website>
</Root>
<Root>
<Name>Sports Service</Name>
<Description>Sport updates</Description>
<Website>http://www.sportsserve.ss</Website>
</Root>
<Root>
<Name>News 247</Name>
<Description>Live news</Description>
<Website>http://www.news247.nw</Website>
</Root>
</Roots>

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 235

6.2.2.1 Understanding the DOM


According to Wikipedia, “the DOM (Document Object Model) is a platform- and language-
independent standard object model for representing HTML or XML and related formats”.
An XML document is represented by the DOM as a tree structure with elements, attributes,
and text as nodes as shown in Figure 6.6:

Figure 6.6 – An XML file represented in a tree form

6.2.2.2 The XmlReader object


The XmlReader class is an abstract class that has forward-only, read-only access to XML
data. The XmlReader class provides functionality to:

 Verify that the characters are legal XML characters, and that element and attribute
names are valid XML names.
 Verify that the XML document is well formed.
 Validate data against a DTD or schema.
 Retrieve data from the XML stream or skip unwanted records using a pull model.

The current node refers to the node on which the reader is positioned. Any of the read
methods can be used to advance the reader. The properties are used to return the value
of the current node.

Table 31Error! Reference source not found. shows the most important properties of the
XmlReader class:

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 236

Table 31 – Important properties of the XmlReader class


Property Description
Depth The depth of the node in the tree.
HasAttributes Whether or not the node has attributes.
HasValue Whether or not the node can have a text value.
IsEmptyElement Whether or not an Element node is empty.
Name The qualified name of the node.
NodeType The XmlNodeType of the node.
Value The text value of the node.

Table 32 shows the most important methods of the XmlReader class:

Table 32 – Important methods of the XmlReader class


Method Description
GetAttribute() Returns the value of an attribute.
IsStartElement() Specifies whether the current node denotes a start tag.
MoveToElement() Moves the pointer to the element which contains the
current attribute.
MoveToFirstAttribute() Moves the pointer to the first attribute of the current
element.
MoveToNextAttribute() Moves the pointer to the next attribute of the current
element.
Read() Reads the next node from the XML file.
Skip() Jumps over the children of the current element.

The XmlReader class cannot be instantiated and therefore the XmlTextReader class
must be used.

6.2.2.3 Example 1: XmlTextReader


 Create a new C# Windows Application in Visual C# 2008 and call it
XmlTextReaderEx1.
 Copy data.xml (created previously) into the project directory, and modify it as follows:

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


<Roots>
<Root Rating="6">
<Name>Weather Service</Name>
<Description>Latest weather information</Description>
<Website>http://www.weatherserv.ws</Website>
</Root>
<Root Rating="9">
<Name>Sports Service</Name>
<Description>Sport updates</Description>
<Website>http://www.sportsserve.ss</Website>
</Root>

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 237

<Root Rating="7">
<Name>News 247</Name>
<Description>Live news</Description>
<Website>http://www.news247.nw</Website>
</Root>
</Roots>

 Add a Button control with the label “Read XML” (btnReadXml) and a ListBox
control (lstNodes) to the form.
 Switch to the Code window and add the following using directive:
using System.Xml;
 Add the following code to the click event-handler for the Button control:

private void btnReadXml_Click(object sender, EventArgs e)


{
// Create a StringBuilder object.
StringBuilder curNode = new StringBuilder();

// Create an XmlTextReader object.


XmlTextReader xReader = new XmlTextReader(@"..\data.xml");

// While the XmlTextReader reads the specified file...


while (xReader.Read())
{
// Initializes the length of the StringBuilder object to zero.
curNode.Length = 0;

// Loops through the XmlTextReader with its Depth property and


// adds a blank space each time the loop goes around.
for (int i = 0; i < xReader.Depth; i++)
{
curNode.Append(" ");
}

// Adds the XmlTextReader object’s name and NodeType to the


// StringBuilder.
curNode.Append(xReader.Name + " ");
curNode.Append(xReader.NodeType.ToString());

// Tests if the TextReader has a value...


if (xReader.HasValue)
{
// If value is present, it is appended to the StringBuilder.
curNode.Append(": " + xReader.Value);
}

// The StringBuilder is added to a ListBox as an item.


lstNodes.Items.Add(curNode.ToString());
}

// Close the XmlTextReader.


xReader.Close();
}

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 238

The example above uses the following methods and properties:

 Read()
 Name
 HasValue
 Depth
 NodeType
 Value

 Build and run the project. Click the Read XML button.

The output should look like the one shown in Figure 6.7:

Figure 6.7 – Data read from an XML file using an XmlTextReader object

6.2.2.4 Example 2: XmlTextReader


In order to write an application which uses the XmlTextReader class, the following steps
must be performed:

 Create a new Windows Application in Visual C# 2008 and call it XmlTextReaderEx2.


 Add a Button control with the label “Read XML” (btnReadXml) and a ListBox
control (lstNodes) as in the previous example.
 Remember to add data.xml to the project folder as in the previous example.
 Switch to the Code window and add the following using directive:
using System.Xml;

 Add the following code to the click event-handler for the Button control:

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 239

private void btnReadXml_Click(object sender, EventArgs e)


{
StringBuilder curNode = new StringBuilder();
XmlTextReader xReader = new XmlTextReader(@"..\data.xml");

while (xReader.Read())
{
if ((xReader.NodeType == XmlNodeType.Element) ||
(xReader.NodeType == XmlNodeType.Text))
{
curNode.Length = 0;
for (int i = 0; i < xReader.Depth; i++)
{
curNode.Append(" ");
}

curNode.Append(xReader.Name + " ");


curNode.Append(xReader.NodeType.ToString());

if (xReader.HasValue)
{
curNode.Append(": " + xReader.Value);
}

lstNodes.Items.Add(curNode.ToString());

// Attributes are displayed.


if (xReader.HasAttributes)
{
while (xReader.MoveToNextAttribute())
{
curNode.Length = 0;
for (int i = 1; i <= xReader.Depth; i++)
{
curNode.Append(" ");
}

curNode.Append(xReader.Name + " ");


curNode.Append(xReader.NodeType.ToString());

if (xReader.HasValue)
{
curNode.Append(": " + xReader.Value);
}

lstNodes.Items.Add(curNode.ToString());
}
}
}
}
}

When the project is run and the Read XML button is clicked, the output should look like
Figure 6.8:

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 240

Figure 6.8 – Selected data read from an XML file using an XmlTextReader object

6.2.2.5 The XmlNode class


Each individual item in an XML file is called a node. There are a few entities that can be
treated as nodes. These are elements, attributes, whitespaces, tags, etc. Table 33 lists
members of the XmlNodeType enumeration:

Table 33 – Members of the XmlNodeType enumeration


Member Description
Attribute The value of an XML attribute.
CDATA The content of the XML CDATA section.
Comment The content of the XML comment.
Document Outermost element of an XML document
DocumentFragment Outermost element of an XML document’s subsection.
DocumentType DTD (Documents Type Description) reference.
Element XML element.
EndElement Closing tag of an XML element.
EndEntity End of an included entity.
Entity XML entity declaration.
EntityReference Reference to an entity.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 241

None The XmlReader object being used has not been


initialized.
Notation XML notation.
ProcessingInstruction XML processing instruction.
SignificantWhitespace Whitespace that must be preserved to keep the original
intact.
Text The text content of an item.
Whitespace The space between XML items.
XmlDeclaration The content of the XML declaration.

The XmlNode class is used to access a node as a whole, instead of accessing those
nodes as part of an XML data stream. It is more efficient to access a node as a whole. In
order to make code more object-orientated and provide a better overview of object in an
XML document, properties of a whole object can be changed after instantiating the object.
It can then be written back to the original XML file.

The XmlNode class contains a substantial number of properties and methods. It is


possible to retrieve or alter information regarding the object, as well as navigate through
the DOM, using these methods and properties. Table 34 lists the most important
properties of the XmlNode class:

Table 34 – Properties of the XmlNode class


Member Description
Attributes Retrieves the attributes of this node.
ChildNodes Retrieves all the child nodes of this node.
FirstChild Retrieves the first child of this node.
HasChildNodes Retrieves a value indicating whether this node has any
child nodes.
InnerText Retrieves the values of the node and all its child nodes.
InnerXml Retrieves the markup representing only the child nodes of
this node.
LastChild Retrieves the last child of the node.
Name Retrieves the qualified name of the node.
NextSibling Retrieves the node immediately after this node.
NodeType Retrieves the type of the current node.
OuterXml Retrieves the markup representing this node and all its
child nodes.
OwnerDocument Retrieves the XmlDocument to which this node belongs.
ParentNode Retrieves the parent of this node.
PreviousSibling Retrieves the node immediately before this node.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 242

Table 35 lists the most important methods of the XmlNode class:

Table 35 – Methods of the XmlNode class


Member Description
AppendChild() Adds the specified node to the end of the list of child nodes.
CloneNode() Creates a duplicate of this node.
InsertAfter() Inserts the specified node immediately after the current node.
InsertBefore() Inserts the specified node immediately before the current node.
PrependChild() Adds the specified node to the beginning of the child nodes list.
RemoveAll() Removes all the child nodes of the current node.
RemoveChild() Removes a specified child of the current node.
ReplaceChild() Replaces a specific child node with a new child node.
SelectNodes() Selects a number of nodes matching an XPath expression.
SelectSingleNode() Selects the first XmlNode that matches an XPath expression.
WriteContentTo() Saves all the child nodes of the node to a specified XmlWriter
object.
WriteTo() Saves the current node to a specified XmlWriter object.

6.2.2.6 The XmlDocument class


An XmlDocument object represents an entire XML document. It is therefore used to
create an XmlNode object that represents an item from an XML document. Table 36 lists
the most important methods of the XmlDocument class:

Table 36 – Methods of the XmlDocument class


Member Description
CreateAttribute() Creates an attribute node.
CreateElement() Creates an element node.
CreateNode() Creates an XmlNode object.
ImportNode() Imports a node from another document.
Load() Loads an XML document into an object.
LoadXml() Loads an XML document from a string of XML data.
Save() Saves the XmlDocument object as a file or stream.
WriteTo() Saves the XmlDocument object to an XmlWriter object.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 243

Table 37 lists the most important properties of the XmlDocument class:

Table 37 – Properties of the XmlDocument class


Member Description
DocumentElement Retrieves the root node for the document.
DocumentType Retrieves the node containing the DTD information for this
document, if one exists.
PreserveWhitespace Retrieves the value indicating whether to preserve white
space when loading or saving XML.

Table 38 lists the most important events of the XmlDocument class:

Table 38 – Events of the XmlDocument class


Member Description
NodeChanged Occurs after the value of a node has been changed.
NodeChanging Occurs when the value of a node is about to be changed.
NodeInserted Occurs after a new node has been inserted.
NodeInserting Occurs when a new node is about to be inserted.
NodeRemoved Occurs after a node has been removed.
NodeRemoving Occurs when a node is about to be removed.

6.2.2.7 Example 3: XmlNode and XmlDocument classes


 Create a new Windows Forms Application in Visual C# 2008 Express Edition and
name it XmlNodeEx1.
 Add a Button control (btnSearch) and a ListBox control (lstNodes) to the form.
 Add the following using directive:
using System.Xml;
 Add the same .xml file used in Example 1 to the current project folder.
 Add the following class below the Form1 class:

private void AddChildren(XmlNode xNode, Int32 iDepth)


{
// This method adds a child to the list of nodes
StringBuilder currentNode = new StringBuilder();
if ((xNode.NodeType == XmlNodeType.Element) ||
(xNode.NodeType == XmlNodeType.Text))
{
currentNode.Length = 0;

for (int i = 0; i < iDepth; i++)


{
currentNode.Append(" ");
}

currentNode.Append(xNode.Name + " ");


currentNode.Append(xNode.NodeType.ToString());
currentNode.Append(": " + xNode.Value);

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 244

lstNodes.Items.Add(currentNode.ToString());

XmlAttributeCollection attCollection = xNode.Attributes;


if (attCollection != null)
{
for (int i = 0; i < attCollection.Count; i++)
{
currentNode.Length = 0;
for (int j = 0; j < iDepth + 1; j++)
{
currentNode.Append(" ");
}

currentNode.Append(attCollection[i].Name + " ");


currentNode.Append(
attCollection[i].NodeType.ToString());
currentNode.Append(": " + attCollection[i].Value);
lstNodes.Items.Add(currentNode.ToString());
}
}

XmlNode xNodeWorking;
if (xNode.HasChildNodes)
{
xNodeWorking = xNode.FirstChild;
while (xNodeWorking != null)
{
AddChildren(xNodeWorking, iDepth + 1);
xNodeWorking = xNodeWorking.NextSibling;
}
}
}
}

 Add the following code to the click event-handler of btnSearch:

StringBuilder currentNode = new StringBuilder();


XmlTextReader xTReader = new XmlTextReader(@"../../data.xml");
xTReader.WhitespaceHandling = WhitespaceHandling.None;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(xTReader);
XmlNode xRootNode = xDoc.DocumentElement;
XmlNode xNodeWorking;
if (xRootNode.HasChildNodes)
{
xNodeWorking = xRootNode.FirstChild;
while (xNodeWorking != null)
{
AddChildren(xNodeWorking, 0);
xNodeWorking = xNodeWorking.NextSibling;
}
}
xTReader.Close();

When all the code is entered the entire source code file should look like this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 245

using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace XmlNodeEx1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void AddChildren(XmlNode xNode, Int32 iDepth)


{
// This method adds a child to the list of nodes
StringBuilder currentNode = new StringBuilder();
if ((xNode.NodeType == XmlNodeType.Element) ||
(xNode.NodeType == XmlNodeType.Text))
{
currentNode.Length = 0;
for (int i = 0; i < iDepth; i++)
{
currentNode.Append(" ");
}
currentNode.Append(xNode.Name + " ");
currentNode.Append(xNode.NodeType.ToString());
currentNode.Append(": " + xNode.Value);
lstNodes.Items.Add(currentNode.ToString());

XmlAttributeCollection attCollection = xNode.Attributes;


if (attCollection != null)
{
for (int i = 0; i < attCollection.Count; i++)
{
currentNode.Length = 0;
for (int j = 0; j < iDepth + 1; j++)
{
currentNode.Append(" ");
}
currentNode.Append(attCollection[i].Name + " ");
currentNode.Append(
attCollection[i].NodeType.ToString());
currentNode.Append(": " + attCollection[i].Value);
lstNodes.Items.Add(currentNode.ToString());
}
}
XmlNode xNodeWorking;
if (xNode.HasChildNodes)
{
xNodeWorking = xNode.FirstChild;
while (xNodeWorking != null)
{
AddChildren(xNodeWorking, iDepth + 1);
xNodeWorking = xNodeWorking.NextSibling;
}
}
}
}

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 246

private void btnSearch_Click(object sender, EventArgs e)


{
StringBuilder currentNode = new StringBuilder();
XmlTextReader xTReader = new XmlTextReader(@"../../data.xml");
xTReader.WhitespaceHandling = WhitespaceHandling.None;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(xTReader);
XmlNode xRootNode = xDoc.DocumentElement;
XmlNode xNodeWorking;

if (xRootNode.HasChildNodes)
{
xNodeWorking = xRootNode.FirstChild;
while (xNodeWorking != null)
{
AddChildren(xNodeWorking, 0);
xNodeWorking = xNodeWorking.NextSibling;
}
}
xTReader.Close();
}
}
}

The output is very similar to the previous example. It should look like Figure 6.9:

Figure 6.9 – Selected data read from an XML file

The difference between the output in this example and the previous example is that the
program uses the XmlDocument class to navigate through the nodes. It also uses
recursion to visit the nodes right down to the last child.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 247

The specified information is displayed for each child and then each child of that node is
visited. The process is repeated until all nodes have been visited.

6.2.3 XPath
XPath (XML Path Language) is described as “a language for addressing parts of an XML
document”. It can be thought of as a query language, similar to SQL. A set of nodes can
be selected from the DOM representation of an XML document.

6.2.3.1 The XPath language


Particular elements or attributes can be selected from an XML document using XPath.
The expression starts off with the current context. This way the set of nodes that will be
considered for the “query” are determined. The current context can be specified in four
different ways and these are listed in Table 39:

Table 39 – XPath current context specifications


Symbol Description
./ Uses the current node as the current context.
/ Uses the root of the XML document as the current context.
./ / Uses the entire hierarchy starting with the current node as the current context.
// Uses the entire XML document as the current context.

A specific path down the tree structure is used to find a set of items. The items are
separated using forward slashes. This concept is shown in Figure 6.10:

Figure 6.10 – Selecting Name elements using XPath expressions

In figure 6.10, the Name element is selected. It can also be selected without being explicit,
as follows:

//Name

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 248

As in SQL statements, an asterisk (*) can be used as a wildcard. It has basically the
same function as in SQL. All names that are grandchildren of the Files node can be
selected as follows:

/Files/*/Name

A set of attributes can be selected instead of just a single element. To do this, simply add
the @ character in front of the attribute name. All Name attributes can be selected with the
following XPath expression:

//Files/File/@Name

Although the attribute can be specified without the path, it is recommended that all
expressions be presented explicitly.

The wildcard can once again be used to select multiple attributes but with a slight
difference. If the @ character is not included, the XPath expression looks for an element
instead. To select all the attributes of File, the following XPath expression can be used:

//File/@*

Specific nodes can also be extracted from XML using XPath expressions. Use the
following expression to find all Name elements in File with the value of Bill:

/Files/File/Name[.="Bill"]

Notice the dot operator. It represents the current node and the square brackets specify
the filter pattern. It is also possible to find all the Files with the name “Bill” with the
following expression:

/Files/File[./Name="Bill"]

Different patterns can be specified within the filtering specifications. These patterns
include attributes and Boolean expressions as shown in the next example:

/Files/File[./@Rating<10]

Apart from filtering patterns, different filtering functions, which form part of the filtering
patterns, can also be used in expressions. The example below selects all names that start
with B:

/Files/File[starts-with(Name, "B")]

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 249

There are a number of filtering functions that can be used and they are listed in Table 40:

Table 40 – XPath filtering functions


Function Description
concat() Returns the concatenation of the arguments.
contains() Determines whether one string is contained within another.
count() Returns the number of nodes in an expression.
last() Returns the last element in the expression.
normalize-space() Returns the string with the whitespace removed.
not() Returns true if the argument is false, otherwise false.
number() Converts the argument to a number.
position() Returns the origin of the node within the parent.
starts-with() Determines whether one string starts with another.
string-length() Returns the number of characters in the string.
substring() Returns a subsection of a string.

Square brackets and indexing can be used in conjunction with XPath. Indicating the
square brackets after a particular element makes it possible to select a certain element by
an index (numerical) value placed in the square brackets.

6.2.3.2 Example 4: Selecting nodes with XPath


 Create a new Windows Forms Application and name it XPathEx1.
 Add a Label control (lblOne), a TextBox control (txtExpression), a Button
control with the label “Search” (btnSearch), and a ListBox control (lstResults)
to the form.
 Add the following using directives:
using System.Xml;
 Add the same .xml file used in Example 1 to the current project folder.
 Add the following code to the XPathEx1 example:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace XPathEx1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 250

private void btnSearch_Click(object sender, EventArgs e)


{
XmlTextReader xTReader = new XmlTextReader(@"..\\..\data.xml");
xReader.WhitespaceHandling = WhitespaceHandling.None;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(xTReader);
XmlNodeList xNodeList =
xDoc.DocumentElement.SelectNodes(txtExpression.Text);
lstResults.Items.Clear();

foreach (XmlNode xNode in xNodeList)


{
if (xNode.NodeType == XmlNodeType.Element)
{
lstResults.Items.Add(xNode.NodeType.ToString() + ": " +
xNode.Name + " = " + xNode.FirstChild.Value);
}
else
{
lstResults.Items.Add(xNode.NodeType.ToString() + ": " +
xNode.Name + " = " + xNode.Value);
}
}
xTReader.Close();
}
}
}

 Run the project and enter the following expression into the TextBox control:
//Files/File/Name
 Click on the Search button and the names of all the files in the XML file will be shown
as seen in Figure 6.11:

Figure 6.11 – XPath example 4

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 251

6.2.3.3 The XPathNavigator class


When reading an XML file, the XmlReader class only allows forward-only and read-only
access. For random access to an XML file, another class called the XPathNavigator is
used. It provides read-only, random access to an XML file. It can select a set of nodes
based on an XPath expression as well as navigating the DOM representing an XML file.

The XPathNavigator class is an abstract class that defines a cursor model for
navigating and editing XML information items.

6.2.3.4 Selecting nodes with the XPathNavigator class via XPath


In order to select nodes using XPath and XPathNavigator, another class is included.
This class is called the XPathDocument. It is designed to provide optimised querying of
an XML file. The XPathDocument can be set up from a file, stream, or reader. There is
one very important method to remember and that is the CreateNavigator() method. It
returns an XPathNavigator object, which is then used in the query process.

Table 42 lists the most important properties of the XPathNavigator class:

Table 41 – Properties of the XPathNavigator class


Member Description
HasAttributes Retrieves a value indicating whether the current node
contains any attributes.
HasChildren Retrieves a value indicating whether the current node
contains any child nodes.
IsEmptyElement Retrieves a value indicating whether the current node is an
empty element without an end element tag.
Name Retrieves the qualified name of the current node.
Value Denotes the value of the current node.

Table 42 lists the most important methods of the XPathNavigator class:

Table 42 – Methods of the XPathNavigator class


Member Description
Clone() Creates a new XPathNavigator positioned at the same
node as this XPathNavigator.
ComparePosition() Compares the position of the current XPathNavigator
with the position of the XPathNavigator specified.
Compile() Compiles a string representing an XPath expression and
returns an XPathExpression object.
Evaluate() Evaluates the specified XPath expression and returns the
typed result.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 252

Matches() Determines whether the current node matches the


specified XPath expression.
MoveToFirst() Moves the XPathNavigator to the first sibling node of
the current node.
MoveToFirstAttribute() Moves the XPathNavigator to the first attribute of the
current node.
MoveToFirstChild() Moves the XPathNavigator to the first child node of the
current node.
MoveToNext() Moves the XPathNavigator to the next sibling node of
the current node.
MoveToNextAttribute() Moves the XPathNavigator to the next attribute.
MoveToParent() Moves the XPathNavigator to the parent node of the
current node.
MoveToPrevious() Moves the XPathNavigator to the previous sibling node
of the current node.
MoveToRoot() Moves the XPathNavigator to the root node that the
current node belongs to.
Select() Selects a node set, using the specified XPath expression.

6.2.3.5 Example 5: Selecting nodes using XPathNavigator


 Create a new Windows Forms Application and name it XPathEx2.
 Add a Label control (lblOne), a TextBox control (txtExpresssion), a Button
control (btnSearch), and a ListBox control (lstResults) to the form.
 Add the following using directive:
using System.Xml.XPath;
 Add the same .xml file used in Example 1 to the current project folder.
 Add the following code to the XPathEx2 example:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.XPath;

namespace XPathEx2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void btnSearch_Click(object sender, EventArgs e)


{
XPathDocument xpDoc = new XPathDocument(@"..\..\data.xml");

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 253

XPathNavigator xpNav = xpDoc.CreateNavigator();


XPathNodeIterator xpNodeIt = xpNav.Select(txtExpression.Text);
lstResults.Items.Clear();
while (xpNodeIt.MoveNext())
{
lstResults.Items.Add(xpNodeIt.Current.NodeType.ToString() + ": " +
xpNodeIt.Current.Name + " = " + xpNodeIt.Current.Value);
}
}
}
}

 Run the project and enter the following expression in the TextBox control:
//Files/File/Name
 Click the Search button and the names of all the roots in the XML file will be shown.

The output should look like Figure 6.12:

Figure 6.12 – XPath example 5

The XPathNodeIterator in example 5 makes it possible to visit every member of the


selected set of nodes, but it is also possible to use the XPathNavigator to move around
in the DOM.

6.2.3.6 Example 6: Navigating nodes with an XPathNavigator object


 Create a new Windows Forms Application and name it XPathEx3.
 Add four Button controls (btnParent, btnChild, btnPrevious, and btnNext)
and a ListBox control (lstResults) to the form.
 Add the following using directive:
using System.Xml.XmlPath;
 Add the same .xml file used in Example 1 to the current project folder.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 254

 Add the following code to the class definition just below the public partial class
Form1 : Form definition:

private XPathDocument xpDoc;


private XPathNavigator xpNav;

private void ListNode()


{
lstResults.Items.Add(xpNav.NodeType.ToString() + ": " + xpNav.Name + " = "
+ xpNav.Value);
}

 Add the following code to the Load event-handler of the form:

xpDoc = new XPathDocument(@"..\..\data.xml");


xpNav = xpDoc.CreateNavigator();
xpNav.MoveToRoot();
ListNode();

 Add the following code to the click event-handler of btnParent:

if (xpNav.MoveToParent())
{
ListNode();
}
else
{
lstResults.Items.Add("No parent node");
}

 Add the following code to the click event-handler of btnChild:

if (xpNav.MoveToFirstChild())
{
ListNode();
}
else
{
lstResults.Items.Add("No child node");
}

 Add the following code to the click event-handler of btnPrevious:

if (xpNav.MoveToPrevious())
{
ListNode();
}
else
{
lstResults.Items.Add("No previous node");
}

 Add the following code to the check event-handler of btnNext:

if (xpNav.MoveToNext())
{
ListNode();

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 255

else
{
lstResults.Items.Add("No next node");
}

 When all the pieces of code have been added, the source file should contain the
following:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.XPath;

namespace XPathEx3
{
public partial class Form1 : Form
{
private XPathDocument xpDoc;
private XPathNavigator xpNav;

private void ListNode()


{
lstResults.Items.Add(xpNav.NodeType.ToString() + ": " + xpNav.Name +
" = " + xpNav.Value);
}

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)


{
xpDoc = new XPathDocument(@"..\..\data.xml");
xpNav = xpDoc.CreateNavigator();
xpNav.MoveToRoot();
ListNode();
}

private void btnParent_Click(object sender, EventArgs e)


{
if (xpNav.MoveToParent())
{
ListNode();
}
else
{
lstResults.Items.Add("No parent node");
}
}

private void btnChild_Click(object sender, EventArgs e)


{
if (xpNav.MoveToFirstChild())

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 256

{
ListNode();
}
else
{
lstResults.Items.Add("No child node");
}
}

private void btnPrevious_Click(object sender, EventArgs e)


{
if (xpNav.MoveToPrevious())
{
ListNode();
}
else
{
lstResults.Items.Add("No previous node");
}
}

private void btnNext_Click(object sender, EventArgs e)


{
if (xpNav.MoveToNext())
{
ListNode();
}
else
{
lstResults.Items.Add("No next node");
}
}
}
}

 Run the project and randomly select between the buttons.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 257

The result should look similar to Figure 6.13:

Figure 6.13 – XPath example 6

6.2.4 Exercises
1. What does DOM stand for?
2. In which namespace is all XML support contained?
3. Which property of the XmlReader class is used to determine
whether or not the node can have a text value?
4. Which method of the XmlReader class is used to jump over children
of the current element?
5. For what is the XmlNode class used?

6.2.5 Revision questions


1. True/False: The XmlDocument class does not contain events.
2. True/False: XPath is also referred to as the XML Path Language.
3. True/False: The dot notation represents the current node.
4. True/False: The not() method belongs to the XPathDocument
class.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 258

6.3 .NET Remoting

At the end of this subsection, you should be able to:

 Understand the concept of .NET Remoting.


 Understand application boundaries.
 Understand the basics of distributed applications.
 Understand the basic structure of the .NET Remoting architecture.
 Implement this architecture to create a distributed application.

6.3.1 Introduction
.NET Remoting enables applications to communicate with each other. The .NET objects
are exposed to remote processes which allow inter-process communication. This is all
made possible by the .NET Framework which provides a platform for distributed
applications. The two most prevalent means are .NET Remoting and Web Services.

6.3.2 When is .NET Remoting used?


.NET Remoting is designed automatically to perform certain tasks that were previously
done manually. These tasks include creating sockets, sending data across a network,
accepting the data on a remote server, processing the data, and then passing it back to its
origin. It must also maintain open port connections to which clients may connect.

Now that Remoting handles these tasks automatically, socket programming is performed
in the background and management responsibilities are something of the past.
Programmers need no longer to concern themselves with how a program will connect to a
remote server, but only with the design of a program and making sure the logic is correct.
In the end it makes development of distributed applications efficient and cost-effective.

6.3.3 Application boundaries


Firstly the word boundaries have to be defined. Boundaries are a set of rules and borders
defined for an application. These boundaries have to be obeyed as much as possible.
These boundaries are aspects like data, space, and code. It might not be clear why an
application has these boundaries, but it is to protect the application from interfering with, or
the interference from, other applications.

6.3.3.1 Process boundaries


These application boundaries can be further expanded to become more specific. In this
case, they work exactly as described in this section. When an application is run in an
operating system such as Windows, it is said that a process is in progress.
For example, a Word document and an Excel document may be open. These documents
are described as the application and each of these documents will run in its own process.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 259

Windows then creates boundaries between these documents so that they do not affect
each other. These process boundaries ensure that:

 One process cannot gain access to code or data of another process.


 Each process owns separate address space, executable code, and data.
 Each process can only be associated with one application so that program failure does
not have an effect on other applications.

Processes have to be created, monitored constantly, and terminated when a failure occurs
or each time a different application is run, and they are therefore resource-intense.

6.3.3.2 Application domain boundary


Efficient execution, secure execution, and extensive debugging support are ensured by
features provided by the CLR (Common Language Runtime). Type-safety verification aids
in process isolation. This means that code is much less likely to access another process
by accident. The code execution is therefore referred to as managed code.

The application domain is considered the base of process isolation and is represented by
the System.AppDomain class. It is possible to run multiple application domains within a
single Windows process. This results in the reduction of the overhead because there is
less switching of processes.

Application domain boundaries have techniques to reduce overhead caused by process


switching and improve application performance. They are as follows:

 One application domain cannot gain access to code or data of another domain.
 Every application domain has its own code, data, and configuration.
 The code running within an application domain cannot affect code running within
another application domain.
 An application domain can be terminated by the CLR without affecting or terminating
other applications in the same process.

6.3.4 Distributed applications


As described above, under normal circumstances it is not possible for one application to
access anything outside its own application boundaries. However, there is an increasing
need for applications to be able to communicate with one another, which means crossing
those boundaries. Distributed applications have the following needs:

 Establish communication between objects in separate application domains.


 Establish communication between objects running on enterprise applications.
 Run portions of an application if another part is busy or has failed. This is known as
application availability.

6.3.4.1 Evolution of distributed applications


A distributed application has multiple, independent components. The .NET Framework is
ideal for creating distributed applications. With technology rapidly developing all around

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 260

the world, developers have to be able to develop a product as quickly as possible,


integrate that product with legacy applications, and make applications interoperable with
their business partners’ applications. The .NET Framework is ideal to meet all these
needs all at once or one by one, depending on the project.

6.3.4.2 Developing distributed applications with the .NET framework


The functionality provided by the .NET supports the development of distributed
applications and they are contained in three namespaces: System.Web.Services,
System.Net, and System.Runtime.Remoting.

1. System.Net provides classes to create listeners, protocol handlers, and customised


frameworks. The function of a listener is to listen for attempts to connect to a port.

2. System.Runtime.Remoting provides classes that make up the .NET Remoting


framework.

3. System.Web.Services provides classes that make up the ASP.NET Web Services


framework.

The functionality of Remoting and Web Services is very similar because Web Services
were built on the Remoting infrastructure. It is sometimes difficult to decide whether to
make use of Web Services or Remoting. Follow these tips to make a choice:

 An application designed for a corporate network, for example, needs to have both
ends of communication (namely the client and the server) under control and therefore
.NET Remoting will be better suited to this application.
 When only one end point needs to be under control, ASP.NET Web Services will
suffice. This might be used when a business partners’ application needs to be
interoperable.

6.3.5 .NET Remoting architecture


.NET Remoting can be used when one domain needs to communicate with another
domain, but its real strength is tested when one object needs to communicate with an
object that resides in a different location across a network.

It was previously stated that applications have boundaries and the question of how
domains communicate across a network might arise. There is a solution! These tasks are
performed indirectly by using a proxy object as illustrated in Figure 6.14:

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 261

Figure 6.14 – Simplified .NET Remoting architecture

The process outlined above takes place in the following steps:

1. When the client requests information from the server, the Remoting system on the
client application creates a proxy object, which behaves like the actual server object,
but resides in the same application as the client. The server objects now appear to be
in the same process.
2. When a method on the server object is called by the client object, the proxy
object passes information to the client’s Remoting system, which sends it to the
server’s Remoting system through a transmission channel.
3. The server’s Remoting system receives the information and calls the method in the
server object.
4. The server’s Remoting system receives the result of the method and sends the
information back to the client’s Remoting system, through the transmission
channel.
5. The client’s Remoting system then receives the result and passes it back to the
client object via the proxy object.

The process above is known as marshalling. This includes communication between


objects across application boundaries, and using serialisation and de-serialisation.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 262

Serialisation is the process of encoding an object or data into a form that can be sent
safely across a communication channel. De-serialization is the exact opposite of
serialisation. It is invoked once information arrives.

6.3.5.1 Object marshalling


Objects that can be marshalled across application domains are known as remotable
objects. Objects which cannot be marshalled are referred to as non-remotable objects.
There are two types of remotable objects: Marshal-By-Value and Marshal-By-Reference.

6.3.5.1.1 Marshal-By-Value (MBV) objects


 MBV objects are located on the server. When a request is sent by a client to invoke a
method, the entire object is serialised, sent to the client, and restored there as the
complete object, to then be used by the client object. Since there is now a copy of the
object running on the server, method calls do not have to go through a proxy object.
 The advantage of these objects is that network traffic is reduced because there is only
one transmission. However, it can become a disadvantage when the object is quite
large. This type of object does not run its methods in the server environment.
 Declare a class with the Serializable attribute to create an MBV object:

[Serializable()]
public class MBVObject
{
// Methods to be called.
}

6.3.5.1.2 Marshal-By-Reference (MBR) objects


 MBR objects can only be found on the server. This is the only place where their
methods are invoked. When the client wants to invoke a method, communication is
established through the proxy object which contains a reference to the server object.
 MBR objects are used when network traffic could be dramatically affected by
transferring a whole object. The number of roundtrips is increased, but there are other
advantages. If the object was designed to run in the server environment, this
approach is vital.
 Derive a class from the System.MarshalByRefObject class to create an MBR
object:

public class MBRObject : MarshalByRefObject


{
// Methods to be called.
}

6.3.5.2 Channels
Channels are very handy objects. They are used to transport information or data across
application boundaries. Each call from a client is sent from the client’s Remoting system
to the server’s Remoting system through a channel object. This is also known as the
transmission channel as shown in figure 6.14. Any results will be returned to the client via
the same channel.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 263

Each channel consists of two endpoints: one at the server’s side and one at the client’s
side. The end at the server’s side listens for any information or data on a specific protocol
and port number. The end at the client’s side receives the information or data sent across
the channel using the same specific protocol and port number. There are two channel
implementations provided with .NET. One is based on HTTP and the other on TCP.

6.3.5.2 1 HTTP (Hypertext Transmission Protocol) Channels


 HTTP is used to provide communication between two end points. All implementations
are in the System.Runtime.Remoting.Channels.Http namespace. Table 43
lists the related classes:

Table 43 – HTTP channel classes


Class Implements Description
HttpServerChannel IChannelReceiver Implements a server channel
to communicate via HTTP.
HttpClientChannel IChannelSender Implements a client channel to
communicate via HTTP.
HttpChannel IChannelReceiver and Implements a combination of
IChannelSender the server and client channel.

 The code below registers an HTTP channel on port 1248 and is able to send and
receive:

using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;

// Preceding code.
HttpChannel channel = new HttpChannel(1248);
ChannelServices.RegisterChannel(channel);

The RegisterChannel method is part of the ChannelServices class. It performs


several services related to Remoting.

6.3.5.2 2 TCP (Transmission Control Protocol) Channels


 TCP is used to provide communication between its two endpoints. Implementations
are in the System.Runtime.Remoting.Channels.Tcp namespace. Table 44 lists
the related classes:

Table 44 – TCP channel classes


Class Implements Description
TcpServerChannel IChannelReceiver Implements a server channel to
communicate via TCP.
TcpClientChannel IChannelSender Implements a client channel to
communicate via TCP.
TcpChannel IChannelReceiver and Implements a combination of
IChannelSender the server and client channel.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 264

 The code below registers a TCP channel on port 1248 and is able to send and receive:

using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

// Preceding code.
TcpChannel channel = new TcpChannel(1248);
ChannelServices.RegisterChannel(channel);

6.3.5.3 Choosing between HTTP and TCP channels


In order to make an informed decision about which channel to choose, it is wise to
compare the two, as outlined in Table 45:

Table 45 – Comparing HTTP and TCP channels


HttpChannel TcpChannel
Efficiency Decreased Increased
 HTTP has a high overhead and  This protocol uses raw sockets to
this decreases efficiency. transmit information or data across
a network.
Scope Wide Narrow
 HTTP servers are more robust  Certain ports are required to be
because objects can be hosted opened, and therefore not
on them. everyone may obtain access.
 This object can be accessed from
anywhere via the Internet.
Security High Low
 Advantage can be taken of SSL  There is no security system to
(Secure Socket Layer), and accompany this protocol, therefore
Windows authentication when creating a security risk.
hosting IIS.

6.3.5.4 Formatters
Formatters play a very important role in sending messages across a channel. The data
contained within a message first needs to be serialised and encoded. When it reaches the
receiving end, the data is decoded and de-serialised. This is all done by Formatters. Two
formatters are commonly used: Soap and Binary.

6.3.5.4 1 SoapFormatter class


SOAP is not bound to a transport medium. The SoapFormatter class is implemented in
the System.Runtime.Serialisation.Formatters.Soap namespace. In cases
when communication between two incompatible architectures is required, this formatter is
used.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 265

6.3.5.4.2 BinaryFormatter class


The data BinaryFormatter objects encode can only be ecoded by objects based on
the .NET framework. It is, however, much more compact and efficient. The
BinaryFormatter class exists in the
System.Runtime.Serialization.Formatters.Binary namespace.

6.3.5.5 Channels and Formatters


The SOAP formatter is selected by default when the HTTP channel is used. TCP, on the
other hand, uses binary formatting by default. It is possible to configure these details. If a
different formatter is required above the default one, it is possible to make the change.

6.3.5.6 Remote Object Activation


MBR objects were covered earlier and they are the only objects that can be activated
remotely. This is because MBV objects are copied directly to the client’s machine,
whereas MBR objects are not. They can be classified as follows:

 Server-activated objects
 Client-activated objects

6.3.5.6.1 Server-activated objects (SAO)


These objects are activated by the server and the server controls their lifetime. When a
client calls a method on the remote object, an object is instantiated by the server. This
makes the method somewhat inflexible, because no parameters can be passed when
instantiating the object. Two activation modes exist for server-activated objects:

1. SingleCall activation mode


When using SingleCall activation mode, the remote object is only instantiated for a
single request from the client. After the method has been executed, the object will be
deleted and the memory that contained the object is released. There is literally
nothing that is kept since they only exist for the duration of the request. In other
words, no information that is particular to a client is preserved on the server’s side
from one request to the next. Objects activated in SingleCall mode are therefore
known as stateless. This mode is preferred when:

 The object does not involve a significant overhead.


 No information needs to be preserved.
 The server must be able to handle a large number of requests.
 Support for load-balancing must be available.

2. Singleton activation mode


When the Singleton activation mode is used, there will only be one instance of the
remote object at most at any given time. This is regardless of the number of requests.
Unlike SingleCall activation mode, this mode can maintain information. Objects
activated in this mode are also known as stateful objects. Information can be shared
by clients. This mode is preferred when:

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 266

 Creating an object involves substantial overhead.


 Information needs to be preserved.
 Several clients must be able to access the shared state.

6.3.5.6.2 Client-activated objects (CAO)


As the name suggests, the lifetime of the client-activated objects is directly controlled by
the client. The remote object is instantiated the moment a client requests for it to be
created, and not only when the first method is called. The lifetime of a CAO is as follows:

1. A request is sent to the server to activate the object when a client wants to create an
instance of the remote object.
2. The object is instantiated with the constructor parameters provided by the client’s
request. This object is instantiated by the server. An ObjRef object is returned,
which contains information to generate a proxy to the remote object on the client that
can communicate with the remote object.
3. A proxy object is created by the client. It is based on the ObjRef object it received
from the server.

CAO is used when:

 Clients require a private session with the server.


 Clients require control over the creation and the lifetime of the remote object.

6.3.5.7 Lifetime Leases


The lifetime lease of an object is determined by the length of time that the object stays in
memory. Singleton SAOs and CAOs both implement lifetime leases to set the lifespan of
an object before it is deleted and the memory is reclaimed. The ILease interface,
contained in the System.Runtime.Remoting.Lifetime namespace, represents the
lifetime lease. Table 46 lists the most important properties of the ILease interface:

Table 46 – Important properties of the ILease interface


Member name Description
CurrentLeaseTime The time left before the object is marked for deletion.
InitialLeaseTime The initial time set for the objects lifespan. This will determine
the shortest time that will be taken to stay in memory.
RenewOnCallTime The amount by which CurrentLeaseTime will increase each
time a method of the object is called.
SponsorshipTimeout The time allowed for a lease to be renewed after the current
lease has expired.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 267

Table 47 lists the most important methods of the ILease interface:

Table 47 – Important methods of the ILease interface


Member name Description
Register() Register a sponsor for the lease.
Renew() Renew the lease of the object for a specific time.

The InitialLeaseTime property is used to set an object’s lifetime lease once it is


created. When one of the object’s methods is called, CurrentLeaseTime is increased
by the value in RenewOnCallTime. The lease can be directly renewed by calling the
Renew() method. When CurrentLeaseTime reaches zero, the time specified in
SponsorshipTimeout is allowed for renewal of the lease. When there is no renewal,
the object is deleted.

6.3.6 .NET Remoting applied

6.3.6.1 Creating a remotable class


For this example, a remotable class which simulates a connection to a database will be
created. The class returns a message to let the user know that a connection was created
to the specified database. The example does not require an actual database for it to work.

 Create a new Class Library and call it UseDatabase.


 Class1.cs is automatically generated. This can be seen in the Solution Explorer
window. Rename it to UseDatabase.cs.

 Alter the code in the source code file to look like the code below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace UseDatabase
{
public class UseDatabase : MarshalByRefObject
{
OleDbConnection conn = new OleDbConnection();

// Default constructor.
public UseDatabase() : this("CollegeDatabase.accdb")
{

public UseDatabase(string dbPath)


{
conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source = " + dbPath);
}

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 268

public DataSet ExecuteQuery(string query)


{
try
{
// Open a connection.
conn.Open();

// Create and fill the DataSet.


DataSet ds = new DataSet();
OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn);
adapter.Fill(ds);

// Close the connection.


conn.Close();

// Return the DataSet.


return ds;
}
catch (Exception e)
{
// Display an error message.
Console.WriteLine("An error has ocurred:" + e.Message);

// Re-throw e (i.e. pass it up to the next level).


throw e;
}
}
}
}

 Make sure to build the project by going to Build > Build Solution.

6.3.6.2 Creating the Server


 Create a new Windows Forms Application and name it DatabaseServer.
 Create an interface for this application. It should consist of the following:
o A Label control called lblMessage.
o A Button control called btnClose.
 Open the Project menu and select Add Reference….
 Select System.Runtime.Remoting from the list and select OK.
 Once again, open the Project menu and select Add Reference….
 Click on the Browse tab (as shown in Figure 6.15).
 Browse to the location of the UseDatabase project.
 In the UseDatabase project folder, browse to “\UseDabase\bin\Release\”.
 Select UseDatabase.dll and click OK.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 269

Figure 6.15 – Add Reference window

 Add the Microsoft Office Access 2007 database, CollegeDatabase.accdb, to the


project. This database was created in Unit 5.
 Alter the code in the source code file to look like the code below:

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Runtime.Remoting;
10 using System.Runtime.Remoting.Channels;
11 using System.Runtime.Remoting.Channels.Tcp;
12
13 namespace DatabaseServer
14 {
15 public partial class Form1 : Form
16 {
17 public Form1()
18 {
19 InitializeComponent();
20 }
21
22 private void Form1_Load(object sender, EventArgs e)
23 {
24 RunServer();
25 }
26
27 public void RunServer()
28 {
29 try
30 {

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 270

31 // Create and register the channel using TCP and port 1902.
32 TcpChannel channel = new TcpChannel(1902);
33 ChannelServices.RegisterChannel(channel, true);
34
35 // Register the UseDabase class.
36 RemotingConfiguration.RegisterWellKnownServiceType
37 (typeof(UseDatabase.UseDatabase), "UseDatabase",
38 WellKnownObjectMode.SingleCall);
39
40 lblMessage.Text = "Server running...";
41 }
42 catch (Exception e)
43 {
44 lblMessage.Text = "An error has ocurred...";
45 MessageBox.Show(e.Message);
46 }
47 }
48
49 private void btnClose_Click(object sender, EventArgs e)
50 {
51 Application.Exit();
52 }
53 }
54 }

On line 33, the RegisterChannel() method takes two parameters. The first parameter
specifies the name of the TcpServerChannel object and the second parameter indicates
whether security must be activated on this channel.

 Build and run the DatabaseServer project.

The resulting output should look like Figure 6.16:

Figure 6.16 – Database Server

6.3.6.3 Creating a client


 Create a new Windows Forms Application named DatabaseClient.
 Create an interface for the client. This interface must consist of the following:
o A TextBox control called txtQuery.
o A Button control called btnExecute.
o A DataGridView control called gridResults.
 As with the server, add references to both System.Runtime.Remoting and
UseDatabase.dll.
 Add the CollegeDatabase.accdb to the project.

 Modify the code in the source code file to look like the following code:

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 271

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using UseDatabase;

namespace DatabaseClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void btnExecute_Click(object sender, EventArgs e)


{
UseDatabase.UseDatabase useDb;

try
{
// Get the object from the server.
useDb = (UseDatabase.UseDatabase)Activator.GetObject
(typeof(UseDatabase.UseDatabase),
"tcp://localhost:8085/UseDatabase");

useDb = new UseDatabase.UseDatabase();

// Call the method.


DataSet ds = useDb.ExecuteQuery(txtQuery.Text);
// Set the DataGridView control's DataSource.
gridResults.DataSource = ds.Tables[0];

}
catch (Exception ex)
{
MessageBox.Show("An error has ocurred." + ex.Message);
}
}

private void Form1_Load(object sender, EventArgs e)


{
// The channel needs to be registered or
// the application will not work correctly.
TcpChannel channel = new TcpChannel();
ChannelServices.RegisterChannel(channel, true);
}
}
}

 Build and run the application.


 Ensure that the server is still running.
 Enter a query into the TextBox control and click the Execute Query Button control.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 272

The resulting output should look like Figure 6.17:

Figure 6.17 – SingleCall Client result

6.3.6.4 SingleCall mode vs. Singleton mode


 Create a new remotable class called Counter. The code for this class should be as
follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Counter
{
public class Counter : MarshalByRefObject
{
private int count = 0;

public int CountUp()


{
// Increment count.
count = count + 1;
// Return the new value.
return count;
}
}
}

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 273

 Save the project.


 Build the .dll file by opening the Build menu and clicking Build Counter.
 Create a new server called CountServer.
 Create the interface as before.
 As before, add references to System.Runtime.Remoting and the remotable object
(Counter.dll).
 The code for the server should be as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace CountServer
{
public partial class CountServer : Form
{
public CountServer()
{
InitializeComponent();
}

private void CountServer_Load(object sender, EventArgs e)


{
try
{
// Using TCP and port 1902.
TcpChannel channel = new TcpChannel(1902);
ChannelServices.RegisterChannel(channel, true);

// (A)
RemotingConfiguration.RegisterWellKnownServiceType
(typeof(Counter.Counter), "Counter",
WellKnownObjectMode.SingleCall);

lblMessage.Text = "Server running...";


}
catch (Exception ex)
{
lblMessage.Text = "An error has ocurred...";
MessageBox.Show(ex.Message);
}
}

private void btnClose_Click(object sender, EventArgs e)


{
Application.Exit();
}
}
}

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 274

 Save the project.


 Create a new Windows Forms Application for the client and call it CountClient.
 As before, add references to System.Runtime.Remoting and the remotable object
(Count.dll).
 Create an interface for the client. The interface should consist of the following:
o A Button control called btnCount.
o A Label control called lblMessage.
 The code for the client should be as follows:

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Runtime.Remoting;
10 using System.Runtime.Remoting.Channels;
11 using System.Runtime.Remoting.Channels.Tcp;
12
13 namespace CountClient
14 {
15 public partial class CountClient : Form
16 {
17 public CountClient()
18 {
19 InitializeComponent();
20 }
21
22 private void btnCount_Click(object sender, EventArgs e)
23 {
24 try
25 {
26 // Get the object from the server.
27 Counter.Counter c = (Counter.Counter)Activator.GetObject
28 (typeof(Counter.Counter), "tcp://localhost:1902/Counter");
29
30 // Call the method.
31 lblMessage.Text = "Count Value: " + c.CountUp();
32 }
33 catch (Exception ex)
34 {
35 MessageBox.Show("An error has ocurred." + ex.Message);
36 }
37 }
38
39 private void CountClient_Load(object sender, EventArgs e)
40 {
41 // The channel needs to be registerd or
42 // the application will not work correctly.
43 TcpChannel channel = new TcpChannel();
44 ChannelServices.RegisterChannel(channel, true);
45 }
46 }
47 }

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 275

 Run the server, followed by the client.

The client interface should resemble the following (Figure 6.18):

Figure 6.18 – Client interface

 Click the Count! Button control a few times.

Observe how the value returned by the Counter is always 1. This is because a new object
is instantiated (line 27) every time the method is called.

 Close both the client and the server.


 Modify point (A) in the Server to use Singleton mode instead of SingleCall mode,
i.e.:

// (A)
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Counter.Counter),
"Counter", WellKnownObjectMode.Singleton);

 Run the server and the client once again.


 Click the Count! Button control a few times.

With the server running in Singleton mode, a new object will be instantiated the first
time the CountUp() method is called. From there on, the same object will be used for
each method call. As such, the value returned from the Counter object will increase by
one every time the CountUp() method is called, and this value will be maintained in
between method calls. Even if the client is closed and reopened, this value will not be lost.

6.3.6.5 Client-activated objects (CAO)


Client-activated objects are created similarly to Server-activated objects. The following
changes are apparent:

1. Channels are registered as separate server and client channels, and not as a
combined channel.
2. The RegisterWellKnownServiceType method is changed to
RegisterActivatedServiceType and RegisterActivatedClientType
respectively.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 276

 Modify point (A) in the server of the previous example so that it appears as follows:

// (A)
RemotingConfiguration.RegisterActivatedServiceType(typeof(Counter.Counter));

 Modify the client code of the previous example so that it appears as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace CountClient
{
public partial class CountClient : Form
{
public CountClient()
{
InitializeComponent();
}

Counter.Counter c;

private void btnCount_Click(object sender, EventArgs e)


{
try
{
// Call the method.
lblMessage.Text = "Count Value: " + c.CountUp();
}
catch (Exception ex)
{
MessageBox.Show("An error has ocurred." + ex.Message);
}
}

private void CountClient_Load(object sender, EventArgs e)


{
// The channel needs to be registerd or
// the application will not work correctly.
TcpChannel channel = new TcpChannel();
ChannelServices.RegisterChannel(channel, true);

// Create an object on the server.


RemotingConfiguration.RegisterActivatedClientType
(typeof(Counter.Counter), "tcp://localhost:1902");

// Instantiate.
c = new Counter.Counter();
}
}
}

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 277

When the Count! Button control is clicked; it will maintain its value for as long as the
client is running. If the client is closed and then run again, a new instance of the Counter
object will be created; thus the count value will be reset. If another client was to connect to
the server at the same time, it would also receive its own unique Counter object which
will be maintained until the client is closed (or the client disposes of the object explicitly).

The CAO is a simple one and could be duplicated without using remoting. It can be
duplicated simply by storing a value in the client itself. However, this does not mean that
client-activated objects have no use. After all, they still reside on the server. One way of
testing this is to have the Counter object write its count value to the console whenever
the CountUp() method is called. As the server is a Windows Forms Application, it will
not display a console by default. The console can be enabled in a Windows Forms
Application by following these steps:

 Open the Project menu.


 Click on (Project Name) Properties….
 In the Application type: ComboBox, select Console Application (this will not change
the application itself in any way – it will merely make the console visible).
 Save the project.

This can be very useful for debugging. When debugging is complete, the Application
type field should be set back to Windows Forms Application.

NOTE Always remember that remotable applications consist of at least three parts,
i.e. the client, the server, and the remotable object(s). All of these must be
handed in for projects and examinations.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 278

6.3.7 Exercises
1. Which parts of network programming are handled by .NET Remoting to
make the developer’s work easier?

2. What purpose do application boundaries serve?

3. Explain, step by step, the process used by .NET Remoting to transfer


information between application boundaries.

4. Tom needs a remotable object that contains a method which retrieves


information from a central database. When the client calls this method,
the latest information from that database is returned. Should Tom use a
marshal-by-value object or a marshal-by-reference object? Why?

5. Adeena is writing an application using .NET Remoting to retrieve her


personal journal entries from a server. These entries are not large, and
can be transferred quickly. She wants to be able to access the server
from anywhere, and the connection must be very secure. Should she
use an HTTP channel or a TCP channel for communication between the
client and server? Why?

6. A chat application using a server-activated object requires user


information to be kept throughout a session. Is SingleCall activation
mode or Singleton activation mode recommended for this requirement?
Why?

6.3.8 Revision questions


1. Which three of the following are resources that reside within an
application’s process boundary?
a. Data
b. Memory bus
c. Executable code
d. Address space
e. Accumulation register
f. Registry handle

2. Henry wants to write an application that must interface with the systems
of his suppliers for automatic ordering of stock. He is not sure what kind
of systems his future suppliers might be using, but knows that they will
provide functionality for placing orders. Which approach should Henry
take when designing this application, and why?
a. He should use .NET Remoting, since he wants to design his
software for a corporate network.
b. He should use .NET Remoting, since both end points of
communication are known and under his control.
c. He should use Web Services, since only one end point is under his
control.
d. He should use socket programming, since he needs to connect to

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 279

his suppliers on a hardware level.


3. True/False: The System.Net namespace contains the functionality
associated with .NET Remoting.

4. Which channel and formatter combination should be used when


interoperability is of great importance, and the need for efficiency is low?
a. TCP & Binary
b. TCP & SOAP
c. HTTP & Binary
d. HTTP & SOAP

5. Which one of the following methods would set a server to listen for client
connections using a server-activated object, and creating and destroying
the object for each client call?
a. RemotingConfiguration.RegisterWellKnownServiceType
(typeof(RemotingExample.DbConnect), "DbConnect",
WellKnownObjectMode.SingleCall);
b. RemotingConfiguration.RegisterWellKnownServiceType
(typeof(RemotingExample.DbConnect), "DbConnect",
WellKnownObjectMode.Singleton);
c. RemotingConfiguration.RegisterActivatedServiceType
(typeof(RemotingExample.DbConnect));
d. RemotingConfiguration.RegisterActivatedClientType
(typeof(RemotingExample.DbConnect), "tcp://localhost:1248");

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 280

6.4 Web Services

At the end of this subsection, you should be able to:

 Understand central Web Service concepts.


 Create a basic Web Service.
 Create a basic client program.
 Create a basic client Web application.

6.4.1 Introduction
The concept of Web Services might seem complicated and difficult, but the idea is quite
simple. A Web Service is a device used to interact with objects over the Internet as shown
in Figure 6.19. Web Services are also known as public methods that can be called over
the Internet.

www.mydomain.com

Client Program
Web Service

Internet
Web Application
(as Client) Application or
Web Application

Figure 6.19 – Web Service interaction through the Internet

Web Services are the basic fundamental building blocks of invoking features that can be
accessed by an application. The accessibility to provide the features across different
platforms that are developed using different languages can be used by any remote
application over the Internet. At times, the Web Services may prove more useful as a
means of providing the user with only the specified or relevant information without the
need for accessibility to resources that have to be securely maintained.

Look at this simple example. An internet ordering system might expose a Web service for
automated ordering purposes. It does not make a difference whether the Web Service’s
client is a standalone application or a Web application as shown in Figure 6.20.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 281

Figure 6.20 – Web Service request and response

6.4.2 Web Service concepts


There are several concepts involved when creating and deploying a Web Services. They
are SOAP, UDDI, and WSDL.

Figure 6.21 shows the basic objects involved in the Web Services architecture:

Figure 6.21 – Basic Web Services architecture objects

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 282

6.4.3 Creating a basic Web Service


In .NET, Web Services are created in Visual Web Developer. This IDE provides
functionality for:

a) Creating the Web Service from a template.


b) Hosting the Web Service.

.NET Web Services will normally be hosted using Microsoft Internet Information Services
(IIS). During testing, however, they can be hosted using Visual Web Developer.

 Open the Visual Web Developer 2008 Express Edition IDE.


 Open the File menu and select New Web Site…
 Ensure that the Language is set to Visual C#.
 Select the ASP.NET Web Service template.
 Call the project AddService.
 Click OK.

The following code will be displayed:

1 using System;
2 using System.Linq;
3 using System.Web;
4 using System.Web.Services;
5 using System.Web.Services.Protocols;
6 using System.Xml.Linq;
7
8 [WebService(Namespace = "http://tempuri.org/")]
9 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
10 // To allow this Web Service to be called from script, using ASP.NET AJAX,
11 // uncomment the following line.
12 // [System.Web.Script.Services.ScriptService]
13 public class Service : System.Web.Services.WebService
14 {
15 public Service ()
16 {
17 //Uncomment the following line if using designed components
18 //InitializeComponent();
19 }
20
21 [WebMethod]
22 public string HelloWorld()
23 {
24 return "Hello World";
25 }
26 }

A brief description of the automatically generated code follows:

 Lines 1 – 6:
o Include the namespaces necessary to create a Web Service.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 283

 Line 8:
o This attribute specifies that this class is a Web Service. It also specifies the
namespace in which the Web Service resides. This is not the .NET namespace,
but the website on which this Web Service will be hosted. This is used to
differentiate between different Web Services which share the same name and
http://tempuri.org/ is generally used during development.
 Line 9:
o This attribute specifies that the Web Service conforms to the WS-I (Web Services
Interoperability Organization) Basic Profile. This profile is primarily used to ensure
that multiple Web Services can be used in a client without interfering with one
another. This line may safely be deleted.
 Line 13:
o Declares a class called Service. This is the Web Service itself. It is not
necessary for the class to be called Service; and can be renamed if desired. All
Web Services are derived from System.Web.Services.WebService.
 Line 21:
o This attribute specifies that the method is a WebMethod. This attribute needs to
be specified for any method which must be accessible remotely.
 Lines 22 – 25:
o This is a WebMethod which returns the string “Hello World”.

 Remove the HelloWorld() WebMethod and replace it with another WebMethod


called Add(). This WebMethod should have the following code:

[WebMethod]
public int Add(int a, int b)
{
return a + b;
}

 Save the project.

Running the Web Service


Web Services can be run in the same way as any other ASP.NET website. However, the
following should be noted:

 When referencing a Web Service in a client application (or website), it is necessary to


know the exact address of the service. By default, when Visual Web Developer runs a
project, it picks a random unused port number to host the website. As such it is
necessary to specify a set port number. For projects and exams, port 8081 must be
used for any Web Services created.
 By default, Visual Web Developer hosts websites and Web Services in a virtual
directory on the server. By default, this virtual directory has the same name as the
project.

To set a specific port number for use by a project in Visual Web Developer:

 Select the project itself in the Solution Explorer.


 In the Properties window, set Use Dynamic ports to False.
 Set the Port number to the desired number (8081 in this case).

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 284

An additional property here is Virtual path. This property specifies which virtual directory
the development server should use. This property can be cleared, in which case no virtual
directory will be used (i.e. the server will run on http://localhost:8081/ instead of
http://localhost:8081/VirtualPath/, where 8081 is the port number). It is recommended, but
not vital, that this is done for any projects or exams. No virtual directories will be used for
further examples in this guide.

The Web Service can now be run.

 Select Start Debugging from the Debug menu, or press the <F5> key.

The following should now be seen (Figure 6.22):

Figure 6.22 – Service Web Service

This page describes the various WebMethods which are available from this Web Service.
These methods can be tested by clicking on their names, entering any necessary
parameters, and viewing the result (which will be returned in an .xml format).

The Web Service will continue to be available for client applications so long as the
development server is running. If stopped, this server will need to be run again before
client applications can access any exposed methods.

NOTE Always remember that the Web Service is separate to the rest of the
application and must also be handed in for any projects or exams.

6.4.4 Creating a client program


 Create a new Windows Forms Application in Visual C# 2008 Express Edition called
WebServiceClient.
 Create the interface. It should look as follows (Figure 6.23):

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 285

Figure 6.23 – Web Service Client

NOTE Make sure that the Web Service is running in Visual Web Developer while
adding the Web reference.

 From the Project menu and select Add Service Reference….


 Click Advanced….
 Click Add Web Reference….

The Add Web Reference dialog will now be visible (Figure 6.24):

Figure 6.24 – Add Web Reference dialog

 Enter the exact URL of the Web Service (http://localhost:8081/Service.asmx in this


case).
 Click Go.

The Web service description page should now be visible, and the Web Service should be
visible on the right-hand side of the screen.

 Enter the name of the Web Service in the Web reference name textbox.
 Click Add Reference.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 286

The Web reference will now appear in the Solution Explorer.

 Modify the code for the main form so that it looks as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WebServiceClient.AddService.Service;

namespace WebServiceClient
{
public partial class Form1 : Form
{
int a;
int b;

public Form1()
{
InitializeComponent();
}

private void btnCalculate_Click(object sender, EventArgs e)


{
try
{
a = Convert.ToInt32(txtNum1.Text);
b = Convert.ToInt32(txtNum2.Text);
}
catch (Exception)
{
MessageBox.Show("Please enter a number!");
}

try
{
Service s = new Service();
txtResult.Text = s.Add(a, b).ToString();
}
catch (Exception ex)
{
MessageBox.Show("An error has occurred..." + ex.Message);
}
}
}
}

 Save the project.


 Ensure that the Web Service is running and then run the application.
 Enter a number into each of the TextBox controls and click the Calculate button.

The answer will be displayed in the third TextBox control.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 287

6.4.5 Creating a client Web application


As with a regular application, creating an ASP.NET website which consumes a Web
Service involves adding a Web reference to the project.

 Create a new ASP.NET website called WebServiceClient.


 Create an interface that looks as follows (Figure 6.25):

Figure 6.25 – WebServiceClient interface

 From the Website menu, select Add Web Reference….

As before, the Add Web Reference dialog will be visible.

 Follow the same procedure as before to add the Web reference to the project.
 Modify the code so that it looks as follows:

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using AddService.Service;

public partial class _Default : System.Web.UI.Page


{
int a;
int b;

protected void Page_Load(object sender, EventArgs e)


{

protected void btnCalculate_Click(object sender, EventArgs e)


{
try
{
a = Convert.ToInt32(txtNum1.Text);
b = Convert.ToInt32(txtNum2.Text);
}
catch (Exception)
{
lblMessage.Text = "Please enter a number!";
}

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 288

try
{
Service s = new Service();
txtResult.Text = s.Add(a, b).ToString();
}
catch (Exception ex)
{
lblMessage.Text = "An error has occurred..." + ex.Message;
}
}
}

 Save the project.


 Ensure that the Web Service is running and then run the website.
 Enter a number into each of the TextBox controls and click the Calculate button.

As with the Windows Forms application, the answer will be displayed in the third TextBox.

6.4.6 Exercises
1. How is a method within a WebService identified as one which is
accessible through the WebService?
2. How is a Web Service accessed from a client application?

6.4.7 Revision questions


1. Which one of the following is not an element involved in Web
Services?
a. Provider
b. Broker
c. Consumer
d. Mediator

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 289

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 290

6.5 Project

At the end of this subsection, you should:

 Have completed one of the three projects listed below. Ask your
instructor which project you should complete.
 Be able to explain and implement all the concepts presented in the
project you have done.

General Guidelines when doing the project

Checking permissions on the database


For this project a Web Application must be created in conjunction with an MS Access
database. If the project is moved to another computer (for instance to work at home), the
permissions on the database can become problematic. ASP.NET does not give an error
when no permissions exist for the current user, but prints a stack trace stating that
“Operation must use an updateable query”.

The following steps should be followed after the project folder has been copied to another
computer:

In Windows Vista - if the computer is standalone (not on a network):

 Log on to the computer with Administrative rights for the user.


 From Windows Explorer, click on Tools  Folder Options. In the Folder Options
window, click on View. Then in Advanced Settings scroll down to the very bottom
and uncheck “Use simple file sharing (recommended)”.
 Right-click the database file (.mdb or .accdb), and choose Properties.
 Click on the Security tab.
 In the “Group or user names” section, click on the user with whom the currently log-on
is registered.
 In the “Permissions for Users” section, check the Allow option for all permissions.

Note on user documentation


Remember to include the following in the user documentation:

 List the software needed on the computer to run the project.


 Access database: Tell the user how to set the permissions needed.
 Give the user the URL-address where the project should be accessed.

Also refer to the section on Required Documentation in the Introduction to this guide.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 291

6.5.1 Project 1 – Sports Cars Auctions


Sports Cars Auctions is a company that deals in expensive sport cars. The owners would
like to develop a system that allows potential buyers to bid on the car of their choice,
similar to eBay. This requires a website for buyers to use a database containing customer
information, cars, and bid information, and a Web Service used by the website to interact
with the database.

Website
This must be written in Visual Web Developer 2008 Express Edition using C# only, and
should present the buyer with interfaces to satisfy the following needs:

 Buyers must be able to register by providing some personal details such as their email
address and a password. An additional question and answer must also be specified
and this will be asked should the password be forgotten.
 A logon facility is required. In case the user has forgotten the password, there must be
an option to change it, as long as the user-specified question is correctly answered.
 Once the user has logged on, a facility to view the cars must be provided. If a car is
selected, its relevant details must be displayed, including the highest bid made so far,
and the closing date for the bidding.
 The user must be able to bid on a specific car. Once a bid has been made, it cannot
be changed or retracted.
 Users must be able to add cars that they want to sell to the system. A facility to enter
all the relevant data must be available.
 The user must be able to change personal information.
 When the user has not logged in successfully and tries to view pages which require a
successful logon, he/she should be redirected to the start page to log in.
 A logoff facility is required for the user to end the session.

Database
The database may be created in Microsoft Access. The following information must be
stored for use in the Web Service and website:

 Buyer information provided when a user registers, e.g. UserID, email address,
password, etc.
 Car information, e.g. carID, description, starting bid, etc.
 Bid information, e.g. carID, userID, bid, value, etc.

Web Service
The Web Service must be created in Visual Web Developer 2008 Express Edition (as
described in the study guide). The following functionality must be made available through
the Web Service:

 Buyer information additions/changes.


 Car information additions/changes.
 Bid information additions.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 292

 Any other functionality required by the website.

Each time a bid is made, the application information is written to a log file.

NOTE It is a good idea to do some research to get idea feel for how auction sites
work. Use as much creativity as possible, but strive for an overall look that is
both professional and straightforward. The layout of each interface should be
clear enough to follow without any problems, yet include all the required
functionality.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 293

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 294

Project Evaluation – C# (CSPBC) Unit 6 – Project 1

Student: ________________ Instructor: ________________

Date submitted: ____________ Date marked: _____________

Achievement: % Possible Achieved


Source code documentation
Comments (author, date, purpose) for each class 2
Comments for individual code segments 2
Correct indentation of code 2
Subtotal: 6
Web site content
User registration works correctly 3
Logging on to the system works correctly 2
Changing user details works correctly 3
Forgotten password facility works correctly 2
Cars are displayed correctly 6
Making bids on cars works correctly 6
Submitting new cars works correctly 6
Session object used to test if user is logged in before displaying page 4
Logging off the system works correctly 2
Subtotal: 34
Database content
Tables are set out logically 4
All required fields are present 4
Field types are correct 2
Subtotal: 10
Web Service content
Relative path used to access the database 2
Data addition functionality works correctly 6
Data modification functionality works correctly 6
Other required functionality implemented and working correctly 4
Bids are written to log file 2
Subtotal: 20
Source code content
Descriptive naming of variables 3
All variables declared as the correct type 3
Code arranged logically in classes 3
Try/catch blocks used to catch exceptions 3
General code efficiency 8
Subtotal: 20
User Interfaces
Eye-pleasing visual design – all controls neatly lined up, no garish colour schemes 2
Appropriate controls used to present information 2
Navigation is intuitive and efficient 2
Information fits on screen properly (no horizontal scrolling) 2
Errors are handled and presented properly 2

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 295

Subtotal: 10

Penalties
Program does not compile -5
Program causes unhandled error during execution or user input -5
Program documentation not handed in -10
Source code listing not handed in -5
Program documentation does not adequately describe
 Program setup (2 marks)
 Database setup/permissions (1 mark)
-5
 Program operation (2 marks)

General comments

Total: 100

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 296

6.5.2 Project 2 – Online Book club


The Online Book club needs to redesign their website to enable registered users to rate
books that they have read with a rating out of 5. Develop a distributed Web application
that can be used as a book storage and rating system. Users must be able to register with
their email address, personal details, and a password. Registered users can then post
books that they have read, and rate books posted by others.

Website
This must be written in Visual Web Developer 2008 Express Edition using C# only, and
should present the user with interfaces to satisfy the following needs:

 Users must be able to register by providing some personal details such as their email
address and a password. An additional question and answer must also be specified
and this will be asked should the password be forgotten.
 A logon facility is required. In case the user has forgotten the password, there must be
an option to change it, as long as the user-specified question is correctly answered.
 Once the user has logged on, a facility to view the posted books must be provided. If
a book is selected, its relevant details must be displayed, including the book name, the
author, and the average rating given so far.
 The user must be able to rate a book on a scale of 1 to 5, with 5 being the highest
rating. Once a rating has been submitted, it cannot be changed or retracted.
 Users must be able to submit books that they want rated. A facility to enter all the
relevant data must be available.
 The user must be able to change personal information.
 If the user has not successfully logged in and tries to view pages which require a
successful logon, he/she should be redirected to the start page to log in.
 A logoff facility is required for the user to end the session.

Database
The database may be created in Microsoft Access. The following information is required
to be stored for use in the Web Service and Website:

 User information provided when a user registers, e.g. emailAddress, password, etc.
 Book information, e.g. bookID, bookName, author, etc.
 Rating information, e.g. bookID, userID, rating, etc.

Web Service
The Web Service must be created using Visual Web Developer 2008 Express Edition (as
described in the study guide). The following functionality must be made available through
the Web Service:

 User information additions/changes.


 Book information additions/changes.
 Rating information additions.
 Any other functionality require by the website.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 297

Each time a book is rated, write the application information to a log file. E.g. User E-mail:
someone@onlinebookclub.com, Book: The Secret, Author: Rhonda Byrne

NOTE It is a good idea to do some research to get an idea of how rating sites work.
Use as much creativity as possible, but strive for an overall look that is both
professional and straightforward. The layout of each interface should be clear
enough to follow without any problems, yet include all the required
functionality.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 298

Project Evaluation – C# (CSPBC) Unit 6 – Project 2

Student: ________________ Instructor: ________________

Date submitted: ____________ Date marked: _____________

Achievement: % Possible Achieved


Source code documentation
Comments (author, date, purpose) for each class 2
Comments for individual code segments 2
Correct indentation of code 2
Subtotal: 6
Web site content
User signup works correctly 3
Logging on to the system works correctly 2
Changing user details works correctly 3
Forgotten password facility works correctly 2
Book Ratings are displayed correctly 6
Rating of Books work correctly 6
Posting Additional Books works correctly 6
Session object used to test if user is logged in before displaying page 4
Logging off the system works correctly 2
Subtotal: 34
Database content
Tables are set out logically 4
All required fields are present 4
Field types are correct 2
Subtotal: 10
Web Service content
Relative path used to access the database 2
Data addition functionality works correctly 6
Data modification functionality works correctly 6
Other required functionality implemented and working correctly 4
Rating information is written to log file
Subtotal: 20
Source code content
Descriptive naming of variables 3
All variables declared as the correct type 3
Code arranged logically in to classes 3
Try/catch blocks used to catch exceptions 3
General code efficiency 8
Subtotal: 20
User Interfaces
Eye-pleasing visual design – all controls neatly lined up, no garish colour schemes 2
Appropriate controls used to present information 2
Navigation is intuitive and efficient 2
Information fits on screen properly (no horizontal scrolling) 2

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 299

Errors are handled and presented properly 2


Subtotal: 10

Penalties
Program does not compile -5
Program causes unhandled error during execution or user input -5
Program documentation not handed in -10
Source code listing not handed in -5
Program documentation does not adequately describe
 Program setup (2 marks)
 Database setup/permissions (1 mark)
-5
 Program operation (2 marks)

General comments

Total: 100

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 300

6.5.3 Project 3 – Buy or Bid Auction


Buy or Bid Auction is a company that sells any item that is still in a good condition. The
owners would like to develop a system that allows potential buyers to bid on the item of
their choice, similar to eBay. Alternatively, the potential buyer could simply buy an item by
bidding the lowest price possible. This requires a website for buyers to use a database
containing customer information, items and bid/buy information, and a Web Service used
by the website to interact with the database.

Website
This must be written in Visual Web Developer 2008 Express Edition using C# only, and
should present the customer with interfaces to satisfy the following needs:

 The potential buyer must be able to sign up by providing an email address and a
password plus other personal information needed for verification: full name, ID
number, address, and contact details. An additional question and answer must also
be specified and this will be asked should the password be forgotten.
 A logon facility is required. In case the user has forgotten the password, there must be
an option to change it, as long as the user-specified question is correctly answered.
 Once the user has logged on, a facility to view items must be provided. When an item
is selected, the relevant details must be displayed, including the price, highest bid
made so far, and the closing date of the bid.
 The user must be able to either buy the item or bid on it. Once the bid has been
made, it cannot be changed or retracted.
 Users must be able to add items that they want to sell to the system. A facility to add
all the relevant details must be available.
 The user must be able to change personal information.
 If the user has not successfully logged in and tries to view pages which require a
successful logon, then he/she should be redirected to the start page to log in.
 A logoff facility is required for the user to end the session.

Database
The database may be created in Microsoft Access. The following information must be
stored for use in the Web Service and website:

 Buyer information provided when a user registers, e.g. emailAddress, password, etc.
 Item information, e.g. itemID, description, price, startingBid, etc.
 Bid information, e.g. itemID, userID, bid, etc.
 Purchase information, e.g. itemID, userID, price, etc.

Web Service
The Web Service must be created using Visual Web Developer 2008 Express Edition (as
described in the study guide). The Web Service must provide the following functionality:

 Buyer information additions/changes.


 Item information additions/changes.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 301

 Bid information additions.


 Purchase information additions.
 Any other functionality required by the Website.

Each time a bid is made, the application information must be written to a log file.

NOTE It is a good idea to do some research to get an idea of how Internet auction
sites work. Use as much creativity as possible, but strive for an overall look
that is both professional and straightforward. The layout of each interface
should be clear enough to follow without any problems, yet include all the
required functionality.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 302

Project Evaluation – C# (CSPBC) Unit 6 – Project 3

Student: ________________ Instructor: ________________

Date submitted: ____________ Date marked: _____________

Achievement: % Possible Achieved


Source code documentation
Comments (author, date, purpose) for each class 2
Comments for individual code segments 2
Correct indentation of code 2
Subtotal: 6
Web site content
User registration works correctly 3
Logging on to the system works correctly 2
Changing user details works correctly 3
Forgotten password facility works correctly 2
Items are displayed correctly 5
Making bids on items works correctly 6
Purchasing items works correctly 5
Submitting new items works correctly 5
Session object used to test if user is logged in before displaying page 3
Logging off the system works correctly 2
Subtotal: 36
Database content
Tables are set out logically 4
All required fields are present 4
Field types are correct 2
Subtotal: 10
Web Service content
Relative path used to access the database 2
Data addition functionality works correctly 5
Data modification functionality works correctly 5
Other required functionality implemented and working correctly 4
Bids and purchases are written to log file 2
Subtotal: 18
Source code content
Descriptive naming of variables 3
All variables declared as the correct type 3
Code arranged logically in classes 3
Try/catch blocks used to catch exceptions 3
General code efficiency 8
Subtotal: 20
User Interfaces
Eye-pleasing visual design – all controls neatly lined up, no garish colour schemes 2
Appropriate controls used to present information 2
Navigation is intuitive and efficient 2

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 303

Information fits on screen properly (no horizontal scrolling) 2


Errors are handled and presented properly 2
Subtotal: 10

Penalties
Program does not compile -5
Program causes unhandled error during execution or user input -5
Program documentation not handed in -10
Source code listing not handed in -5
Program documentation does not adequately describe
 Program setup (2 marks)
 Database setup/permissions (1 mark)
-5
 Program operation (2 marks)

General comments

Total: 100

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 304

Unit 6 Test your knowledge (Self-test)

The questions in this section are similar to those asked in the exam. Try these questions
and then check the answers with the instructor. The questions are taken from the study
guide and textbook. The questions comprise theory and application questions which will
be in multiple choice, multiple response, true/false, and selection formats. Allow about 15
minutes for all the questions. Good luck!

Questions

True/False

1. True/False: An XmlNode can be of the Document type.

2. True/False: To access a Web Service from an application, a proxy of the remotable


object must be referenced when compiling the application.

Multiple choice

1. Which three of the following are members of the XmlReader class?


a. Depth
b. Height
c. SetValue()
d. SetAttribute()
e. EOF
f. Read()

2. Which one of the following properties would be adjusted to increase the lifetime of an
object every time one of its methods is executed?
a. CurrentLeaseTime
b. InitialLeaseTime
c. SponsorshipTimeout
d. RenewOnCallTime

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 305

3. What does the following code do?

StringBuilder curNode = new StringBuilder();


XmlTextReader xReader = new XmlTextReader(@"..\..\Test.xml");

while (xReader.Read())
{
curNode.Length = 0;

for (int i = 0; i < xReader.Depth; i++)


{
curNode.Append(" ");
}
}

a. For each node, one empty string is appended to curNode.


b. For each level of depth of a node, two spaces are appended to the string
contained in curNode.
c. Each node in succession is assigned to curNode.
d. A string is built from each node in the XML file by appending the node itself to a
string.

4. What would the following code do?

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

public class MyClass


{
public static void Main(string[] args)
{
TcpServerChannel channel = new TcpServerChannel(1248);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType
(typeof(RemotingExample.DbConnect), "DbConnect",
WellKnownObjectMode.SingleCall);

Console.WriteLine("Press <ENTER> to terminate...");


Console.ReadLine();
}
}

a. This code represents a client that connects to a server on port 1248, and creates a
proxy object of the object located on the server.
b. This code represents a server that registers the port 1248 for clients wanting to
connect. Upon a request it would create a remotable object, but destroy it after
the call has finished.
c. This code represents a client that connects to a server on port 1248, and requests
that the server register it for communication.
d. This code represents a server that registers the port 1248 for clients wanting to
connect. Upon a request it would create a remotable object, which keeps state
information stored through the session.

© CTI Education Group


Unit 6 – .NET Distributed Computing Page 306

5. When working with Remoting, what can be said about the following piece of code?

[Serializable()]
public class SomeObject
{
// Methods to be called
}

a. This object is located on the server. When a request comes in, the whole object is
serialized and then sent to the client.
b. This object is located on the client. When a request is made, the relevant
information is serialized and sent to the server.
c. This object is located on the server. When a request comes in, only the relevant
information is sent back.
d. This object is located on the client. When a request is made, the object is
serialized and sent to the server.

© CTI Education Group


Language Comparison Page 307

Language Comparison
C#, VB.NET, and Java
Based on the work of Frank McCown, available online at: http://www.harding.edu/fmccown/resources.html
This work is licensed under a Creative Commons license, available online at: http://creativecommons.org/licenses/by-sa/2.0/

C# VB.NET (v2) Java (v5)


PROGRAM STRUCTURE
using System;

namespace Hello Imports System


{
public class HelloWorld Namespace Hello package hello;
{ Class HelloWorld
public static void Main(string[] args) Overloads Shared Sub Main(ByVal args() _ public class HelloWorld {
{ As String) public static void main(String[] args) {
string name = "C#"; Dim name As String = "VB.NET" String name = "Java";

// See if an argument was passed from ' See if an argument was passed from the // See if an argument was passed from the
the ' command line // command line
// command line If args.Length = 1 Then name = args(0) if (args.length == 1)
if (args.Length == 1) name = args[0];
name = args[0]; Console.WriteLine("Hello, " & name & System.out.println("Hello, " + name
"!") +
Console.WriteLine("Hello, " + name + End Sub "!");
"!"); End Class }
} End Namespace }
}
}

COMMENTS
// Single line Single line only // Single line
/* Multiple ''' <summary>XML comments</summary> /* Multiple
line */ line */
/// <summary>XML comments on single /** Javadoc documentation comments */
line</summary>
/** <summary>XML comments on multiple
lines</summary> */

© CTI Education Group


Language Comparison Page 308

C# VB.NET (v2) Java (v5)


DATA TYPES
// Value Types ’ Value Types // Primitive Types
bool Boolean boolean
byte, sbyte Byte, SByte byte
char Char char
short, ushort, int, uint, long, ulong Short, UShort, Integer, UInteger, Long, ULong short, int, long
float, double, decimal Double, Decimal float, double
structures, enumerations structures, enumerations

// Reference Types ’ Reference Types // Reference Types


object // superclass of all other classes Object ’ superclass of all other classes Object // superclass of all other classes
string String String
arrays, classes, interfaces, delegates arrays, classes, interfaces, delegates arrays, classes, interfaces

// Conversions ’ Conversions // Conversions


// int to string ’ Integer to String // int to String
int x = 123; Dim x As Integer = 123 int x = 123;
String y = x.ToString(); // y is "123" Dim y As String = x.ToString() ’ y is "123" String y = Integer.toString(x); // y is "123"
// string to int ’ string to Integer // String to int
y = "456"; y = "456" y = "456";
x = Int32.Parse(y); x = Int32.Parse(y) x = Integer.parseInt(y); // x is 456

// double to int ’ Double to Integer // double to int


double z = 3.5; Dim z As Double = 3.5 double z = 3.5;
x = (int) z; // x is 3 (truncates decimal) x = CType(z, Integer) ‘ x is 3 (truncates x = (int) z; // x is 3 (truncates decimal)
decimal)

CONSTANTS
const double PI = 3.14; Const MAX_STUDENTS As Integer = 25 // May be initialized in a constructor
// Can be set to a const or a variable. May be ’ Can set to a const or variable; may be final double PI = 3.14;
// initialized in a constructor. initialized
readonly int MAX_HEIGHT = 9; ’ in a constructor
ReadOnly MIN_DIAMETER As Single = 4.93

© CTI Education Group


Language Comparison Page 309

C# VB.NET (v2) Java (v5)


ENUMERATIONS
enum Action {Start, Stop, Rewind, Forward}; Enum Action enum Action {Start, Stop, Rewind, Forward};
enum Status {Flunk = 50, Pass = 70, Excel = 90}; Start // Special type of class
// No equivalent [Stop] ' Stop is a reserved word enum Status {
Rewind Flunk(50), Pass(70), Excel(90);
Action a = Action.Stop; Forward private final int value;
if (a != Action.Start) End Enum Status(int value) { this.value = value; }
{ public int value() { return value; }};
Console.WriteLine(a); // Prints Enum Status
"Stop" Flunk = 50 Action a = Action.Stop;
} Pass = 70 if (a != Action.Start)
Status s = Status.Pass; Excel = 90 System.out.println(a); // Prints "Stop"
Console.WriteLine((int) s); // Prints "70" End Enum
Status s = Status.Pass;
Dim a As Action = Action.Stop System.out.println(s.value()); // Prints "70"
If a <> Action.Start Then _
' Prints "Stop is 1"
Console.WriteLine(a.ToString & " is " & a)
'Prints 70
Console.WriteLine(Status.Pass)
' Prints Pass
Console.WriteLine(Status.Pass.ToString())
OPERATORS
// Comparison ’ Comparison // Comparison
== < > <= >= != = < > <= >= <> == < > <= >= !=
// Arithmetic ‘ Arithmetic // Arithmetic
+ - * / + - * / + - * /
% // (mod) Mod % // (mod)
/ // (integer division if both operands are \ ’ (Integer division) /// (integer division if both operands are
ints) ^ ’ (raise to a power) ints)
Math.Pow(x, y) Math.Pow(x, y)
’ Assignment
// Assignment = += -= *= /= \= ^= <<= >>= &= // Assignment
= += -= *= /= %= &= |= ^= <<= >>= ++ = += -= *= /= %= &= |= ^= <<= >>=
-- ’ Bitwise >>>= ++ --
And Or Xor Not << >> // Bitwise
// Bitwise ’ Logical & | ^ ~ << >> >>>
& | ^ ~ << >> AndAlso OrElse And Or Xor Not // Logical
// Logical ’ Note: AndAlso and OrElse perform short-circuit && || & | ^ !
&& || & | ^ ! ’ logical evaluations Note: && and || perform short-circuit logical
Note: && and || perform short-circuit logical ’ String Concatenation evaluations
evaluations & // String Concatenation
// String Concatenation +
+

© CTI Education Group


Language Comparison Page 310

C# VB.NET (v2) Java (v5)

CHOICES
greeting = age < 20 ? "What's up?" : "Hello"; greeting = IIf(age < 20, "What's up?", "Hello") greeting = age < 20 ? "What's up?" : "Hello";
if (x < y) If(x < y) Then if (x < y) {
{ Console.WriteLine(“greater”) System.out.println("greater");
Console.WriteLine("greater"); EndIf }
}
if (x != 100) If(Not(X = 100)) Then if (x != 100) {
{ X *= 2 x *= 5;
x *= 5; y *= 2 y *= 2;
y *= 2; Else }
} Z *= 6 else
else EndIf z *= 6;
z *= 6; int selection = 2;

string colour = "red"; Dim colour As String = “red” // Must be byte, short, int, char, or enum
switch (colour) Select (colour) switch (selection) {
{ Case “red”: // Falls through to next case if no break
// break is mandatory; no fall-through r++ case 1: x++;
case "red": r++; break; Case “green”: case 2: y++; break;
case "blue": b++; break; g++ case 3: z++; break;
case "green": g++; break; Case Else: default: other++;
// break necessary on default other++ }
default: other++; break; End Select
}

ARRAYS
int[] nums = {1, 2, 3}; Dim nums As Integer() = {1, 2, 3} int nums[] = {1, 2, 3}; or int[] nums = {1,
for (int i = 0; i < nums.Length; i++) Dim i As Integer 2, 3};
Console.WriteLine(nums[i]); For i = 0 To Nums.Length for (int i = 0; i < nums.length; i++)
Console.WriteLine(nums[i]) System.out.println(nums[i]);
string[] names = new string[5]; Next String names[] = new String[5];
names[0] = "David"; Dim names(5) As String names[0] = "David";
names(0) = "David" float twoD[][] = new float[rows][cols];
float[,] twoD = new float[rows, cols]; Dim twoD(rows-1, cols-1) As Single twoD[2][0] = 4.5;
twoD[2,0] = 4.5f; twoD(2, 0) = 4.5 int[][] jagged = new int[5][];
int[][] jagged = new int[3][] { Dim jagged()() As Integer = { _ jagged[0] = new int[5];
new int[5], new int[2], new int[3] }; New Integer(4) {}, New Integer(1) {}, _ jagged[1] = new int[2];
jagged[0][4] = 5; New Integer(2) {} } jagged[2] = new int[3];
jagged(0)(4) = 5 jagged[0][4] = 5;

© CTI Education Group


Language Comparison Page 311

C# VB.NET (v2) Java (v5)

LOOPS
while (i < 10) While (i < 10) while (i < 10)
{ i = i + 1 {
i++; End While i++;
} }
For i = 2 To 10 Step 2
for (i = 2; i <= 10; i += 2) Console.WriteLine(i) for (i = 2; i <= 10; i += 2)
{ Next {
Console.WriteLine(i); Console.WriteLine(i);
} Do While(i < 10) }
i = i + 1
do Loop do
{ {
i++; i++;
} }
while (i < 10); while (i < 10);

// foreach can be used to iterate through any ’ For Each can be used to iterate through any // foreach can be used to iterate through any
collection ’ collection collection
foreach (int i in numArray) For Each i As Integer in numArray foreach (int i in numArray)
{ sum += i {
sum += i; Next sum += i;
} }

using System.Collections;. Dim list As ArrayList = new ArrayList() using System.Collections;


ArrayList list = new ArrayList(); list.Add(10) ArrayList list = new ArrayList();
list.Add(10); list.Add("Bisons") list.Add(10);
list.Add("Bisons"); list.Add(2.3) list.Add("Bisons");
list.Add(2.3); list.Add(2.3);
For Each o As Object In list
foreach (Object o in list) Console.WriteLine(o); foreach (Object o in list)
{ Next {
Console.WriteLine(o); Console.WriteLine(o);
} }

© CTI Education Group


Language Comparison Page 312

C# VB.NET (v2) Java (v5)

FUNCTIONS
// Return single value ’ Return single value // Return single value
int Add(int x, int y) Function Add(ByVal x As Integer, _ int Add(int x, int y) {
{ ByVal y As Integer) As Integer return x + y;
return x + y; return x + y }
} End Function int sum = Add(2, 3);
int sum = Add(2, 3); Dim sum As Integer = Add(2, 3)

// Return no value ’ Return no value // Return no value


void PrintSum(int x, int y) Sub PrintSum(ByVal x As Integer, ByVal y As void PrintSum(int x, int y) {
{ Integer) System.out.println(x + y);
Console.WriteLine(x + y); Console.WriteLine(x + y) }
} End Function PrintSum(2, 3);
PrintSum(2, 3);
PrintSum(2, 3)

EXCEPTION HANDLING
’ Throw an exception // Must be in a method that is declared to
Exception up = new Exception("Something is really Dim ex As New _ throw
wrong."); Exception("Something is really wrong.") // this exception
throw ex; Throw ex Exception ex = new Exception("Something is
' Catch an exception really
try Try wrong.");
{ y = 0 throw ex;
y = 0; x = 10 / y try {
x = 10 / y; ' Argument and When is optional y = 0;
} Catch ex As Exception When y = 0 x = 10 / y;
catch (Exception ex) // Variable "ex" is } catch (Exception ex) {
{ // optional Console.WriteLine(ex.Message) System.out.println(ex.getMessage());
Console.WriteLine(ex.Message); Finally } finally {
} Beep() // Code that always gets executed
finally End Try }
{
// Code that always gets executed
}

© CTI Education Group


Language Comparison Page 313

C# VB.NET (v2) Java (v5)

STRINGS
// String concatenation ’ String concatenation // String concatenation
string school = "Harding "; Dim school As String = "Harding " String school = "Harding ";

// school is "Harding University" ’ school is "Harding University" // school is "Harding University"


school = school + "University"; school = school & "University" school = school + "University";

// String comparison ’ String comparison // String comparison


string mascot = "Bisons"; string mascot = "Bisons"; String mascot = "Bisons";
if (mascot == "Bisons") // true If (mascot = "Bisons") Then ’ true if (mascot == "Bisons") // incorrect method
if (mascot.Equals("Bisons")) // true If (mascot.Equals("Bisons")) Then ’ true if (mascot.equals("Bisons")) // true
if (mascot.ToUpper().Equals("BISONS")) // true If (mascot.ToUpper().Equals("BISONS")) Then’ true if (mascot.equalsIgnoreCase("BISONS")) //
if (mascot.CompareTo("Bisons") == 0) // true If (mascot.CompareTo("Bisons") == 0) Then ’ true true
if (mascot.compareTo("Bisons") == 0) // true
// Prints "son" ’ Prints "son"
Console.WriteLine(mascot.Substring(2, 3)); Console.WriteLine(mascot.Substring(2, 3)) // Prints "son"
System.out.println(mascot.substring(2, 3));

NAMESPACES
namespace CTIGroup.CTI.HO Namespace CTIGroup.Cti.HO package CTIGroup.CTI.HO;
{ ...
... End Namespace
} ' or
or Namespace Harding
namespace CTIGroup Namespace Compsci
{ Namespace Graphics
namespace CTI ... // Import single class
{ End Namespace import CTIGroup.CTI.HO.Table;
namespace HO End Namespace // Import all classes
{ End Namespace import CTIGroup.CTI.HO.*;
... Imports CTIGroup.CTI.HO

}
}
// Import all class. Can't import single class.
using CTIGroup.CTI.HO;

© CTI Education Group


Language Comparison Page 314

C# VB.NET (v2) Java (v5)

CLASSES / INTERFACES
Accessibility keywords Accessibility keywords Accessibility keywords
public Public public
private Private private
internal Friend protected
protected Protected static
protected internal Protected Friend
static Shared

// Inheritance ' Inheritance // Inheritance


class FootballGame : Competition Class FootballGame class FootballGame extends Competition {
{ Inherits Competition ...
... ... }
} End Class

// Interface definition ' Interface definition // Interface definition


interface IAlarmClock Interface IAlarmClock interface IAlarmClock {
{ ... ...
... End Interface }
}

// Extending an interface ’ Extending an interface // Extending an interface


interface IAlarmClock : IClock Interface IAlarmClock interface IAlarmClock extends IClock {
{ Inherits IClock ...
... ... }
} End Interface

// Interface implementation ’ Interface implementation // Interface implementation


class WristWatch : IAlarmClock, ITimer Class WristWatch class WristWatch implements IAlarmClock, ITimer
{ Implements IAlarmClock, ITimer {
... ... ...
} End Class }

© CTI Education Group


Language Comparison Page 315

C# VB.NET (v2) Java (v5)

CONSTRUCTORS / DESTRUCTORS
class SuperHero Class SuperHero class SuperHero {
{ Private _powerLevel As Integer private int mPowerLevel;
private int mPowerLevel; public SuperHero() {
Public Sub New() mPowerLevel = 0;
public SuperHero() _powerLevel = 0 }
{ End Sub
mPowerLevel = 0;
}

public SuperHero(int powerLevel) Public Sub New(ByVal powerLevel As Integer) public SuperHero(int powerLevel) {
{ Me._powerLevel = powerLevel this.mPowerLevel= powerLevel;
this.mPowerLevel= powerLevel; End Sub }
} // No destructors, just override the finalize
Protected Overrides Sub Finalize() // method
~SuperHero() ' Destructor code to free unmanaged resources protected void finalize() throws Throwable {
{ MyBase.Finalize() // Always call parent's finalizer
// Destructor code to free unmanaged End Sub super.finalize();
resources. End Class }
// Implicitly creates a Finalize method. }
}

CONSOLE I/O
Console.Write("What's your name? "); Console.Write("What's your name? ") System.out.print("What's your name? ");
string name = Console.ReadLine(); Dim name As String = Console.ReadLine() string name = in.readline();
Console.Write("How old are you? "); Console.Write("How old are you? ") System.out.print("How old are you? ");
int age = Convert.ToInt32(Console.ReadLine()); Dim age As Integer = Val(Console.ReadLine()) int age = Integer.parseInt(in.readline());
Console.WriteLine(name + " is " + age + Console.WriteLine("{0} is {1} years old.", name, System.out.println(name + “ is “ + age + “
" years old."); _ years
age) old”);
int c = Console.Read(); // Read single char ' or
Console.WriteLine(c); // Prints 65 if user Console.WriteLine(name & " is " & age & _ int c;
// enters "A" " years old.") c = in.read();
System.out.println(in);
Dim c As Integer
c = Console.Read() ' Read single char
Console.WriteLine(c) ' Prints 65 if user enters
"A"

© CTI Education Group


Language Comparison Page 316

C# VB.NET (v2) Java (v5)

USING OBJECTS
Dim hero As SuperHero = New SuperHero
' or
SuperHero hero = new SuperHero(); Dim hero As New SuperHero
With hero SuperHero hero = new SuperHero();
hero.Name = "SpamMan"; .Name = "SpamMan" hero.setName("SpamMan");
hero.PowerLevel = 3; .PowerLevel = 3 hero.setPowerLevel(3);
hero.Defend("Laura Jones"); End With
SuperHero.Rest(); // Calling static method hero.Defend("Laura Jones") hero.Defend("Laura Jones");
hero.Rest() ' Calling Shared method SuperHero.Rest(); // Calling static method
// Both refer to same object ' or
SuperHero hero2 = hero; SuperHero.Rest() // Both refer to same object
' Both reference the same object SuperHero hero2 = hero;
hero2.Name = "WormWoman"; Dim hero2 As SuperHero = hero hero2.setName("WormWoman");
hero2.Name = "WormWoman"
// Prints WormWoman ' Prints WormWoman // Prints WormWoman
Console.WriteLine(hero.Name); Console.WriteLine(hero.Name) System.out.println(hero.getName());

// Free the object ' Free the object // Free the object
hero = null ; hero = Nothing hero = null;
If hero Is Nothing Then _ if (hero == null)
if (hero == null) hero = New SuperHero {
{ Dim obj As Object = New SuperHero hero = new SuperHero();
hero = new SuperHero(); If TypeOf obj Is SuperHero Then _ }
} Console.WriteLine("Is a SuperHero object.")
Object obj = new SuperHero();
Object obj = new SuperHero(); Using reader As StreamReader = _ System.out.println("object's type: " +
Console.WriteLine("object's type: " + File.OpenText("test.txt") obj.getClass().toString());
obj.GetType().ToString());
Dim line As String = reader.ReadLine() if (obj instanceof SuperHero)
if (obj is SuperHero) While Not line Is Nothing {
{ Console.WriteLine(line) System.out.println("Is a SuperHero object.");
line = reader.ReadLine() }
Console.WriteLine("Is a SuperHero object."); End While
} End Using

© CTI Education Group


Language Comparison Page 317

C# VB.NET (v2) Java (v5)

PROPERTIES
private int mSize; Private mSize As Integer private int mSize;
public int Size { Public Property Size() As Integer public int getSize() { return mSize; }
get Get public void setSize(int value) {
{ Return mSize if (value < 0)
return mSize; End Get mSize = 0;
} else
set Set mSize = value;
{ If (value < 0) Then }
if (value < 0) mSize = 0
{ Else int s = shoe.getSize();
mSize = 0; mSize = value shoe.setSize(s+1);
} End If
else End Set
{ End Property
mSize = value;
} shoe.Size = shoe.Size + 1;
}
}
shoe.Size++;

STRUCTS
No structs in Java.
struct StudentRecord Structure StudentRecord
{ Public name As String
public string name; Public gpa As Single
public float gpa;
Public Sub New(ByVal name As String, _
public StudentRecord(string name, float gpa) ByVal gpa As Single)
{ Me.name = name
this.name = name; Me.gpa = gpa
this.gpa = gpa; End Sub
} End Structure
} Dim stu As StudentRecord = _
New StudentRecord("Bob", 3.5)
StudentRecord stu = new StudentRecord("Bob",
3.5f); Dim stu2 As StudentRecord = stu
StudentRecord stu2 = stu;
stu2.name = "Sue"
stu2.name = "Sue"; Console.WriteLine(stu.name) ' Prints Bob
Console.WriteLine(stu.name); // Prints Bob Console.WriteLine(stu2.name) ' Prints Sue
Console.WriteLine(stu2.name); // Prints Sue

© CTI Education Group


Language Comparison Page 318

C# VB.NET (v2) Java (v5)

FILE I/O
using System.IO; Imports System.IO import java.io.*;

// Character stream writing ' Write out to text file // Character stream writing
StreamWriter writer = Dim writer As StreamWriter = FileWriter writer = new
File.CreateText("myfile.txt"); File.CreateText("myfile.txt") FileWriter("myfile.txt");
writer.WriteLine("Out to file."); writer.WriteLine("Out to file.") writer.write("Out to file.\n");
writer.Close(); writer.Close() writer.close();

' Read all lines from text file


// Character stream reading Dim reader As StreamReader = // Character stream reading
StreamReader reader = File.OpenText("myfile.txt") FileReader reader = new
File.OpenText("myfile.txt"); Dim line As String = reader.ReadLine() FileReader("myfile.txt");
string line = reader.ReadLine(); While Not line Is Nothing BufferedReader br = new BufferedReader(reader);
while (line != null) Console.WriteLine(line) String line = br.readLine();
{ line = reader.ReadLine() while (line != null)
Console.WriteLine(line); End While {
line = reader.ReadLine(); reader.Close() System.out.println(line);
} line = br.readLine();
reader.Close in (); }
' Write out to binary file reader.close();
Dim str As String = "Text data"
// Binary stream writing Dim num As Integer = 123 // Binary stream writing
BinaryWriter out = new Dim binWriter As New FileOutputStream out = new
BinaryWriter(File.OpenWrite("myfile.dat")); BinaryWriter(File.OpenWrite("myfile.dat")) FileOutputStream("myfile.dat");
out.Write("Text data"); binWriter.Write(str) out.write("Text data".getBytes());
out.Write(123); binWriter.Write(num) out.write(123);
out.Close(); binWriter.Close() out.close();

' Read from binary file


Dim binReader As New
// Binary stream reading BinaryReader(File.OpenRead("myfile.dat")) // Binary stream reading
BinaryReader in = new str = binReader.ReadString() FileInputStream in = new
BinaryReader(File.OpenRead("myfile.dat")); num = binReader.ReadInt32() FileInputStream("myfile.dat");
string s = in.ReadString(); binReader.Close() byte buff[] = new byte[9];
int num = in.ReadInt32(); // Read first 9 bytes into buff
in.Close(); in.read(buff, 0, 9);
String s = new String(buff);
int num = in.read(); // Next is 123
in.close();

© CTI Education Group


Bibliography Page 319

Bibliography

Books

1. Michaelis, M., Essential C# 3.0: For .NET Framework 3.5. ISBN: 978-0-321-53392-0

2. Foxall, J, Sams Teach Yourself Visual C# 2008 in 24 Hours. ISBN: 978-0-672-32990-6

3. Mayo, J. 2002, C# Unleashed. ISBN: 0-672-32122-X

4. Deitel, PJ, Deitel, HM., C# 2008 Programmers Third Edition. ISBN: 978-0-13-714415-0

Websites

1. http://www.msdn.microsoft.com/ : Microsoft Developer Network (MSDN)

2. http://www.blackwasp.co.uk : Blackwasp

3. http://www.akadia.com/ : Akadia

4. http://www.developerfusion.co.uk/ : Developer Fusion

5. http://www.ondotnet.com/ : OnDotNet

© CTI Education Group


Bibliography Page 320

© CTI Education Group


C# – Exercise Checklist Page 321

Advanced C# Programming – Exercise Checklist


CSPBC-09 V1.5

Learner: Start date:


____________________________________________ ________________
Learners please note that unless all of your exercises have been signed off by an instructor
you will not be allowed to book for the exam.

DATE SIGN DATE SIGN DATE SIGN

4.1.2 Windows User Control Exercises 4.3.3 Deploying a Windows Application 4.5.7 Attributes Revision questions
(Page 18) Revision questions (Page 34) continue… (Page 45)
(Complete exercise on paper) (Complete exercise on paper) (Complete exercise on paper)

1 _________ ________ 1 _________ ________ 2 _________ ________

2 _________ ________ 2 _________ ________ 3 _________ ________


4.1.3 Windows User Control Revision 3 _________ ________ 4.6.4 Reflection Exercises (Page 50)
questions (Page 18) (Complete exercise on paper)
(Complete exercise on paper)
4.4.2 Maintaining and Supporting a
Windows Application Exercises (Page 39) 1 _________ ________
1 _________ ________ (Complete exercise on paper)

2 _________ ________
2 _________ ________ 1 _________ ________
4.6.5 Reflection Revision questions (Page
3 _________ ________ 2 _________ ________ 50)
(Complete exercise on paper)
4 _________ ________ 3 _________ ________
1 _________ ________
4.2.6 DateTime data type Exercises (Page 4.4.3 Maintaining and Supporting a
24) Windows Application Revision questions 2 _________ ________
(Complete exercise on paper) (Page 39)
(Complete exercise on paper)
4.7.7 File I/O Exercises (Page 61)
1 _________ ________ (Complete exercise on paper)
1 _________ ________
2 _________ ________ 1 _________ ________
2 _________ ________
4.2.6 DateTime data type Revision 2 _________ ________
questions (Page 24) 3 _________ ________
(Complete exercise on paper)
4.5.6 Attributes Exercises (Page 45)
3 _________ ________
1 _________ ________ (Complete exercise on paper)
4 _________ ________
2 _________ ________ 1 _________ ________
5 _________ ________
3 _________ ________ 2 _________ ________
4.7.8 File I/O Revision questions (Page 62)
(Complete exercise on paper)
4.3.2 Deploying a Windows Application 3 _________ ________
Exercises (Page 34)
(Complete exercise on paper)
4.5.7 Attributes Revision questions (Page
1 _________ ________
45)
1 _________ ________ (Complete exercise on paper) 2 _________ ________

2 _________ ________ 1 _________ ________ 3 _________ ________

© CTI Education Group


C# – Exercise Checklist Page 322

DATE SIGN DATE SIGN DATE SIGN

4.7.8 File I/O Revision questions Unit 4 – Test your knowledge Multiple 5.2.3 Microsoft Visual Web Developer
continue… (Page 62) choice continue… (Page 88) Express Edition IDE Exercises continue…
(Complete exercise on paper) (Complete exercise on paper) (Page 105)
(Complete exercise on paper)
4 _________ ________ 1 _________ ________
3 _________ ________
4.8.13 ADO.NET Exercises (Page 88) 2 _________ ________
(Complete exercise on paper) 5.2.8 Microsoft Visual Web Developer
Express Edition IDE Revision questions
3 _________ ________ (Page 105)
1 _________ ________ (Complete exercise on paper)
4 _________ ________
2 _________ ________ 1 _________ ________
5 _________ ________
3 _________ ________ 2 _________ ________
Unit 4 – Test your knowledge Multiple
4 _________ ________ response (Page 90) 3 _________ ________
(Complete exercise on paper)
5 _________ ________ 5.3.5 ASP.NET: Events and controls
1 _________ ________ Exercises (Page 125)
(Complete exercise on paper)
6 _________ ________
2 _________ ________
1 _________ ________
7 _________ ________
3 _________ ________
4.8.14 ADO.NET Exercises (Page 88)
2 _________ ________
(Complete exercise on paper) 4 _________ ________
3 _________ ________
1 _________ ________ 5 _________ ________
5.3.6 ASP.NET: Events and controls
Revision questions (Page 125)
2 _________ ________ 5.1.3 ASP.NET Fundamentals Exercises (Complete exercise on paper)
(Page 95)
(Complete exercise on paper)
3 _________ ________ 1 _________ ________
1 _________ ________
4 _________ ________ 2 _________ ________
2 _________ ________
5 _________ ________ 3 _________ ________
Unit 4 – Test your knowledge True/False
3 _________ ________
5.4.4 Validating data: Validation Controls
(Page 88) Exercises (Page 137)
(Complete exercise on paper) 5.1.4 ASP.NET Fundamentals Revision (Complete exercise on paper)
questions (Page 96
(Complete exercise on paper)
1 _________ ________ 1 _________ ________
1 _________ ________
2 _________ ________ 2 _________ ________
2 _________ ________
3 _________ ________ 3 _________ ________
3 _________ ________
4 _________ ________ 5.4.5 Validating data: Validation Controls
Revision questions (Page 137)
5.2.7 Microsoft Visual Web Developer (Complete exercise on paper)
5 _________ ________ Express Edition IDE Exercises (Page 105)
(Complete exercise on paper)
1 _________ ________
Unit 4 – Test your knowledge Multiple
choice (Page 88) 1 _________ ________
(Complete exercise on paper) 2 _________ ________
2 _________ ________
1 _________ ________ 3 _________ ________

© CTI Education Group


C# – Exercise Checklist Page 323

DATE SIGN DATE SIGN DATE SIGN

5.5.5 Data-binding Exercises (Page 148) 5.7.5 ASP.NET Objects Exercises 6.1.6 Introduction Exercises (Page 194)
(Complete exercise on paper) continue… (Page 178) (Complete exercise on paper)
(Complete exercise on paper)
1 _________ ________ 1 _________ ________
3 _________ ________
2 _________ ________ 2 _________ ________
5.8.2 Distributing ASP.NET applications
Exercises (Page 182)
3 _________ ________ (Complete exercise on paper) 3 _________ ________

5.5.6 Data-binding Revision questions 1 _________ ________ 4 _________ ________


(Page 148)
(Complete exercise on paper)
2 _________ ________ 5 _________ ________
1 _________ ________
3 _________ ________ 6.1.7 Introduction Revision questions (Page
194)
2 _________ ________ (Complete exercise on paper)
4 _________ ________
3 _________ ________ 1 _________ ________
5.8.3 Distributing ASP.NET applications
Revision questions (Page 182)
5.6.4 Using databases with ASP.NET 2 _________ ________
(Complete exercise on paper)
Exercises (Page 164)
(Complete exercise on paper)
1 _________ ________ 3 _________ ________
1 _________ ________
2 _________ ________ 4 _________ ________
2 _________ ________
3 _________ ________ 6.2.4 XML data Exercises (Page 220)
(Complete exercise on paper)
3 _________ ________
Unit 5 – Test your knowledge Multiple
choice (Page 183) 1 _________ ________
5.6.5 Using databases with ASP.NET
(Complete exercise on paper)
Revision questions (Page 164)
(Complete exercise on paper) 2 _________ ________
1 _________ ________
1 _________ ________ 3 _________ ________
2 _________ ________
2 _________ ________ 4 _________ ________
3 _________ ________
3 _________ ________ 5 _________ ________
4 _________ ________
5.7.4 ASP.NET Objects Exercises (Page 6.2.5 XML data Revision questions (Page
177) 220)
(Complete exercise on paper)
5 _________ ________ (Complete exercise on paper)

Unit 5 – Test your knowledge True/False


1 _________ ________ (Page 184) 1 _________ ________
(Complete exercise on paper)
2 _________ ________ 2 _________ ________
1 _________ ________
3 _________ ________ 3 _________ ________
2 _________ ________
5.7.5 ASP.NET Objects Exercises (Page 4 _________ ________
178) Unit 5 – Test your knowledge Multiple
(Complete exercise on paper) response (Page 184)
6.3.7 .NET Remoting Exercises (Page 238)
(Complete exercise on paper)
(Complete exercise on paper)
1 _________ ________
1 _________ ________ 1 _________ ________
2 _________ ________
2 _________ ________

© CTI Education Group


C# – Exercise Checklist Page 324

DATE SIGN DATE SIGN DATE SIGN

6.3.7 .NET Remoting Exercises continue… 6.4.6 Web Services Exercises (Page 252) Unit 6 – Test your knowledge Multiple
(Page 238) (Complete exercise on paper) choice (Page 261)
(Complete exercise on paper) (Complete exercise on paper)
1 _________ ________
2 _________ ________ 1 _________ ________
2 _________ ________
3 _________ ________ 2 _________ ________
6.4.7 Web Services Revision questions
4 _________ ________ (Page 252) 3 _________ ________
(Complete exercise on paper)

5 _________ ________ 4 _________ ________


1 _________ ________
6 _________ ________ Unit 6 – Test your knowledge True/False
5 _________ ________
(Page 261)
6.3.8 .NET Remoting Revision questions (Complete exercise on paper)
(Page 238)
(Complete exercise on paper)
1 _________ ________
1 _________ ________
2 _________ ________
2 _________ ________

3 _________ ________

4 _________ ________

5 _________ ________

© CTI Education Group


Advanced C# Programming – Evaluation Form
CSPBC-09 V1.5

How would you evaluate the C# study guide? Place a  or  in one of the five squares
that best indicates your choice. Your response will help us to improve the quality of the
study guides and courses, and will be much appreciated.

Very
Poor Fair Good Excellent
poor
The study guide is clear and understandable.
The text material is clear and understandable.
The exercises help you grasp the course material.
The projects help you understand the course material.
You know what to expect in the exam.
The practical exercises test your knowledge and ability.
Your instructor was able to help you.

What did you most enjoy? __________________________________________________

________________________________________________________________________

What did you least enjoy? __________________________________________________

________________________________________________________________________

General comments (what would you add, leave out, etc.).

Please note any errors that you found in the study guide.

Campus: ________________ Instructor: ___________________ Date: _______________

Thank you for completing the evaluation form. Please remove this evaluation form and
return it to your instructor.

© CTI Education Group

You might also like