C# Unit 3

Download as pdf or txt
Download as pdf or txt
You are on page 1of 180

C# and .

NET Framework - Introduction

Syllabus : Diagnostics, Tasks, .Net Security Localization, .NET Localization,


Manipulating Files and the Registry.

Section No. Topic Name Page No.


14.1 Diagnostics and Various Related Tasks 14 - 2
14.2 .NET Security 14 - 8
14.3 .NET Localization and Globalization 14 - 10
14.4 Manipulating the Files and the Registry 14 - 15
Two Marks Questions with Answers 14 - 17
Long Answered Questions 14 - 18

14 - 1 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

14.1 Diagnostics and Various Related Tasks

14.1.1 Introduction

There are various aspects of software application those need to be monitored and improved
over once the application comes in use. In fact, the application can be tested through various
angles while it is in development process as well as after its complete development, so that the
client does not face any issues. Software application may not always behave as expected.
.NET Core provides tools and APIs that helps to diagnose various issues quickly and
effectively.
Following are the benefits of Diagnostic tools,
The ability to monitor performance while debugging.
Correlate performance data with debugging activity.
Richer user experience through IntelliTrace and the Output windows.
Shortening diagnose time to identify and fix an issue.
14.1.2 Types of Tools Used for Diagnostic Tasks

1. Debugger Events : These tools provide access to all Break, Output, and IntelliTrace
events during the debugging. The data is presented both as a timeline and as a tabular
view. Messages that are sent to the Debug tab of the Output window are captured by
IntelliTrace. The post-mortem tools can be used with Windows 7 and later. Windows
8 and later is required to run profiling tools with the debugger (Diagnostic Tools
window).
2. The Memory Usage tools : These tools help developer to monitor the memory usage
of the application during debugging. A developer can analyze memory impact,
growth, and leak issues simply by looking at the graphs. Code break events allow to
identify the parts of the graph that are related to recent debugging activity. Snapshots
can be taken before and after debug actions to analyze memory usage and memory
growth. Developer can look at the number and size of objects on the heap. .NET
Object Allocation tool, helps to identify allocation patterns and anomalies in .NET
code.
3. The CPU Usage tools : These tools track the application's CPU usage while
debugging. The CPU Usage tool is a good place to start analyzing application
performance. It will tell more about CPU resources that application is consuming. A
developer can get a per-function breakdown of CPU usage. To do this go, to Debug -
> Start Diagnostic Tools without Debugging, select CPU Usage, and click Start.

14 - 2 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

To use the tool most effectively, two breakpoints can be set in the code, one at the
beginning and one at the end of the function or the region of code that needs to be analyzed.
The profiling data can be examined when it is paused at the second breakpoint. The CPU
Usage view shows a list of functions ordered by longest running, with the longest running
function at the top. This can help to find out functions where performance bottlenecks are
happening.
Profile release builds without the debugger

Profiling tools like CPU Usage and Memory Usage can be used with the debugger, or
the profiling tools can run post-mortem using the Performance Profiler, which is
intended to provide analysis for Release builds. In the Performance Profiler, the
diagnostic info can be collected while the app is running, and then the collected
information can be examined after the app is stopped.
Examine UI performance and accessibility events (UWP - Universal Windows
Platform)

In UWP applications, UI Analysis can be enabled in the Diagnostic Tools window. The
tool searches for common performance or accessibility issues and displays them in the
Events view while debugging process is on. The event descriptions provide information
that can help to resolve issues.
Analyze resource consumption (XAML - Extensible Application Markup Language)

In XAML applications, such as Windows desktop WPF apps and UWP apps, one can
analyze resource consumption using the Application Timeline tool. For example, the
aspects that can be analyzed are, the time spent by application preparing UI frames
(layout and render), servicing network and disk requests, and in scenarios like
application startup, page load, and Window resize. To use the tool, choose Application
Timeline in the Performance Profiler, and then choose Start. In the application,
scenario should be reviewed with a suspected resource consumption issue, and then
Stop collection can be chosen to generate the report.
Low frame rates in the Visual throughput graph may correspond to visual problems
that can be seen when the application is running. Similarly, high numbers in the
UI thread utilization graph may also correspond to UI responsiveness issues. In the
report, a time period can be selected with a suspected performance issue, and then the
detailed UI thread activities can be examined in the Timeline details view (lower pane).
In the Timeline details view, information such as the type of activity (or the UI element
involved) along with the duration of the activity can be found.

14 - 3 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows
Analyze GPU (Graphics Processing Unit) Usage

In Direct3D applications the activity on the GPU can be examined and performance
issues can be analyzed. To use the tool, GPU Usage can be chosen in the Performance
Profiler, and then Start can be selected. Later after profiling is over Stop collection can
be chosen to generate a report. The graphs can be used to determine whether there are
CPU bound or GPU bound performance bottlenecks.
Analyze performance (legacy tools)

In Visual Studio 2019, the legacy Performance Explorer and related profiling tools such
as the Performance Wizard were folded into the Performance Profiler, which can be
opened using Debug > Performance Profiler. In the Performance Profiler, the
available diagnostics tools depend on the target chosen and the current, open startup
project. The CPU Usage tool provides the sampling capability previously supported in
the Performance Wizard. The Instrumentation tool provides the instrumented profiling
capability (for precise call counts and durations) that was in the Performance Wizard.
Additional memory tools also appear in the Performance Profiler.
14.1.3 System.Diagnostics Namespace

The System.Diagnostics namespace provides classes that allow to interact with system
processes, event logs, and performance counters.
1. The EventLog component provides functionality to write to event logs, read event
log entries, and create and delete event logs and event sources on the network. The
EntryWrittenEventHandler provides a way to interact with event logs
asynchronously. Supporting classes provide access to more detailed control,
including - permission restrictions, the ability to specify event log types (which
controls the type of default data that is written with an event log entry), and iterate
through collections of event log entries. The other related classes those can be used
are EventLogPermission, EventLogEntryType, and EventLogEntryCollection
classes.
2. The Process class provides functionality to monitor system processes across the
network, and to start and stop local system processes. In addition for retrieving lists
of running processes (by specifying either the computer, the process name, or the
process id) or viewing information about the process that currently has access to the
processor, one can get detailed knowledge of process threads and modules both
through the Process class itself, and by interacting with the ProcessThread and
ProcessModule classes. The ProcessStartInfo class enables to specify a variety of

14 - 4 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

elements with which to start a new process, such as input, output, and error streams,
working directories, and command line verbs and arguments. These give a fine
control over the behavior of the processes. Other related classes can be used to
specify window styles, process and thread priorities, and interact with collections of
threads and modules.
3. The PerformanceCounter class enables to monitor system performance, while the
PerformanceCounterCategory class provides a way to create new custom counters
and categories. One can write to local custom counters and read from both local and
remote counters (system as well as custom). One can sample counters using the
PerformanceCounter class, and calculate results from successive performance
counter samples using the CounterSample class. The CounterCreationData class
enables to create multiple counters in a category and specify their types. Other
classes associated with the performance counter component provide access to
collections of counters, counter permission, and counter types.
The System.Diagnostics namespace also provides classes that allow to debug application
and to trace the execution of the code.
System.Diagnostics.Debug class

This class is the most popular widely used class that provides a set of methods and
properties that help debug the code. This class cannot be inherited. Following are the
important methods of this class.
Assert : Overloaded. Checks for a condition and displays a message if the condition is
false
Write/WriteLine : Writes information about the debug to the trace listeners in the
Listeners collection
WriteIf/WriteLineIf : Writes information about the debug to the trace listeners in the
Listeners collection if a condition is true.
System.Diagnostics.Trace class

This class provides a set of methods and properties that help to trace the execution of the
code. The properties and methods can be used in the Trace class to instrument the release
builds. Instrumentation allows the monitoring of the health of the application running in real-
life settings. Members of this class are almost similar to the Debug class.

14 - 5 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows
System.Diagnostics.StackTrace & System.Diagnostics.StackFrame classes

These classes expose the stack information about the routines.


Following example will return the name of the calling method.

System.Diagnostics.SymbolStore class

The System.Diagnostics.SymbolStore namespace provides classes that allow to read and


write debug symbol information, such as source line to Microsoft intermediate language
(MSIL) maps. Compilers targeting the .NET Framework can store the debug symbol
information into programmer's database (PDB) files. Debuggers and code profiler tools can
read the debug symbol information at run time.
Summary of Members of System.Diagnostics Namespace

Class Description

class BooleanSwitch Provides a simple on/off switch that controls


debugging and tracing output.

class ConditionalAttribute Indicates to compilers that a method is callable if


a specified preprocessing identifier is applied to
the method.

class Debug Provides a set of methods and properties that help


debug the code. This class cannot be inherited.

class DebuggableAttribute Modifies code generation for runtime just-in-time


(JIT) debugging. This class cannot be inherited.

class Debugger Enables communication with a debugger. This


class cannot be inherited.

class DebuggerHiddenAttribute Specifies the DebuggerHiddenAttribute. This


class cannot be inherited.

class DebuggerStepThroughAttribute Specifies the DebuggerStepThroughAttribute.


This class cannot be inherited.

14 - 6 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

class DefaultTraceListener Provides the default output methods and behavior


for tracing.

class DiagnosticsConfigurationHandler This type supports the .NET Framework


infrastructure and is not intended to be used
directly from the code.

class Process Provides access to local and remote processes and


enables to start and stop local system processes.

class ProcessStartInfo Specifies a set of values used when starting a


process.

class StackFrame Provides information about a StackFrame.

class StackTrace Acquires a stack trace.

class Switch Provides an base class to create new debugging


and tracing switches.

class TextWriterTraceListener Directs tracing or debugging output to a


TextWriter or to a Stream, such as Console.Out or
FileStream.

class Trace Provides a set of methods and properties that help


to trace the execution of the code. This class
cannot be inherited.

class TraceListener Provides the base class for the listeners who
monitor trace and debug output.

class TraceListenerCollection Provides a thread-safe list of TraceListener


objects.

class TraceSwitch Provides a multilevel switch to control tracing


and debug output without recompiling the code.

Enumerations

Enumeration Description

enumeration TraceLevel Specifies what messages to output for the Debug, Trace and
TraceSwitch classes.

14 - 7 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows
14.1.4 Some Popular .NET Diagnostics Tools
Managed debuggers

Managed debuggers allows to interact with the program. Pausing, incrementally executing,
examining, and resuming gives insight into the behavior of code. A debugger is the first
choice for diagnosing functional problems that can be easily reproduced.
Logging and tracing

Logging and tracing are related techniques. They refer to instrument the code to create log
files. The files record the details of what a program does. These details can be used to
diagnose the most complex problems. When combined with time stamps, these techniques are
also valuable in performance investigations.
Unit testing

Unit testing is a key component of continuous integration and deployment of high-quality


software. Unit tests are designed so as to track an early warning while the breaks are used.
.NET Core diagnostic - Global Tools
dotnet-counters

dotnet-counters is a performance monitoring tool for first-level health monitoring and


performance investigation. It observes performance counter values published via the
EventCounter API. For example, things like the CPU usage or the rate of exceptions being
thrown in .NET Core application can be quickly monitored.
dotnet-dump

The dotnet-dump tool is a way to collect and analyze Windows and Linux core dumps
without a native debugger.
dotnet-trace
.NET Core includes what is called the EventPipe through which diagnostics data is
exposed. The dotnet-trace tool allows to consume useful profiling data from application that
can help in scenarios where one needs to root cause applications running slow.

14.2 .NET Security


Concept

1. Security model : When some action is performed on the user interface, such as click a
button, the application connects to the internet, downloads the modules into the Download

14 - 8 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

Assembly Cache, and begins executing. Behind the scenes, what proof/evidence exists
that one can trust the code, the computer is downloading ?
Explanation
.NET enforces security polices around assemblies. It uses the evidence that an assembly
has, such as the origination of the file. The runtime places all code from the local intranet
into a specific group. It then uses the security policies to decide what permissions the code
should be granted at a granular level.
2. Code access security also known as evidence-based security : The CLR examines the
evidence associated with the code to determine which security policy group the code
belongs to. The CLR then checks what permission set is associated with that code group.
If the code group has the permissions demanded, the request is granted; if not, an
exception is thrown.
3. Code Groups : Code identity permissions are used to define a security policy code group
which groups the related entities. The evidence provided by an assembly is used as the
condition for granting and revoking permissions to it. It is done by putting the code in an
appropriate code group. Every code group stipulates a membership condition and has
specific conditions attached to it. Any assemblies that meet the condition become a
member of the group.
4. Evidence : In order for the CLR to determine which code group to place assembly
information into, the first step is to read supplied evidence. There are two main sources
internet and intranet from where the information is collected. The group internet defines
code that is sources from the internet and the group intranet defines code sources from a
LAN.
Some of the major type of evidence are listed below.
Evidence Description

Zone The region such as intranet, local, trusted from which the code originated.

URL The specific URL from which the code originated.

Strong
Unique verifiable name for the code.
Name

Site The website from which the code originated.

Publisher The assembly digital signature that uniquely identified the developer.

14 - 9 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

5. Permission sets : A permission set is a named set of permissions that can be associated
with a code group. Permissions are the actions that are allowed for each code group to
perform. The system administrator usually manages the permissions at the enterprise,
machine and user levels. Administrators specify which code groups and permission sets
are defined for their system that CLR can use to determine which permissions are allowed
or denied to an assembly.
Some built-in permission sets are,

Nothing : No permissions (cannot run).


Execution : Permission to run, but no permissions that allow use of protected resources.
Everything : All standard (built-in) permissions except permission to skip verification.
This is the only built-in permission set that can be modified.
FullTrust : Full access to all resources protected by permissions that can be unrestricted.
SkipVerification : Bypass all security verification
6. Policy : Security policy is the predefined set of rules that the CLR follows when
determining the permissions to grant to code; the .NET Framework ships with four policy
levels, User, Enterprise and Machine which are as follows,
User Policy : This policy is for individual user and is administered by and for the
current logged in user and evaluated at the time of grant.
Enterprise : This policy is applied for a particular application being used on all the
systems in the enterprise. This policy affects every user and system in the enterprise.
This can define policy for all machines across the system.
Machine : It is indented for single machine and administered by the system
administrator or domain controller. The settings on this level affect only the
applications that run on the local system.
Application domain : It is intended for defining policies for programs/codes running
in a certain application domain.

14.3 .NET Localization and Globalization

.NET Globalization is the process of internationalizing application code, that is culture


neutral and language neutral, and that supports localized user interfaces and regional data for
all users. The executable code is separate from the data specific to the locale. The global
resource can be used with any page in an application. Globalization involves making design
and programming decisions function for multiple cultures that are not based on culture-
specific assumptions. While a globalized application is not localized, it nevertheless is

14 - 10 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

designed and written so that it can be subsequently localized into one or more languages with
relative ease
14.3.1 Concept

Globalization allows the web application to be useful for different people in different parts
of the world who speaks different languages. ASP.Net makes it easy to localize an application
through the use of resource files. Resource files are xml files with .resx extension. Resources
can either be a global resource, in which it is accessible throughout the site and placed in
App_GlobalResources folder in a website or a local resource which is specific to a page only
and is placed in App_LocalResources folder.
Localization is the process of customizing the globalized web application to a specific
locale and culture. Various resources such as images and text for the specific locale are
created. The resource file in localization is scoped to a particular page in an application.
Localization is the process of translating an application's resources into localized versions
for each culture that the application will support. Localization support is possible to
automatically detect the user's culture and to respond to that detection with properly formatted
dates, currency and other numeric values, properly configured controls etc. One should
proceed to the localization step only after completing the Localizability step to verify that the
globalized application is ready for localization.
For each localized version of the application, a new satellite assembly should be added that
contains the localized user interface block translated into the appropriate language for the
target culture. The code block for all cultures should remain the same. The combination of a
localized version of the user interface block with the code block produces a localized version
of the application.
CultureInfo Class ,Provides information about a specific culture . The information
includes the names for the culture, the writing system, the calendar used, and formatting for
dates and sort strings.
14.3.2 Various Resources Required to be Localized/Translated
In a typical ASP.NET application, the following four resources or items may differ
depending on the user’s language and regional preferences and hence need to localized,
1. Text resources – The text that resides in the aspx page. Both asp server tags and
traditional html tags may contain text on an aspx page. This includes the UI text that may
appear in C-Sharp(C#) and Visual Basic code behind files.
All text resources should be externalized to resx files in order to make translation and
maintenance easier. Also known as “resources file”, a resx file consists of XML entries
which specify objects and strings.

14 - 11 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

Visual Studio does provide an automated way to externalize the strings after the page has
been created but this function is limited. It only works on the server tags on aspx pages.
Visual Studio cannot externalize the text in CS/VB code or process regular html tags. The
best approach is to externalize the tags as the pages are being developed.
2. Database content - Most of the translatable text resides in a database for a typical
ASP.NET application particularly in content management systems (product information,
articles etc.).
The database schema and relations will have to be carefully designed to externalize
translatable text to a table(s) which maps to languages and parent tables. Although adding
additional columns to existing tables for each language may seem easier; maintenance of
this solution is extremely difficult and not recommended.
3. Images and graphics - Graphics and images may contain translatable text. If possible, try
avoiding images and graphics with embedded text. Using background images and
retrieving the text from a resource file will make the localization effort much easier. If
that is not possible, point the source of the image to the resx file which will easily change
it depending on the language. This applies to other external assets such as pdf and doc
files as well.
4. Regional options - These items are very straight forward ones likes, Date/time, currency,
number/decimal formatting will vary depending on the user’s region and/or preferences.
As in any other programming language and platform, avoid manually formatting and hard
coding date/time and number formats. .NET offers a CultureInfo class which provides
access to culture-specific instances of objects such as : DateTimeFormatInfo and
NumberFormatInfo. Using these objects, culture-specific operations can be performed
easily such as formatting dates and numbers, casing and comparing strings.
14.3.3 Creating a Global Application and a Local Version of the same
Application

Globalization is the first step in the process. A globalized application supports localized
user interfaces and regional data for all users. Truly global applications should be culture-
neutral and language-neutral. A globalized application can correctly accept, process and
display a worldwide assortment of scripts, data formats and languages. While the globalized
application may possess such flexibility, ensure that the application's resources are separated
that require translation from the rest of the application's code. If application is correctly tested
for localizability before proceeding to the localization step, then there is no need to modify the
application's source code during localization.

14 - 12 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

The steps for creating a local resource file in an ASP.NET application are as shown below,
1) To create a resource file, Open the page for which the resource file is to be created.
2) Add a drop down list control and switch to the design view of the web page
3) At the top of the ASP.NET web application in the Tools menu, click ‘Generate Local
Resources’ option.
4) Visual Studio will automatically create the App_LocalResources folder in the root
folder of the application
5) A neutral base resource file is created for the current page in the application. It
contains a key/value pair for each control property or page property that requires
localization.
6) In the Visual Studio web page, a meta attribute is added for the web server control for
controlling the implicit localization. The UICulture and Culture properties are added
to the <%@Page %> directive.
7) Add the values for each resource that is added in the application and save the
resource file.
Creating resource file for different cultures

The .Net Framework represents different cultures across the world by using the culture
code. The culture code consists of two parts, a two letter language code and an optional
two letter country/region code.
The general code format of the culture code is as shown below,

Following table lists some cultures codes and their description,

Culture Code Description

En It specifies English language, no region

en-CA It specifies English language, Canada region

fr-FR It specifies French language, France region

De It specifies German language, no region

Zh-CN It specifies Chinese region, China region

de-DE It specifies German language, Germany region

14 - 13 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows
14.3.4 System.Globalization Namespace
To implement globalization in an application, include System.Globalization namespace in
the application. The namespace provides classes that define culture related information such
as language, country, calendars and formats.
CutureInfo Class
The class provides information about a specific culture. It includes details as name of the
culture, the formatting styles and calendar used.
The list of properties of CultureInfo class
Property Description

CurrentCulture It returns the instance of the CultureInfo class representing the


culture of the current thread

CurrentUICulture It returns the instance of the CultureInfo class representing the


culture used by the resource manager for the culture specific
resource at runtime

Name It returns the name of the culture in <Language code>-


<Country/Region code> format

IsNeutralCulture
It returns a Boolean value indicating the culture represented by the
CultureInfo object is a neutral culture

NumberFormat
It gets or sets the NumberFormatInfo object that defines the correct
format for displaying numbers, currency, and percentage

The list of methods of CultureInfo class


Methods Description

CreateSpecificCulture It creates a CultureInfo object that represents the


specific culture associated with the specific name

GetCultureInfo It returns the read-only instance of the culture

GetCultures It gets a list of the supported cultures filtered by the


specified type

GetFormat It returns the object that represents the format of the


specified type

14 - 14 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

14.4 Manipulating the Files and the Registry

Microsoft .Net enables to access the Windows Registry programmatically to store and
retrieve data. The Windows Registry is a hierarchical database that has a collection of Keys,
Sub Keys, Predefined Keys, Hives, and Value Entries and can be used to store system specific
or application specific data. As it is said, the registry acts as a central repository of information
for the operating system and the applications on a computer. One can take advantage of the
Windows Registry to store configuration metadata of the applications so that it can be
retrieved a later when required.
The Windows Registry stores the following types of information in a hierarchical manner.
1. User profile information
2. Hardware information of the system
3. Property settings
4. Information of installed programs in the system
Extra care should be taken while manipulating the Windows Registry. It is advisable to
back-up the registry before any changes are made to it so that changes can be reverted back if
required.
The Windows Registry is a hierarchical database for storing many kinds of system and
application settings. Prior to the Registry, .ini files in the form of text files were commonly
used for storing these settings. However, these files were unable to meet all the requirements
of a modern application. Especially in multi-user scenarios the .ini files were nearly useless.
On the other hand, the Windows Registry uses one logical repository that is able to store user-
specific settings.
14.4.1 Structure of the Registry

The Registry is based on the two basic elements, keys and values and the entire structure is
a tree with several root elements that slightly differ depending on the version of Windows
being currently used. The keys are container objects very similar to folders that can contain
other keys or values. The values can be a string, binary, or DWORD depending on the
scenario.
The most common root elements are as follows,
1. HKEY_CLASSES_ROOT : This root element holds the information about
registered (installed) applications and associated file extensions. For example,
Windows is able to open the .docx extension with Microsoft Word because of the
settings in this key. It is not advised to alter these keys manually and the Folder
Options in the Windows Explorer should be used instead.

14 - 15 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

2. HKEY_CURRENT_USER : This root element represents the currently logged-in


user and their specific settings. It is a link to a subkey of HKEY_USERS that
corresponds to the current user. It cannot be edited.
3. HKEY_LOCAL_MACHINE : This root element contains five subkeys (hardware,
security accounts manager, security, software, system) that are used for storing many
kinds of settings used by the operating system. Hardware, security and security
accounts manager subkeys can't be edited. It is not advised to manully alter the rest
as it might result in a system crash.
4. HKEY_USERS : This root element holds complete user profiles used on the
machine. Even though it can be edited, one has to be careful while editing it.
5. HKEY_CURRENT_CONFIG : This root element contains read-only settings about
the available hardware settings. These settings are not permanently stored on disk,
but generated at the boot time and updated at runtime.
14.4.2 Windows Registry and C#

Registry manipulations (store, retrieve and remove) can be done programmatically using
settings in code in C#. The Registry and RegistryKey classes from the Microsoft.Win32
namespace are used for registry manipulations.
Registry class

This class is like a gate keeper and allows to access the root elements. It provides
RegistryKey objects of the root keys and several static methods to access key/value pairs.
RegistryKey class

An instance of this class represents a key-level node in the Registry.


Storing data in the Registry
In order to store any data in the Registry, a subkey of one of the predefined root elements is
to be accessed. This is done by calling the static CreateSubKey method of the Registry class
will return the RegistryKey object to manipulate with it. Later, many values can be stored in
the subkey as needed by calling the SetValue method that takes the 2 arguments, name as a
string and value as an object.

14 - 16 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

Retrieving data from the Registry


To retrieve any data from the Registry, the static OpenSubKey method of the Registry class
is used that returns a RegistryKey instance of the given subkey. If the object is not null (in case
the given subkey doesn't exist), the GetValue method can be used to retrieve the values. This
method takes just one argument, the key name.

Two Marks Questions with Answers

Q.1 What is meant by Globalization and Localization ?


Ans. : Internationalization is the process of designing applications that support multiple
languages. This is divided into Localization and Globalization.
Globalization is nothing but developing applications to support different languages.
Existing applications can also be converted to support multiple cultures.
Whereas Localization means changing the already globalized app to cater to a specific
culture or language Microsoft.Extensions.Localization is used for localizing the app
content. Some of the other keywords that are used for Localization are IHtmlLocalizer,
IStringLocalizer, IViewLocalizer and so on
Q.2 Explain the Code Access Security (CAS) in .NET framework.
Ans. : .NET security model is used to prevent unauthorized access of resources and
operations and also restrict the codes to perform particular tasks. Code Access Security is a
part of that .NET security.
Q.3 How would you ensure that all relevant registry entries were removed in the
event that installation of your application failed ?
Ans. : You can ensure that registry entries are removed, as well as perform any other
"clean-up" tasks, by creating an Installer class and writing the appropriate code in the
Rollback event handler. Then create a new Custom Action and set the InstallerClass, and
EntryPoint properties to appropriate values.

14 - 17 C# and .NET Programming


.NET Diagnostics, .NET Security, .NET Localization,
Manipulating Files and Registry in Windows

Q.4 How to get access to the Windows Registry ?


Ans. : In all Windows operating systems, the Windows Registry is opened and edited using
a tool called the Registry Editor. This tool is built into Windows and works the same in all
modern versions of this operating system: Windows 10, Windows 8.1 and Windows 7.
The fastest way to open the Registry Editor is to use search. In Windows 10, write
"regedit" inside Cortana's search field from your taskbar and then click or tap on the
"regedit" search result.
Q.5 What does the Windows Registry do ?
Ans. : The keys and values from Windows Registry are used by Windows to know what
settings to use for all tools and features, hardware devices and some third-party software
applications.
The Windows Registry database stores settings that control the following :
How the drivers of hardware devices work in Windows
How the operating system settings found in the Settings app or the Control Panel are
configured
Which are the default programs set to open certain file types or protocols
How some of the third-party applications that you installed work, etc.

Long Answered Questions

Q.1 What are various diagnostic tasks in .NET environment ? (Refer section 14.1)
Q.2 How security is dealt in .NET environment ? (Refer section 14.2)
Q.3 Discuss Localization in .NET. (Refer section 14.3)
Q.4 What is Windows registry ? (Refer section 14.4)
Q.5 How Windows registry is manipulated ? (Refer section 14.4)
Q.6 Discuss in detail about security in .Net. (Refer section 14.2)
Q.7 Discuss the Common ASP.NET Security Flaws.
(Refer section 14.2)

.NET Diagnostics, .NET Security, .NET Localization,


Manipulating Files and Registry in Windows ends …

14 - 18 C# and .NET Programming


C# and .NET Framework - Introduction

Syllabus : Threads and Synchronization.

Section Topic Name Page No.


No.
15.1 Processes Tasks and Threads 15 - 2

15.2 Thread Life Cycle 15 - 2

15.3 Working with Threads 15 - 3

15.4 Managing Threads 15 - 14

15.5 Applications and Benefits of Threads 15 - 21

15.6 Thread Communication 15 - 21

Two Marks Questions with Answers 15 - 23

Long Answered Questions 15 - 25

15 - 1 C# and .NET Programming


Threads and Synchronization

15.1 Processes Tasks and Threads

Concept

Multitasking is the ability of an operating system to execute more than one program
simultaneously. Operating system achieves the multitasking through CPU scheduling
algorithm. Operating system uses algorithm to switch the CPU from one program to the next
so quickly that appears as if all of the programs are executing at the same time.
Multithreading is the ability of an operating system to execute the different parts of the
process (A program in execution is called as process.) simultaneously. The program has to
be designed so that it is separated in different sub-parts(threads) and different threads do not
interfere with each other.
A thread is defined as the execution path of a program.
Explanation

C# supports parallel execution of job or program code through multithreading and set of
classes that carry out threading programming.
Each thread defines a unique flow of control.
When application involves complicated and time consuming operations, then it is often
helpful to set different execution paths or threads, with each thread performing a particular
job.
Threads are lightweight processes.
Use of threads saves wastage of CPU cycle and increase efficiency of an application.

15.2 Thread Life Cycle

Concept

The life cycle of a thread starts when an object of the System.Threading.Thread class is
created and ends when the thread is terminated or completes execution.
Explanation

States of the thread


1. The Unstarted State
It is the situation when the instance of the thread is created but the Start method is not
called.
2. The Ready State
It is the situation when the thread is ready to run and waiting for CPU cycle.

15 - 2 C# and .NET Programming


Threads and Synchronization

3. The Not Runnable State


A thread is not executable,
o Sleep method has been called.
o Wait method has been called.
o Blocked by I/O operations.
4. The Dead State
It is the situation when the thread completes execution or is aborted.

Fig. 15.2.1 Threads

15.3 Working with Threads AU : Dec.-19

1. Thread Creation

1. Create a new ThreadStart delegate. The delegate points to a method that will be
executed by the new thread.
2. Pass this delegate as a parameter when creating a new Thread instance.
3. Now, call the Thread.Start method to run the thread method.
4. Syntax
using System.Threading;

Thread thread = new Thread(new ThreadStart(ThreadTaskMethod));


thread.Start();
Example 1
namespace ThreadApps
{
class ThreadCreationOp
{
static void Main(string[] args)
{
/* creating thread start delegate instance which contains the method to execute by
the thread*/

15 - 3 C# and .NET Programming


Threads and Synchronization

ThreadStart ths = new ThreadStart(Show);


// create new thread
Thread tr = new Thread(ths);
// start thread
tr.Start();
// makes the main thread sleep so as to give early chance to Child thread execute
Thread.Sleep(1000);
for (int cnt = 1; cnt<=10; cnt++)
{
Console.WriteLine("Main Thread data value is" + cnt);
Thread.Sleep(1500);
}

Console.WriteLine("Main Thread Finished");


}
// this method executed by a separate thread
static void Show()
{
for (int cnt = 1; cnt < =5; cnt++)
{
Console.WriteLine("Child Thread data value is " + cnt);
Thread.Sleep(500);
}
Console.WriteLine("Child Thread Finished");
}
}
}
Output
Child Thread data value is 1
Child Thread data value is 2
Main Thread data value is 1
Child Thread data value is 3
Child Thread data value is 4
Main Thread data value is 2
Main Thread data value is 3
Child Thread data value is 5
Child Thread Finished
Main Thread data value is 4
Main Thread data value is 5
Main Thread data value is 6
Main Thread data value is 7
Main Thread data value is 8

15 - 4 C# and .NET Programming


Threads and Synchronization

Main Thread data value is 9


Main Thread data value is 10
Main Thread Finished

Example 2
//illustration of operation of thread creation.
using System;
using System.Threading;
namespace ThreadApps
{
class ThreadCreationOp
{
public static void CallChildThread()
{
Console.WriteLine("Child thread starts");
}

static void Main(string[] args)


{
ThreadStart childdlg = new ThreadStart(CallChildThread);
Console.WriteLine("Main Thread : Child thread Creation");
Thread childThe = new Thread(childdlg);
childThread.Start();
}
}
}
Output
Main Thread : Child thread Creation
Child thread starts

Example 3
// Two methods in the same class for creating two threads
Program 1
using System;
using System.Threading;

public class TwoThreads {

public static void Thread1() {


for (int cnt = 1; cnt < =6; cnt ++) {
Console.WriteLine("Thread1 {0}", cnt);
}
}

15 - 5 C# and .NET Programming


Threads and Synchronization

public static void Thread2() {


for (int cnt = 1; i < = 6; cnt ++) {
Console.WriteLine("Thread2 {0}", cnt);
}
}
}

public class ThreadCreation {

public static void Main() {


Console.WriteLine("Before start thread");

Thread thr1 = new Thread(new ThreadStart(TwoThreads.Thread1 ) );


Thread thr2 = new Thread(new ThreadStart(TwoThreads.Thread2 ) );

thr1.Start();
thr2.Start();
}
}
Output
Thread1 1
Thread1 2
Thread2 1
Thread2 2
Thread1 3
Thread1 4
Thread2 3
Thread2 4
Thread1 5
Thread2 5
Thread2 6

Example 4
// One thread method to create two threads by creating two objects of the thread class.
using System;
using System.Threading;

public class TwoThreads {

public static void ThreadTask() {

Console.WriteLine(this.name);
for (int cnt = 1; cnt < =5; cnt ++) {
Console.WriteLine(“Data {0}", cnt);

15 - 6 C# and .NET Programming


Threads and Synchronization

}
}

public class ThreadCreation {

public static void Main() {


Console.WriteLine("Before thread start");

MyThread thr1 = new MyThread();


MyThread thr2 = new MyThread();

Thread td1 = new Thread(new ThreadStart(thr1.ThreadTask) );


Thread td2 = new Thread(new ThreadStart(thr2.ThreadTask) );
td1.name=”Thread 1”;
td2.name=”Thread 2”;
tid1.Start();
tid2.Start();
}
}

Output
Before thread start
Thread 1
Data 1
Data 2
Thread 2
Data 1
Data 2
Thread 1
Data 3
Data 4
Thread 2
Data 3
Data 4
Thread 1
Data 5
Thread 2
Data 5

15 - 7 C# and .NET Programming


Threads and Synchronization

2. Properties of the Thread Class

Property Description

CurrentContext Gets the current context in which the thread is executing.

CurrentCulture Gets or sets the culture for the current thread.

CurrentPrinciple Gets or sets the thread's current principal (for role-based security).

CurrentThread Gets the currently running thread.

CurrentUICulture Gets or sets the current culture used by the Resource Manager to look up
culture-specific resources at run-time.

ExecutionContext Gets an ExecutionContext object that contains information about the


various contexts of the current thread.

IsAlive Gets a value indicating the execution status of the current thread.

IsBackground Gets or sets a value indicating whether or not a thread is a


background thread.

IsThreadPoolThread Gets a value indicating whether or not a thread belongs to the


managed thread pool.

ManagedThreadId Gets a unique identifier for the current managed thread.

Name Gets or sets the name of the thread.

Priority Gets or sets a value indicating the scheduling priority of a thread.

ThreadState Gets a value containing the states of the current thread.

3. Methods of the Thread Class

Sr.No. Methods

1. public void Abort()


Raises a ThreadAbortException in the thread on which it is invoked, to
begin the process of terminating the thread. Calling this method usually
terminates the thread.
2. public static LocalDataStoreSlot AllocateDataSlot()
Allocates an unnamed data slot on all the threads. For better performance,
use fields that are marked with the ThreadStaticAttribute attribute instead.

15 - 8 C# and .NET Programming


Threads and Synchronization

3. public static LocalDataStoreSlot AllocateNamedDataSlot(string name)


Allocates a named data slot on all threads. For better performance, use fields
that are marked with the ThreadStaticAttribute attribute instead.
4. public static void BeginCriticalRegion()
Notifies a host that execution is about to enter a region of code in which the
effects of a thread abort or unhandled exception might jeopardize other tasks
in the application domain.
5. public static void BeginThreadAffinity()
Notifies a host that managed code is about to execute instructions that
depend on the identity of the current physical operating system thread.
6. public static void EndCriticalRegion()
Notifies a host that execution is about to enter a region of code in which the
effects of a thread abort or unhandled exception are limited to the current
task.

7. public static void EndThreadAffinity()

Notifies a host that managed code has finished executing instructions that
depend on the identity of the current physical operating system thread.

8. public static void FreeNamedDataSlot(string name)

Eliminates the association between a name and a slot, for all threads in the
process. For better performance, use fields that are marked with the
ThreadStaticAttribute attribute instead.

9. public static Object GetData(LocalDataStoreSlot slot)

Retrieves the value from the specified slot on the current thread, within the
current thread's current domain. For better performance, use fields that are
marked with the ThreadStaticAttribute attribute instead.

10. public static AppDomain GetDomain()

Returns the current domain in which the current thread is running.

11. public static AppDomain GetDomain()

Returns a unique application domain identifier

15 - 9 C# and .NET Programming


Threads and Synchronization

12. public static LocalDataStoreSlot GetNamedDataSlot(string name)


Looks up a named data slot. For better performance, use fields that are
marked with the ThreadStaticAttribute attribute instead.
13. public void Interrupt()
Interrupts a thread that is in the WaitSleepJoin thread state.
14. public void Join()
Blocks the calling thread until a thread terminates, while continuing to
perform standard COM and SendMessage pumping. This method has
different overloaded forms.
15. public static void MemoryBarrier()
Synchronizes memory access as follows: The processor executing the
current thread cannot reorder instructions in such a way that memory
accesses prior to the call to MemoryBarrier execute after memory accesses
that follow the call to MemoryBarrier.
16. public static void ResetAbort()
Cancels an Abort requested for the current thread.
17. public static void SetData(LocalDataStoreSlot slot, Object data)
Sets the data in the specified slot on the currently running thread, for that
thread's current domain. For better performance, use fields marked with the
ThreadStaticAttribute attribute instead.
18. public void Start()
Starts a thread.
19. public static void Sleep(int millisecondsTimeout)
Makes the thread pause for a period of time.
20. public static void SpinWait(int iterations)
Causes a thread to wait the number of times defined by the iterations
parameter
21. public static byte VolatileRead(ref byte address)
public static double VolatileRead(ref double address)
public static int VolatileRead(ref int address)

15 - 10 C# and .NET Programming


Threads and Synchronization

public static Object VolatileRead(ref Object address)


Reads the value of a field. The value is the latest written by any processor in
a computer, regardless of the number of processors or the state of processor
cache. This method has different overloaded forms. Only some are given
above.
22. public static void VolatileWrite(ref byte address, byte value)
public static void VolatileWrite(ref double address, double value)
public static void VolatileWrite(ref int address, int value)
public static void VolatileWrite(ref Object address, Object value)
Writes a value to a field immediately, so that the value is visibile to all
processors in the computers. This method has differen overload forms. Only
some are given above.
23. public static bool Yield()
Causes the calling thread to yield execution to another thread that is ready to
run on the current processor. The operating system selects the thread to yield
to.
4. The Main Thread
Concept

In C#, the System.Threading.Thread class is used for working with threads.


Explanation

It allows creating and accessing individual threads in a multithreaded application.


The first thread to be executed in a process is called the main thread.
When a C# program starts execution, the main thread is automatically created.
The threads created using the Thread class are called the child threads of the main
thread.
The threads can be accessed using the CurrentThread property of the Thread class.
Example
//The following program demonstrates main thread execution:
using System;
using System.Threading;

namespace MultithreadingApplication
{

15 - 11 C# and .NET Programming


Threads and Synchronization

class MainThreadProgram
{
static void Main(string[] args)
{
Thread th = Thread.CurrentThread;
th.Name = "MainThread";
Console.WriteLine("This is {0}", th.Name);
Console.ReadKey();
}
}
}
Input
NIL
Output
This is MainThread
5. ThreadPool Class
1. Using ThreadPool class , many different threads can be executed in parallel and have the
system recycle them as soon as possible.
2. This is an ideal way to start many short-lived tasks as indicated following figure.

Fig. 15.3.1 Thread pool

3. The ThreadPool type provides built-in functionality.


4. By using the threadpool class one can assign work to be done by a separate thread easily
and this is the way recommended using whenever possible.
5. Thread pooling is essential in multithreaded applications for the following reasons.
When threadpools are used every time thread creation is not done from scratch hence,
Thread pooling improves the response time of an application as threads are already
available in the thread pool waiting for their next assignment.

15 - 12 C# and .NET Programming


Threads and Synchronization

Thread pooling saves the CLR time of creating an entirely new thread for every short-
lived task and reclaiming its resources once it dies. Thread pooling effectively uses CPU
time slots.
Thread pooling enables to begin several tasks without having to set the properties for
each thread.
Thread pooling enables to pass information as an object to the procedure arguments of
the task that is being executed.
Using Thread pooling maximum number of threads that are to be processed can be fixed
to certain number.
Example
//illustration of Threadpool class

// assign thread pool thread to do the job


ThreadPool.QueueUserWorkItem(run);

If one want to pass any parameters to the method executing by the thread it can be pass
them as a second argument.like this for run method with object parameter.

// assign thread pool thread to do the job


ThreadPool.QueueUserWorkItem(run,10);
Example
class ThreadpoolDemo
{
static void Main(string[] args)
{
// assign thread pool thread to do the job
ThreadPool.QueueUserWorkItem(run,5);
// makes the main thread sleep – so as to run child threads
Thread.Sleep(1000);
for (int tcnt = 10; tcnt > 0; tcnt--)
{
Console.WriteLine("Main Thread value is " + tcnt);
Thread.Sleep(1000);
}

Console.WriteLine("Main Thread Finished");


Console.ReadLine();
}
/* this method executed by a separate thread. It should match with the WaitCallback
(parameters must be passed as an object) */

15 - 13 C# and .NET Programming


Threads and Synchronization

static void run(object argsOb)


{
// cast the parameter
int total = (int)argsOb;
for (int cnt = 0; cnt < total; cnt++)
{
Console.WriteLine("Child Thread value is " + cnt);
Thread.Sleep(1000);

}
Console.WriteLine("Child Thread Finished");
}
}

15.4 Managing Threads

The Thread class provides various methods for managing threads.


1. Pausing a Thread

The Thread.Sleep method can be used to pause a thread for a fixed period of time.
Syntax
Thread.Sleep()
Example
//Illustration of Sleep method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace MultiThread
{
class SleepOp
{
static void Main(string[] args)
{
Thread th = new Thread(Show);
th.Start();
for (int cnt = 1; cnt <= 10; cnt ++)
{
Console.WriteLine("India");
Thread.Sleep(2000); //sleeps for 2000 milliseconds
}
}

15 - 14 C# and .NET Programming


Threads and Synchronization

private static void Show()


{
for (int cnt = 1; cnt <= 5; cnt ++)
{
Console.WriteLine("Welcome To");
Thread.Sleep(1000); //sleeps for 1000 milliseconds
}
}
}
}

Output
Welcome To
India
Welcome To
India
Welcome To
Welcome To
India
Welcome To
India
India
India
India
India
India
India

2. Destroying Threads

1. The Abort() method is used for destroying threads.


2. The runtime environment aborts the thread by throwing a ThreadAbortException. This
exception cannot be caught and the control is sent to the finally block, if any.
3. Before invoking the Abort method it should made sure to check the thread’s IsAlive
property.
4. Syntax
If (Thread.IsAlive)
{
Thread.Abort();
}

15 - 15 C# and .NET Programming


Threads and Synchronization

Example
//Illustration of thread Abort operation

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

namespace MultiThread
{
class AbortOp
{
static void Main(string[] args)
{
Thread th = new Thread(Show);

if (th.IsAlive)
{
th.Start();
th.Abort(); //show method if immediately stopped as thread aborts
}
for (int cnt = 1; cnt <= 10; cnt ++)
{
Console.WriteLine("India");
}
}
private static void Show()
{
for (int cnt = 1; cnt <= 5; cnt ++)
{
Console.WriteLine("Welcome To");
}

}
}

}
Output
India
India
India
India

15 - 16 C# and .NET Programming


Threads and Synchronization

India
India
India
India
India
India

3. Suspend a Thread

The Suspend method of the Thread class suspends a thread.


The thread is suspended until the Resume method is called.
Syntax
if (thread.ThreadState == ThreadState.Running)
{
thread.Suspend();
}

4. Resume a suspended Thread

The Resume method is called to resume a suspended thread.


If the thread is not suspended, the Resume method will have no effect.
Syntax
if (thread.ThreadState == ThreadState.Suspended) {
thread.Resume();
}
5. Make the thread a background thread
The threads running in background remain running even the main thread finishes. To end
all threads when main thread dies, IsBackground property is set to true.
Syntax
// make the thread background
thrd.IsBackground = true;
6. Thread Priority
Concept
1. Priority is certain values (usually integer type) attached with the thread so as to indicate its
importance from running point of view. That is priority tells that which thread is to be
given a chance to execute first over other simultaneously running threads.
Explanation
2. The Thread class's ThreadPriority property is used to set the thread's priority. The thread
priority can have Normal, AboveNormal, BelowNormal, Highest, and Lowest values.

15 - 17 C# and .NET Programming


Threads and Synchronization

In C#, System.Threading.Thread.Priority is a enumeration that defines the priority states


of a thread that in turn determines how much processor time a thread gets to execute.
3. High priority threads always get more processor time than their counterparts. If there is
more than one thread at a high priority then the operating system cycles through the
threads giving each high priority thread some amount of processor time. Lower priority
threads do not get to execute as long as a higher priority thread is available.
4. When there are no more threads of higher priority, the operating system then selects the
next lower priority threads for execution. If at any point it encounters a higher priority
thread, \then the lower priority threads are preempted (taken away from CPU) and higher
priority thread is executed.
5. Any new thread when created, is assigned a Normal priority. If required the thread
priority value can be changed to any of the values shown below. There are 5 priorities
defined in the Priority property of the Thread class.
1. Highest
2. AboveNormal
3. Normal
4. BelowNormal
5. Lowest
6. Syntax
thread.Priority = ThreadPriority.Lowest
//Example

//Illustration of thread creation without setting any priority

/* PrioritiesDemo1 program do not define any priority, which executes the method Show()
first and then Main method gets a chance to execute. */

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

namespace MultiThread
{
class PriortiesDemo1
{
static void Main(string[] args)
{
Thread th = new Thread(Show);

15 - 18 C# and .NET Programming


Threads and Synchronization

th.Start();
for (int cnt = 1; cnt <= 10; cnt ++)
{
Console.WriteLine("India");
}
}

private static void Show()


{
for (int cnt = 1; cnt <= 5; cnt++)
{
Console.WriteLine("Welcome to");
}
}
}
}
Output
Welcome to
Welcome to
Welcome to
Welcome to
Welcome to
India
India
India
India
India
India
India
India
India
India

Example
//illustration of thread Using With Lowest Priority
/* PrioritiesDemo2 program defines the priority. New thread has low priority therefore
method Show() of this thread gets chance after high priority Main thread. Main method
executes first. */

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

15 - 19 C# and .NET Programming


Threads and Synchronization

using System.Threading;

namespace MultiThread
{
class PrioritiesDemo2
{
static void Main(string[] args)
{
Thread th = new Thread(Show);
th.Priority = ThreadPriority.Lowest;
th.Start();
for (int cnt = 1; cnt <= 10; cnt++)
{
Console.WriteLine("India");
}
}

private static void Show()


{
for (int cnt = 0; cnt <= 5; cnt ++)
{
Console.WriteLine("Welcome To");
}
}
}
}
Output
India
India
India
India
India
India
India
India
India
India
Welcome To
Welcome To
Welcome To
Welcome To
Welcome To

15 - 20 C# and .NET Programming


Threads and Synchronization

15.5 Applications and Benefits of Threads

1. Mutually exclusive tasks of the single process, such as gathering user input and
background processing can be managed with the use of threads.
2. Threads can be used as a convenient way to structure a program that performs several
similar or identical tasks concurrently.
3. Major advantage of using the threads is that multiple activities can be carried out
simultaneously.
4. Another advantage is that thread can be used to achieve faster computations by doing two
different computations in two threads instead of serially one after the other.

15.6 Thread Communication

15.6.1 Synchronization
Concept

Synchronization means coordinating the actions of threads for a fixed expected


predictable outcome in terms of time and manipulations.
Explanation

Synchronization is particularly important when threads access the same data.


Synchronization processing can be divided in following four categories.
1. Synchronization using blocking the methods
In this synchronization technique, rest of the threads wait for another thread to finish or
wait for a period of time to elapse. Sleep, Join, and EndInvoke are simple blocking
methods used for blocking
2. Synchronization using Locking concept
In this, exclusive access to a resource enforced, such as a field or section of code, ensuring
that only one thread can enter at a time. Locking is the primary thread-safety mechanism,
that allows threads to access common data without interfering with each other. The
locking constructs are lock and Mutex and a variation of mutex called Semaphore.
3. Synchronization using Signals
By sending signals, a thread can be paused until receiving a notification from another,
avoiding the need for inefficient polling. There are two signaling mechanism, event wait
and Monitor's Wait/Pulse methods.

15 - 21 C# and .NET Programming


Threads and Synchronization

4. Synchronization using Nonblocking


By this method, access to a common field is protected by calling upon processor
primitives. The Interlocked class and the volatile keyword are the two constructs for
achieving nonblocking methodology.
15.6.2 Blocking
Concept

A thread is said to be blocked when its execution is paused for some reason, such as
when waiting for another to end via Join or EndInvoke.
Explanation

A blocked thread consumes almost no processor time.


The CLR and operating system know about blocked threads, and provide appropriate
support to keep them in a non-working state, waking them up when their blocking
conditions are satisfied.
15.6.3 Locking
Concept

Exclusive locking is used to ensure that only one thread can enter particular sections of
code at a time. The .NET Framework provides two exclusive locking constructs namely
lock and Mutex.
Explanation

Only one thread can lock the synchronizing object (in this case, locker) at a time, and
any contending threads are blocked until the lock is released. If more than one thread
contends the lock, they are queued on a "ready queue" and granted the lock on a first-
come, first-served basis. Exclusive locks are sometimes said to enforce serialized access
to whatever's protected by the lock, because one thread's access cannot overlap with that
of another thread.
A thread is blocked while awaiting a contended lock has a ThreadState of
WaitSleepJoin.
Locking should be done before accessing any field comprising writable shared state.
15.6.4 Mutex

A Mutex is like a C# lock, but it can work across multiple processes. In other words, Mutex
can be computer-wide as well as application-wide.

15 - 22 C# and .NET Programming


Threads and Synchronization

15.6.5 Semaphore

A Semaphore is similar to mutex, except that the Semaphore has no "owner"-it is thread-
agnostic. Any thread can call Release on a Semaphore, whereas with Mutex and lock, only
the thread that obtained the lock can release it. Semaphores can be useful in limiting
concurrency-preventing too many threads from executing a particular piece of code at once.
15.6.6 Nonblocking Synchronization

For locking, always a thread must be blocked, suffering the overhead and latency of being
temporarily descheduled.
The .NET Framework's nonblocking synchronization constructs can perform simple
operations without ever blocking, pausing, or waiting. These involve using instructions that
are strictly atomic or instructing the compiler to use "volatile" read and write semantics.

Two Marks Questions with Answers

Q.1 Define thread. Explain about Multithreading.


Ans. : Thread is a set of instructions that when executed enables the program to perform
concurrent processing. Concurrent processing helps in doing more than one process at a
time. By default, C# consists of only thread. Other threads can be created to execute the
code in parallel with original thread.
Thread follows a life cycle where it starts whenever a thread is created and gets
terminated immediately after the execution. The namespace it follows is System.Threading
which has to be included to create threads and use its members.
Threads are created by extending the thread class. Start() method marks the beginning of
the thread execution.
1. //callThread is our target method//
2. ThreadStart methodThread = new ThreadStart(CallThread);
3. Thread childThread = new Thread(methodThread);
4. childThread.start();
C# can also execute more than proceeses/task at a time which is done by handling different
processes at different time labeled as "multithreading".
Several operations of the same are listed below :
Start
Sleep
Abort

15 - 23 C# and .NET Programming


Threads and Synchronization

Suspend
Resume
Join
Q.2 Explain Synchronous and Asynchronous Operations.
Ans. : Synchronization is a way of creating a thread-safe code where only a single thread
will access the code in a given time. A synchronous call waits for completion of method
and then continous the program flow. Synchronous programming adversely affects the UI
operations that normally happens when user tries to perform time-consuming operations
since only one thread is used.
In Asynchronous operation, the method call immediately returns allowing the program
to perform other operations while the method called completes its share of work in certain
circumstances.
Q.3 What is Thread Pooling ?
Ans. : A Thread pool is a collection of threads that perform tasks without disturbing the
primary thread. Once the task is completed by a thread it returns to the primary thread.
Q.4 Illustrate Race Condition.
Ans. : A Race Condition occurs in a situation when two threads access the same resource
and try to change it at the same time. The thread which accesses the resource first cannot be
predicted. Let me take a small example where two threads X1 and X2 are trying to access
the same shared resource called T. And if both threads try to write the value to T, then the
last value written to T will be saved.
Q.5 Name the different states of a thread.
Ans. : Following are the different states of a thread :
Unstarted : The thread is created
Running : The execution of the thread starts
WaitSleepJoin : The thread is asked to sleep, asks other thread to wait and asks the
other thread to join
Suspended : The thread has been suspended
Aborted : The thread is dead but didn't change the state
Stopped : The thread has been stopped
Q.6 What are the properties of the thread class ?
Ans. : Following are the properties of the thread class :
IsAlive : When the thread is active, it contains the true value.

15 - 24 C# and .NET Programming


Threads and Synchronization

Name : It is used for setting the name for a thread and also for returning the name of
the thread.
Priority : The value is returned to the task set as per operating system.
IsBackground : It is the deciding factor for a thread whether it should be in the
background or the foreground.
ThreadState : This explains the state of the thread.
Q.7 Name a few methods used for handling the multi-threaded operations.
Ans. : Following are the few methods that are used for handling the multi-threaded
operations :
Start
Sleep
Abort
Suspend
Resume
Join
Q.8 How can we access a thread in C# ? AU : Dec.-19

Ans. :
For accessing main thread it requires the Thread class object to refer it. It can be
created by using the CurrentThread property of the Thread class. It will return the
reference to the thread in which it used. So when the CurrentThread property is used
inside the main thread one will get the reference of the main thread. After that, one
will get control over the main thread just like another thread. Once this control is
obtained then if further threads are created in the applications they all can be accessed
using Thread class.
The System.Threading namespace provides the classes and interfaces that implement
multithreaded programming. One of the classes in this namespace is the Thread class.
This class is used for creating and controlling threads.

Long Answered Questions

Q.1 Discuss C# threads. (Refer section 15.1)


Q.2 What are benefits and applications of threads ? (Refer section 15.5)
Q.3 How inter-thread communication occurs ? (Refer section 15.6)
Q.4 Explain Thread programming classes supported in C#. (Refer section 15.3)
Q.5 Discuss thread life cycle. (Refer section 15.2)

15 - 25 C# and .NET Programming


Threads and Synchronization

Q.6 Write a C# Program to Obtain Status of the Current Thread.


AU : Dec.-18, Marks 7
Ans. :
/*
* C# Program to Obtain Status of the Current Thread
*/
using System;
using System.Threading;

namespace threademos
{
class ProgramThreadStatus
{
static void Main(string[] args)
{
Console.WriteLine("Current information");
Thread t = Thread.CurrentThread;
t.Name = "primarythread";

Console.WriteLine("Thread Name: {0}", t.Name);


Console.WriteLine("Thread Status: {0}", t.IsAlive);

Console.ReadKey();
}

}
}
Q.7 Write a C# program to illustrate the concept of Passing Parameter for thread.
AU : May-18, Marks 6

Ans. :
/*
* C# Program to illustrate the Concept of Passing Parameter for Thread
*/
using System;
using System.Threading;
public class ThreadDemo
{
public static void Main()
{
Thread newThread = new Thread(ThreadDemo.task1);
newThread.Start(20);
ThreadDemo p = new ThreadDemo ();
newThread = new Thread(p.task2);
newThread.Start("Instance");

15 - 26 C# and .NET Programming


Threads and Synchronization

Console.ReadLine();
}
public static void task1(object data)
{
Console.WriteLine("Static Thread Procedure : Data ='{0}'",data);
}
public void task2(object data)
{
Console.WriteLine("Instance Thread Procedure : Data ='{0}'", data);
}
}
Q.8 Consider 2 toll booths in a national highway. People passing by are to pay
30/-. The booths keeps track of the number of people who visited the booth
and the total ticket amount collected. Model the toll booth with a class called
TollBooth in C# with the following members.
Data Members
Numbers of people who visited the booth
Total amount collected
Member Functions
Increment number of people and amount of someone passes by
Display the result
Exception : The number of people has to be a valid integer.
Use appropriate constructors and destructor. Use the concept of threads to
implement the 2 booths. (Refer section 15.3) AU : Dec.-19, Marks 13

Threads and Synchronization ends …

15 - 27 C# and .NET Programming


Threads and Synchronization

15 - 28 C# and .NET Programming


C# and .NET Framework - Introduction

Syllabus : Transactions, ADO.NET

Section No. Topic Name Page No.


16.1 ADO.NET - Handling Data through the .NET 16 - 2
Environment
16.2 Disconnected Data Access Architecture 16 - 3
16.3 Data Providers 16 - 4
16.4 ADO.NET Objects 16 - 5
16.5 Data Set 16 - 7
16.6 Working with Data 16 - 8
16.7 Exception Handling with ADO.NET 16 - 40
16.8 Transaction in ADO .NET 16 - 44
Two Marks Questions with Answers 16 - 49
Long Answered Questions 16 - 53

16 - 1 C# and .NET Programming


ADO .NET and Transactions

16.1 ADO.NET - Handling Data through the .NET Environment

AU : May-19
Concept
1. ADO.NET is an object-oriented set of libraries that allows developer to interact with data
sources. Commonly, the data source is a database, but it could also be a text file, an Excel
spreadsheet, or an XML file.
Explanation

2. There are many different types of databases available through which data can be accessed.
For example, there is Microsoft SQL Server, Microsoft Access, Oracle, Borland Interbase,
and IBM DB2, just to name a few.
ADO.NET Architecture

Fig. 16.1.1 ADO.NET architecture (title)

3. Advantages of ADO.Net
1. ADO.NET relies on managed providers defined by the .NET Common Language
Runtime.
2. ADO.NET can have separate objects that represent connections to different data
sources.
3. In ADO.NET one can create multiple data provider namespaces to connect
specifically with a particular data source, making access faster and more efficient and
allowing each namespace to exploit the features of its targeted data provider.
4. ADO.NET gives the choice of either using client side or server side cursors.

16 - 2 C# and .NET Programming


ADO .NET and Transactions

5. ADO.NET has no Recordset object and ADO.NET introduced Dataset instead of


Recordset. DataSet provides a disconnected representation of result sets from the Data
Source, and it is completely independent from the Data Source.
6. ADO.Net datasets can hold data from various sources and integrate the data and write
it back to one or several data sources.
7. In the case of Data Communication, ADO.NET uses XML for passing the data which
is highly compatible with current applications platforms.

16.2 Disconnected Data Access Architecture AU : May-19

Concept

1. The ADO.NET Framework supports two models of Data Access Architecture,


Connection Oriented Data Access Architecture and Disconnected Data Access
Architecture. The ADO.NET Disconnected Data Access Architecture is more flexible
and powerful than ADOs Connection Oriented Data Access.
Explanation

2. In Connection Oriented Data Access Architecture the application makes a connection to


the Data Source and then interact with it through SQL requests using the same connection.
In this case the application stays connected to the database system even when it is not
using any Database Operations. On the other hand the disconnected approach makes no
attempt to maintain a connection to the data source.
3. ADO.Net provides a new solution by introducing a component called Dataset. The
DataSet is the central component in the ADO.NET Disconnected Data Access
Architecture. A DataSet is an in-memory data store that can hold multiple tables at the
same time. DataSets only hold data and do not interact with a Data Source. One of the key
characteristics of the DataSet is that it has no knowledge of the underlying Data Source
that might have been used to populate it.
4. In Connection Oriented Data Access, when data is read from a database by using a
DataReader object, an open connection must be maintained between application and the
Data Source. Unlike the DataReader, the DataSet is not connected directly to a Data
Source through a Connection object when it is populated. DataAdapter manages
connections between Data Source and Dataset by fill the data from Data Source to the
Dataset and giving a disconnected behavior to the Dataset. The DataAdapter acts as a
bridge between the Connected and Disconnected Objects.

16 - 3 C# and .NET Programming


ADO .NET and Transactions

5. By keeping connections open for only a minimum period of time, ADO.NET conserves
system resources and provides maximum security for databases and also has less impact
on system performance.

16.3 Data Providers

Concept

1. As different data sources expose different protocols, there is need of different methods to
communicate with the right data source using the right protocol.
Explanation

2. Some older data sources use the ODBC protocol, many newer data sources use the
OleDb protocol, and that allow to communicate with them directly through .NET
ADO.NET class libraries.
3. ADO.NET provides a relatively common way to interact with data sources in the form of
libraries. These libraries are called Data Providers and are usually named for the protocol
or data source type they allow to interact with. Following Table 16.3.1 lists some well
known data providers, the API prefix they use, and the type of data source they allow to
interact with.
4. The Data provider communication

Fig. 16.3.1 Data provider communication

5. ADO.NET Data Providers are class libraries that allow a common way to interact with
specific data sources or protocols. The library APIs have prefixes that indicate which
provider they support.
Provider API prefix Data source description
name
ODBC Data Data Sources with an ODBC interface. Normally older data
Odbc
Provider
bases.
OleDb Data Data Sources that expose an OleDb interface, i.e. Access or
OleDb
Provider
Excel.

16 - 4 C# and .NET Programming


ADO .NET and Transactions

Oracle Data For Oracle Databases.


Oracle
Provider
SQL Data For interacting with Microsoft SQL Server.
Sql
Provider
Borland Data Generic access to many databases such as Interbase, SQL
Bdp
Provider
Server, IBM DB2, and Oracle.

Table 16.3.1 Data provides

16.4 ADO.NET Objects

Concept
ADO.NET includes many objects to work around with data which are discussed below.

Fig. 16.4.1 ADO .NET objects

16 - 5 C# and .NET Programming


ADO .NET and Transactions

Explanation

1. The SqlConnection Object


To interact with a database, one must have a connection to it. The connection helps to
identify the database server, the database name, user name, password, and other
parameters that are required for connecting to the data base. A connection object is
used by command objects so they will know which database to execute the command
on.
The Connection Object provides physical connection to the Data Source. Connection
object needs the necessary information to recognize the data source and to log on to it
properly, this information is provided through a connection string.
ADO.NET connection object, which allows to establish a connection to a data source.
If OleDb Data Provider is used to connect to a data source that exposes an OleDb
interface, then the connection object named OleDbConnection is used. Similarly, the
connection object name would be prefixed with Odbc or Sql for an OdbcConnection
object on an Odbc data source or a SqlConnection object on a SQL Server database,
respectively.

2. The SqlCommand Object


The Command Object uses to perform SQL statement or stored procedure to be
executed at the Data Source. The command object provides a number of Execute
methods that can be used to perform the SQL queries in a variety of ways.
The process of interacting with a database means that one must specify the actions
that can occur on dataset. This is done with a command object. A command object is
used to send SQL statements to the database. A command object uses a connection
object to figure out which database to communicate with. A command object only can
be used, to execute a command directly, or assign a reference to a command object to
an SqlDataAdapter, which holds a set of commands that work on a group of data as
described below.

3. The SqlDataReader Object


The DataReader Object is a stream-based, forward-only, read-only retrieval of query
results from the Data Source, which do not update the data. DataReader requires a live
connection with the databse and provides a very intelligent way of consuming all or
part of the result set.
Many data operations require a stream of data for reading. The data reader object
allows to obtain the results of a SELECT statement from a command object. For
performance reasons, the data returned from a data reader is a fast forward-only
stream of data. This means that data is brought from the stream in a sequential manner
so as to read and not to manipulate.

16 - 6 C# and .NET Programming


ADO .NET and Transactions

4. The DataSet Object


DataSet objects are the in-memory representations of data. They contain multiple
Datatable objects, which contain columns and rows, just like normal database tables.
Relationship can be defined between tables to create parent-child associations. The
DataSet is specifically designed to help so as to manage data in memory and to
support disconnected operations on data, when such a operations are required. The
DataSet is an object that is used by all of the Data Providers, which is why it does not
have a Data Provider specific prefix.

5. The SqlDataAdapter Object


DataAdapter Object populate a Dataset Object with results from a Data Source. It is a
special class whose purpose is to bridge the gap between the disconnected Dataset
objects and the physical data source.
When data is primarily read-only and not required to be manipulated then unwanted
database calls can be saved with the help of DataAdapter object . The data adapter
manages data in a disconnected mode as well. The data adapter fills a DataSet object
when reading the data and writes in a single batch when persisting changes back to the
database. A data adapter contains a reference to the connection object and opens and
closes the connection automatically when reading from or writing to the database.
Additionally, the data adapter contains command object references for SELECT,
INSERT, UPDATE, and DELETE operations on the data. There is a data adapter
defined for each table in a DataSet and it handles all communications with the
database. Data adapter only need to inform about when to load from or write to the
database.

16.5 Data Set AU : Dec.-17

Concept

DataSet provides a disconnected representation of result sets from the Data Source, and
it is completely independent from the Data Source. DataSet provides much greater
flexibility when dealing with related Result Sets.
Explanation

DataSet contains rows, columns, primary keys, constraints, and relations with other
DataTable objects. It consists of a collection of DataTable objects that one can relate to
each other with DataRelation objects. The DataAdapter Object provides a bridge
between the DataSet and the Data Source.

16 - 7 C# and .NET Programming


ADO .NET and Transactions

Fig. 16.5.1 Data set

16.6 Working with Data AU : May-18

16.6.1 ADO .NET - Handling Data thourgh Data Manipulation Classes

While working with database following hierarchy is instantiated in a sequence.

Fig. 16.6.1 Database object creation

1. Creating a SqlConnection Object


A SqlConnection is an object, just like any other C# object which is declared and
instantiated as follows,
SqlConnection conn = new SqlConnection(
"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");
The SqlConnection object instantiated above uses a constructor with a single argument of
type string. This argument is called a connection string.
Common parts of a connection string
ADO.NET Connection Strings contain certain key/value pairs for specifying how to make
a database connection. They include the location, name of the database, and security
parameters.

16 - 8 C# and .NET Programming


ADO .NET and Transactions

Connection String Description


Parameter Name

Data Source Identifies the server. Could be local machine, machine domain name, or
IP Address.

Initial Catalog Database name.

Integrated Security Set to SSPI to make connection with user’s Windows login

User ID Name of user configured in SQL Server.

Password Password matching SQL Server User ID.

The following statement shows a connection string, using the User ID and Password
parameters for security purpose,
SqlConnection conn = new SqlConnection(
"Data Source=DatabaseServer;Initial Catalog=Northwind;User
D=ValidUserID;Password=ValidPassword");
Notice how the Data Source is set to DatabaseServer to indicate that one can identify a
database located on a different machine, over a LAN, or over the Internet. Additionally,
User ID and Password replace the Integrated Security parameter.
--C# ADO.NET Connection String
Connection String is a normal String representation which contains Database connection
information to establish the connection between Database and the Application. The
Connection String includes parameters such as the name of the driver, Server name and
Database name , as well as security information such as user name and password.
Usually Data Providers use a connection string containing a collection of parameters to
establish the connection with the database through applications. The .NET Framework
provides mainly three data providers, they are which are Microsoft SQL Server,
OLEDB, ODBC.
Building Microsoft SQL Server Connection String
connetionString="Data Source=ServerName;Initial Catalog=Databasename;
User ID=UserName;Password=Password"
Building OLEDB Data Provider Connection String
connetionString="Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=yourdatabasename.mdb;"
Building ODBC Connection String
connetionString="Driver={Microsoft Access Driver (*.mdb)};
DBQ=yourdatabasename.mdb;"

16 - 9 C# and .NET Programming


ADO .NET and Transactions

Necessary connection information to the Connection String attributes must be provided


so as to build the connection string.
2. Using a SqlConnection

The purpose of creating a SqlConnection object is to work around the database. Other
ADO.NET objects, such as a SqlCommand and a SqlDataAdapter take a connection
object as a parameter. The sequence of operations occurring in the lifetime of a
SqlConnection can be,
1. Instantiate the SqlConnection.
2. Open the connection.
3. Pass the connection to other ADO.NET objects.
4. Perform database operations with the other ADO.NET objects.
5. Close the connection.
Example
/// Illustration of working with SqlConnection objects

class SqlConnectionDemo
{
static void Main()
{
// 1. Instantiate the connection object
SqlConnection sqlconn = new SqlConnection(
"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");

SqlDataReader sqlrdr = null;

try
{
// 2. Open the connection
sqlconn.Open();

// 3. Pass the connection to a command object


SqlCommand sqlcmd = new SqlCommand("select * from Books", conn);

//
// 4. Use the connection
//

16 - 10 C# and .NET Programming


ADO .NET and Transactions

// get query results


sqlrdr = sqlcmd.ExecuteReader();

// print the BookID of each record


while (sqlrdr.Read())
{
Console.WriteLine(sqlrdr[0]);
}
}
finally
{
// close the reader
if (sqlrdr != null)
{
sqlrdr.Close();
}

// 5. Close the connection


if (sqlconn != null)
{
sqlconn.Close();
}
}
}
}
Explanation of Code Snippet

Connection is opened by calling the Open() method of the SqlConnection instance,


sqlconn. Any operations on a connection that was not yet opened will generate an
exception. So, connection must be opened before using it.
Before using a SqlCommand, ADO.NET should know which connection the appilcation
needs. The second parameter to the SqlCommand object is set with the SqlConnection
object, sqlconn. Any operations performed with the SqlCommand will use this
connection only.
The code that uses the connection is a SqlCommand object, which performs a query on
the Book table. The result set is returned as aSqlDataReader and the while loop reads
the first column from each row of the result set, which is the BookID column.
Once connection object is use is over, it must be closed. Failure to do so could have
serious consequences in the performance and scalability of the application. The Close()
method is called in a finally block and it is ensured that the connection is not null before
closing it.

16 - 11 C# and .NET Programming


ADO .NET and Transactions

3. SqlCommand Object
A SqlCommand object allows to specify operations on database. For example, select,
insert, modify, and delete commands on rows of data in a database table. The
SqlCommand object can be used to support disconnected data management scenarios as
well using SqlDataAdapter.
The Command Object uses the connection object to execute SQL queries.
The queries can be in the Form of Inline text, Stored Procedures or direct Table access.
An important feature of Command object is that it can be used to execute queries and
Stored Procedures with Parameters.
If a select query is issued, the result set it returns is usually stored in either a DataSet or
a DataReader object.
Associated Properties of SqlCommand Class

Property Type of Access Description

The SqlConnection object that is used by the


command object to execute SQL queries or
Connection Read/Write
Stored Procedure.

Represents the T-SQL Statement or the name of


CommandText Read/Write
the Stored Procedure.

This property indicates how the CommandText


property should be interpreted. The possible
values are :

CommandType Read/Write 1. Text (T-SQL Statement)


2. StoredProcedure (Stored Procedure
Name)
3. TableDirect

This property indicates the time to wait when


executing a particular command.
Default Time for Execution of Command is 30
CommandTimeout Read/Write
Seconds.
The Command is aborted after it times out and
an exception is thrown.

16 - 12 C# and .NET Programming


ADO .NET and Transactions

Methods of Command Object


Property Description

This method executes the command specifies and returns the number of
ExecuteNonQuery
rows affected.

The ExecuteReader method executes the command specified and returns


ExecuteReader
an instance of instance of SqlDataReader class.

This method executes the command specified and returns the first column
ExecuteScalar
of first row of the result set. The remaining rows and column are ignored.

This method executes the command specified and returns an instance of


ExecuteXMLReader XmlReader class. This method can be used to return the result set in the
form of an XML document

Creating a SqlCommand Object


SqlCommand sqlcmd = new SqlCommand("select BookCategoryName from
BookCategories", sqlconn);
Above statement takes a string parameter that holds the command to be executed and a
reference to a SqlConnection object.
Querying Data
When using a SQL select command, a data set is retrieved for viewing. To retrieve data
ExecuteReader method is used, which returns a SqlDataReader object.
// 1. Instantiate a new command with a query and connection
SqlCommand sqlcmd = new SqlCommand("select BookCategoryName from
BookCategories", sqlconn);

// 2. Call Execute reader to get query results


SqlDataReader sqlrdr = sqlcmd.ExecuteReader();
In the above code snippet, SqlCommand object is instantiated, by passing the command
string and connection object to the constructor. Then a SqlDataReader object is obtained by
calling the ExecuteReader method of the SqlCommand object, sqlcmd.
Inserting Data
To insert data into a database, the ExecuteNonQuery method of the SqlCommand object is
used.
// Illustration of insert data into a database table.
// Prepare command string
string insertString = @"
insert into BookCategories
(BookCategoryName, Description)

16 - 13 C# and .NET Programming


ADO .NET and Transactions

values ('Fantasy', 'The best of the imaginations')";

// 1. Instantiate a new command with a query and connection


SqlCommand sqlcmd = new SqlCommand(insertString, sqlconn);

// 2. Call ExecuteNonQuery to send command


sqlcmd.ExecuteNonQuery();

Variable, insertString is used SqlCommand instantiation. The insertString variable is


declared just above the SqlCommand declaration.
The two apostrophes (”) in the insertString text for the word “doesn”t”. This get the string
to populate column properly.
To execute this command, call the ExecuteNonQuery method on the SqlCommand
instance, sqlcmd.
Updating Data
The ExecuteNonQuery method is used for updating data.
//Illustration of updating data
// Prepare command string
string updateString = @"
update BookCategories
set BookCategoryName = 'Fiction'
where BookCategoryName = 'Fantasy'";

// 1. Instantiate a new command with command text only


SqlCommand sqlcmd = new SqlCommand(updateString);

// 2. Set the Connection property


sqlcmd.Connection = sqlconn;

// 3. Call ExecuteNonQuery to send command


sqlcmd.ExecuteNonQuery();
Explanation
The ExecuteNonQuery method performs the update command.
Deleting Data
Data can be deleted using the ExecuteNonQuery method.
//Illustration of deleting a record from a database.
// prepare command string
string deleteString = @ "
delete from BookCategories
where BookCategoryName = 'Fiction'" ;

16 - 14 C# and .NET Programming


ADO .NET and Transactions

// 1. Instantiate a new command


SqlCommand sqlcmd = new SqlCommand();

// 2. Set the CommandText property


sqlcmd.CommandText = deleteString;

// 3. Set the Connection property


sqlcmd.Connection = sqlconn;

// 4. Call ExecuteNonQuery to send command


sqlcmd.ExecuteNonQuery();
Explanation

Here, SqlCommand constructor is used with no parameters. Instead, it explicity sets the
CommandText and Connection properties of the SqlCommand object, sqlcmd.
The ExecuteNonQuery method call sends the command to the database.
Getting Single values
Single value from database is required so as to get aggregate value from data, which may
be count, sum, average etc. ExecuteReader is used to perform this and the result is calculated.
// 1. Instantiate a new command
SqlCommand sqlcmd = new SqlCommand("select count(*) from BookCategories", sqlconn);

// 2. Call ExecuteNonQuery to send command


int count = (int)cmd.ExecuteScalar();
The query in the SqlCommand constructor obtains the count of all records from the
BookCategories table. This query will only return a single value. The ExecuteScalar method
in step 2 returns this value. Since the return type of ExecuteScalar is type object, the cast
operator is used to convert the value to int.
Complete illustration of above code snippets for working database.
using System;
using System.Data;
using System.Data.SqlClient;

/// Demonstrates how to work with SqlCommand objects


class SqlCommandDemo
{
SqlConnection sqlconn;

public SqlCommandDemo()
{
// Instantiate the connection

16 - 15 C# and .NET Programming


ADO .NET and Transactions

sqlconn = new SqlConnection(


"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");
}

// call methods that demo SqlCommand capabilities


static void Main()
{
SqlCommandDemo sqlscd = new SqlCommandDemo();

Console.WriteLine();
Console.WriteLine("Book Categories Before Insert");

// ExecuteReader method
sqlscd.ReadData();

// ExecuteNonQuery method for Insert


sqlscd.Insertdata();
Console.WriteLine();
Console.WriteLine("BookCategories After Insert");

sqlscd.ReadData();

// ExecuteNonQuery method for Update


sqlscd.UpdateData();

Console.WriteLine();
Console.WriteLine("BookCategories After Update");

sqlscd.ReadData();

// ExecuteNonQuery method for Delete


sqlscd.DeleteData();

Console.WriteLine();
Console.WriteLine("BookCategories After Delete");
sqlscd.ReadData();

//ExecuteScalar method
int countOfRecords = sqlscd.GetNumberOfRecords();

Console.WriteLine();
Console.WriteLine("Total Records: {0}", numberOfRecords);
}

/// ExecuteReader method

16 - 16 C# and .NET Programming


ADO .NET and Transactions

public void ReadData()


{
SqlDataReader sqlrdr = null;

try
{
// Open the connection
conn.Open();

// 1.Instantiate command with a query and connection


SqlCommand sqlcmd = new SqlCommand("select BookCategoryName from
BookCategories", sqlconn);

// 2. Execute reader to get query results


sqlrdr = sqlcmd.ExecuteReader();

// print the BookCategoryName of each record


while (sqlrdr.Read())
{
Console.WriteLine(sqlrdr[0]);
}
}
finally
{
// close the reader
if (sqlrdr != null)
{
sqlrdr.Close();
}

// Close the connection


if (sqlconn != null)
{
sqlconn.Close();
}
}
}

/// ExecuteNonQuery method for Insert


public void Insertdata()
{
try
{
// Open the connection
sqlconn.Open();

16 - 17 C# and .NET Programming


ADO .NET and Transactions

// prepare command string


string insertString = @ "
insert into BookCategories
(BookCategoryName, BookDescription)
values ('Fantasy', 'Imaginations unlimited')" ;

// 1.Instantiate command with a query and connection


SqlCommand sqlcmd = new SqlCommand(insertString, sqlconn);

// 2. ExecuteNonQuery to send command


sqlcmd.ExecuteNonQuery();
}
finally
{
// Close the connection
if (sqlconn != null)
{
sqlconn.Close();
}
}
}

/// ExecuteNonQuery method for Update


public void UpdateData()
{
try
{
// Open the connection
sqlconn.Open();

// prepare command string


string updateString = @ "
update BookCategories
set BookCategoryName = 'Fiction'
where BookCategoryName = 'Fantasy'" ;

//1.Instantiate command with command text only


SqlCommand sqlcmd = new SqlCommand(updateString);
// 2. Set the Connection property
sqlcmd.Connection = sqlconn;

// 3. ExecuteNonQuery to send command


sqlcmd.ExecuteNonQuery();
}
finally
{

16 - 18 C# and .NET Programming


ADO .NET and Transactions

// Close the connection


if (sqlconn != null)
{
sqlconn.Close();
}
}
}

/// ExecuteNonQuery method for Delete


public void DeleteData()
{
try
{
// Open the connection
sqlconn.Open();

// prepare command string


string deleteString = @ "
delete from BookCategories
where BookCategoryName = 'Fiction'" ;

// 1. Instantiate a command
SqlCommand sqlcmd = new SqlCommand();

// 2. Set the CommandText property


sqlcmd.CommandText = deleteString;

// 3. Set the Connection property


sqlcmd.Connection = sqlconn;

// 4. ExecuteNonQuery to send command


sqlcmd.ExecuteNonQuery();
}
finally
{
// Close the connection
if (sqlconn != null)

{
sqlconn.Close();
}
}
}

/// use ExecuteScalar method

16 - 19 C# and .NET Programming


ADO .NET and Transactions

/// <returns>number of records</returns>


public int GetCountOfRecords()
{
int count = -1;

try
{
// Open the connection
sqlconn.Open();

// 1. Instantiate a new command


SqlCommand sqlcmd = new SqlCommand("select count(*) from BookCategories",
sqlconn);

// 2. ExecuteScalar to send command


count = (int) sqlcmd.ExecuteScalar();
}
finally
{
// Close the connection
if (sqlconn != null)
{
sqlconn.Close();
}
}
return count;
}
}
4. Using SqlDataReader Object

DataReader Properties
Property Description

Depth Indicates the depth of nesting for row

FieldCount Returns number of columns in a row

IsClosed Indicates whether a data reader is closed

Item Gets the value of a column in native format

RecordsAffected Number of row affected after a transaction

16 - 20 C# and .NET Programming


ADO .NET and Transactions

DataReader methods
Method Description

Close Closes a DataRaeder object.

Read Reads next record in the data reader.

NextResult Advances the data reader to the next result during batch transactions.

Getxxx There are dozens of Getxxx methods. These methods read a specific data
type value from a column. For example. GetChar will return a column
value as a character and GetString as a string.

Creating a SqlDataReader Object


Instantiating SqlDataReader is different than the instantiating other ADO.NET objects.
First call ExecuteReader on a command object,
SqlDataReader sqlrdr = sqlcmd.ExecuteReader();
The ExecuteReader method of the SqlCommand object, sqlcmd , returns a SqlDataReader
instance. Creating a SqlDataReader with the new operator is not sufficient to do anything as
the SqlCommand object references the connection and the SQL statement is necessary for the
SqlDataReader to obtain data.
Reading Data
The SqlDataReader returns data via a sequential stream. To read this data, data is fetched
from a table row-by-row. Once a row has been read, the previous row is no longer available.
To read that row again, one would have to create a new instance of the SqlDataReader and
read through the data stream again.
The typical method of reading from the data stream returned by the SqlDataReader is to
iterate through each row with a while loop.
while (sqlrdr.Read())
{
// get the results of each column
string contact = (string)sqlrdr["AuthorContactName"];
string publication = (string)sqlrdr["AuthorPublicationName"];
string city = (string)sqlrdr["AuthorCity"];

// print results
Console.Write("{0,-35}", contact);
Console.Write("{0,-30}", city);
Console.Write("{0,-35}", publication);
}

16 - 21 C# and .NET Programming


ADO .NET and Transactions

The return value of Read is type bool and returns true as long as there are more records to
read. After the last record in the data stream has been read, Read returns false.
Each column can be extracted from the row with a numeric indexer. Instead of numeric
indexer string indexer can be used, where the string is the column name from the SQL query
(the table column name is used if an asterisk, *, is used.) String indexers are much more
readable, making the code easier to maintain.
Regardless of the type of the indexer parameter, a SqlDataReader indexer will return type
object.
Closing Connection
Once used SqlDataReader, close the SqlConnection.
try
{
// data access code
}
finally
{
// 3. close the reader
if (sqlrdr != null)
{
sqlrdr.Close();
}

// close the connection too


}

Example
using System;
using System.Data;
using System.Data.SqlClient;

namespace ADONetDemos
{
class ReadersDemo
{
static void Main()
{
ReadersDemo rsd = new ReadersDemo();
rsd.DataRead();
}

public void DataRead()


{

16 - 22 C# and .NET Programming


ADO .NET and Transactions

// declare the SqlDataReader


SqlDataReader sqlrdr = null;

// create a connection object


SqlConnection sqlconn = new SqlConnection(
"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");

// create a command object


SqlCommand sqlcmd = new SqlCommand(
"select * from Books", conn);

try
{
// open the connection
sqlconn.Open();

// 1. get an instance of the SqlDataReader


sqlrdr = sqlcmd.ExecuteReader();

// print column headers


Console.WriteLine("Author Contact Name Author City Publication Name");

// 2. print necessary columns of each record


while (sqlrdr.Read())
{
// get the results of each column
string contact = (string)sqlrdr["AuthorContactName"];
string publication = (string)sqlrdr["Publication"];
string city = (string)sqlrdr["AuthorCity"];

// print results
Console.Write("{0,-35}", contact);
Console.Write("{0,-30}", city);
Console.Write("{0,-35}", publication);
}
}
finally
{
// 3. close the reader
if (sqlrdr != null)
{
sqlrdr.Close();
}

// close the connection


if (sqlconn != null)

16 - 23 C# and .NET Programming


ADO .NET and Transactions

{
sqlconn.Close();
}
}
}
}
}
5. Using SqlDataAdapter

A DataSet is an in-memory data store that can hold numerous tables. DataSets only hold
data and do not interact with a data source. SqlDataAdapter manages connections with
the data source and gives the disconnected behavior. The SqlDataAdapter opens a
connection only when required and closes it as soon as it has performed its task.
SqlDataAdapter performs the following tasks when filling a DataSet with data,
1. Open connection
2. Retrieve data into DataSet
3. Close connection
and performs the following actions when updating data source when DataSet
changes,
1. Open connection
2. Write changes from DataSet to data source
3. Close connection
In between the Fill and Update operations, data source connections are closed. Data can be
read and written with the DataSet. As the applications holds on to connections only when
necessary, the application becomes more scalable.
Creating a DataSet Object
DataSet dsBooks = new DataSet();
Now, the DataSet is empty and need a SqlDataAdapter to load it.
Creating A SqlDataAdapter
1. The SqlDataAdapter holds the SQL commands and connection object for reading
and writing data. It is initialized with a SQL select statement and connection object :
SqlDataAdapter daBooks = new SqlDataAdapter("select BookID,Author from Books",
sqlconn);
2. The code above creates a new SqlDataAdapter, daBooks. The SQL select statement
specifies what data will be read into a DataSet. The connection object, sqlconn,
should have already been instantiated, but not opened. SqlDataAdapter’s is
responsible to open and close the connection during Fill and Update method calls.

16 - 24 C# and .NET Programming


ADO .NET and Transactions

3. The SqlDataAdapter contains all of the commands necessary to interact with the data
source. There are two ways to add insert, update, and delete commands : via
SqlDataAdapter properties or with a SqlCommandBuilder.
-Using SqlCommandBuilder
SqlCommandBuilder cmdBldr = new SqlCommandBuilder(daBooks);
4. SqlCommandBuilder is instantiated with a single constructor parameter of the
SqlDataAdapter, daBooks, instance. This tells the SqlCommandBuilder what
SqlDataAdapter to add commands to. The SqlCommandBuilder will read the SQL
select statement (specified when the SqlDataAdapter was instantiated), infer the
insert, update, and delete commands, and assign the new commands to the Insert,
Update, and Delete properties of the SqlDataAdapter, respectively.
Note that, SqlCommandBuilder would work for single table and not for multiple table
joins.
Filling the DataSet
daBooks.Fill(dsBooks, "Books");
The Fill method, in the code above, takes two parameters : A DataSet and a table name.
The DataSet must be instantiated before trying to fill it with data. The second parameter is the
name of the table that will be created in the DataSet.
The Fill method has an overload that accepts one parameter for the DataSet only. In that
case, the table created has a default name of “table1” for the first table. The number will be
incremented (table2, table3, …, tableN) for each table added to the DataSet where the table
name was not specified in the Fill method.
Using the DataSet
A DataSet will bind with both ASP.NET and Windows forms DataGrids.
//Illustration with of DataSet assigned to a Windows forms DataGrid
dgBooks.DataSource = dsBooks;
dgBooks.DataMember = "Books";
DataSet is assigned to the DataSource property of the DataGrid.
To specify exactly which table to use, set the DataGrid’s DataMember property to the
name of the table.
Updating Changes
After modifications are made to the data, if it is to be updated to actual database, the
Update method of the SqlDataAdapter is used to put modifications to the database.
daBooks.Update(dsBooks, "Books");
The Update method, above, is called on the SqlDataAdapter instance that originally filled
the dsBooks DataSet. The second parameter to the Update method specifies which table, from

16 - 25 C# and .NET Programming


ADO .NET and Transactions

the DataSet, to update. The table contains a list of records that have been modified and the
Insert, Update, and Delete properties of the SqlDataAdapter contain the SQL statements used
to make database modifications.
6. DataSet Object

DataSet is tabular representation of data into rows and columns. The dataset
represents a subset of the database. It does not have a continuous connection to the
database. To update the database a reconnection is required. The DataSet contains
DataTable objects and DataRelation objects. The DataRelation objects represent the
relationship between two tables.
The ADO.NET DataSet contains DataTableCollection and their DataRelationCollection
. It represents a collection of data retrieved from the Data Source. Dataset can be used in
combination with DataAdapter class. The DataSet object offers a disconnected data
source architecture. The Dataset can work with the data it contain, without knowing the
source of the data coming from. That is, the Dataset can work with a disconnected mode
from its Data Source. It gives a better advantage over DataReader, because the
DataReader is working only with the connection oriented Data Sources.
Some important properties of the DataSet class

Properties Description

CaseSensitive Indicates whether string comparisons within the data tables are case-
sensitive.

Container Gets the container for the component.

DataSetName Gets or sets the name of the current data set.

DefaultViewManager Returns a view of data in the data set.

DesignMode Indicates whether the component is currently in design mode.

EnforceConstraints Indicates whether constraint rules are followed when attempting any
update operation.

Events Gets the list of event handlers that are attached to this component.

ExtendedProperties Gets the collection of customized user information associated with the
DataSet.

HasErrors Indicates if there are any errors.

IsInitialized Indicates whether the DataSet is initialized.

16 - 26 C# and .NET Programming


ADO .NET and Transactions

Locale Gets or sets the locale information used to compare strings within the
table.

Namespace Gets or sets the namespace of the DataSet.

Prefix Gets or sets an XML prefix that aliases the namespace of the DataSet.

Relations Returns the collection of DataRelation objects.

Tables Returns the collection of DataTable objects.

Some important methods of the DataSet class

Methods Description

AcceptChanges Accepts all changes made since the DataSet was loaded or this
method was called.

BeginInit Begins the initialization of the DataSet. The initialization


occurs at run time.

Clear Clears data.

Clone Copies the structure of the DataSet, including all DataTable


schemas, relations, and constraints. Does not copy any data.

Copy Copies both structure and data.

CreateDataReader() Returns a DataTableReader with one result set per DataTable,


in the same sequence as the tables appear in the Tables
collection.

CreateDataReader(DataTable[]) Returns a DataTableReader with one result set per DataTable.

EndInit Ends the initialization of the data set.

Equals(Object) Determines whether the specified object is equal to the current


object.

Finalize Free resources and perform other cleanups.

GetChanges Returns a copy of the DataSet with all changes made since it
was loaded or the AcceptChanges method was called.

GetChanges(DataRowState) Gets a copy of DataSet with all changes made since it was
loaded or the AcceptChanges method was called, filtered by
DataRowState.

GetDataSetSchema Gets a copy of XmlSchemaSet for the DataSet.

16 - 27 C# and .NET Programming


ADO .NET and Transactions

GetObjectData Populates a serialization information object with the data


needed to serialize the DataSet.

GetType Gets the type of the current instance.

GetXML Returns the XML representation of the data.

GetXMLSchema Returns the XSD schema for the XML representation of the
data.

HasChanges() Gets a value indicating whether the DataSet has changes,


including new, deleted, or modified rows.

HasChanges(DataRowState) Gets a value indicating whether the DataSet has changes,


including new, deleted, or modified rows, filtered by
DataRowState.

IsBinarySerialized Inspects the format of the serialized representation of the


DataSet.

Load(IDataReader, LoadOption, Fills a DataSet with values from a data source using the
DataTable[]) supplied IDataReader, using an array of DataTable instances
to supply the schema and namespace information.

Load(IDataReader, LoadOption, Fills a DataSet with values from a data source using the
String[]) supplied IDataReader, using an array of strings to supply the
names for the tables within the DataSet.

Merge() Merges the data with data from another DataSet. This method
has different overloaded forms.

ReadXML() Reads an XML schema and data into the DataSet. This
method has different overloaded forms.

ReadXMLSchema(0) Reads an XML schema into the DataSet. This method has
different overloaded forms.

RejectChanges Rolls back all changes made since the last call to
AcceptChanges.

WriteXML() Writes an XML schema and data from the DataSet. This
method has different overloaded forms.

WriteXMLSchema() Writes the structure of the DataSet as an XML schema. This


method has different overloaded forms.

16 - 28 C# and .NET Programming


ADO .NET and Transactions

7. The DataTable Class

The DataTable class represents the tables in the database. It has the following important
properties; most of these properties are read only properties except the PrimaryKey
property.
Some important properties of datatable class

Properties Description

ChildRelations Returns the collection of child relationship.

Columns Returns the columns collection.

Constraints Returns the constraints collection.

DataSet Returns the parent DataSet.

DefaultView Returns a view of the table.

ParentRelations Returns the ParentRelations collection.

PrimaryKey Gets or sets an array of columns as the primary key for the table.

Rows Returns the Rows collection.

Some important methods of the DataTable class

Methods Description

AcceptChanges Commits all changes since the last AcceptChanges.

Clear Clears all data from the table.

GetChanges Returns a copy of the DataTable with all changes made since the
AcceptChanges method was called.

GetErrors Returns an array of rows with errors.

ImportRows Copies a new row into the table.

LoadDataRow Finds and updates a specific row, or creates a new one, if not found any.

Merge Merges the table with another DataTable.

NewRow Creates a new DataRow.

16 - 29 C# and .NET Programming


ADO .NET and Transactions

RejectChanges Rolls back all changes made since the last call to AcceptChanges.

Reset Resets the table to its original state.

Select Returns an array of DataRow objects.

The DataRow Class

The DataRow object represents a row in a table.


Some important properties

Properties Description

HasErrors Indicates if there are any errors.

Items Gets or sets the data stored in a specific column.

ItemArrays Gets or sets all the values for the row.

Table Returns the parent table.

Some important methods of the DataRow class

Methods Description

AcceptChanges Accepts all changes made since this method was called.

BeginEdit Begins edit operation.

CancelEdit Cancels edit operation.

Delete Deletes the DataRow.

EndEdit Ends the edit operation.

GetChildRows Gets the child rows of this row.

GetParentRow Gets the parent row.

GetParentRows Gets parent rows of DataRow object.

RejectChanges Rolls back all changes made since the last call to AcceptChanges.

8. The DataAdapter Object

The DataAdapter object acts as a mediator between the DataSet object and the database.
This helps the Dataset to contain data from multiple databases or other data source.

16 - 30 C# and .NET Programming


ADO .NET and Transactions

9. The DataReader Object

The DataReader object is an alternative to the DataSet and DataAdapter combination.


This object provides a connection oriented access to the data records in the database. These
objects are suitable for read-only access, such as populating a list and then breaking the
connection.
10. DbCommand and DbConnection Objects
The DbConnection object represents a connection to the data source. The connection could
be shared among different command objects.
The DbCommand object represents the command or a stored procedure sent to the database
from retrieving or manipulating data.
Example
//illustration of Reading data using DataSet

using System;
using System.Data;
using System.Data.SqlClient;

class DatasetDemo
{
static void Main()
{
string sqlconnString = "server=(local)\\SQLEXP;database=MyDatabase;Integrated
Security=SSPI";
string sqlqry = @"select * from Books";
SqlConnection sqlconn = new SqlConnection(sqlconnString);

try
{
sqlconn.Open();
SqlDataAdapter sqlda = new SqlDataAdapter(sqlqry, sqlconn);
DataSet ds = new DataSet();
sqlda.Fill(ds, "Books");
DataTable dt = ds.Tables["CatagoryName"];
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn col in dt.Columns)
Console.WriteLine(row[col]);
Console.WriteLine(" ".PadLeft(20, '='));
}
}
catch(Exception e)
{
Console.WriteLine("Error: " + e);

16 - 31 C# and .NET Programming


ADO .NET and Transactions

}
finally
{
sqlconn.Close();
}
}
}

16.6.2 ADO .NET and Store Procedures - Updating Databases through Stored
Procedures

A stored procedure is nothing more than a prepared SQL code that is saved to reuse again
and again. So if there is a query that is being used over multiple times it can be better saved as
a stored procedure and then just the stored procedure would be called as per need to execute
the SQL code. So store procedure is a pre-define and a pre-compiled set of source code.
Difference between Stored Procedure and Functions

1. Function must return a value, but in Stored Procedure it is optional (procedure can
return zero or n values).
2. Functions can have only input parameters for it, whereas procedures can have
input/output parameters.
3. Functions can be called from procedure, whereas procedures cannot be called from
function. As stored Procedure may contain DML statements where as function can't
contain DML statements.
4. Procedure allows SELECT as well as DML (INSERT/UPDATE/DELETE) statement
in it whereas function allows only SELECT statement in it.
5. Stored procedure is precompiled execution plan whereas functions are not.
Using Stored Procedure for Database Updation in ADO .NET

Stored procedures can be called using SqlDataAdapter to update the table in database
from the DataTable . If a query is written in SelectCommand of SqlDataAdapter, it
automatically generates the required InsertCommand, UpdateCommand and
DeleteCommand in a simple scenario to update the database but if the name of Stored
Procedure is passed in SelectCommand, then it won't be able to generate these other
commands.
There is another way of doing it by table-valued parameter where one can pass the
datatable directly to stored procedure but SQL SERVER 2005 and previous version
does not support it and that requires creating User Type and enabling CLR in SQL
SERVER.

16 - 32 C# and .NET Programming


ADO .NET and Transactions

For using stored procedure one can use SqlDataAdapter. SqlDataAdapter will require
only name of the stored procedure and the DataTable which needs to be updated.
Example 1 -

Step 1 - Create table in SQL named Customer with the specified columns.
CREATE TABLE Customer(
[ID] [int] IDENTITY(1,1) Primary Key,
[Name] [varchar](20) NULL,
[City] [varchar](20) NULL,
[DOB] [date] NULL,
[Married] [bit] NULL,
[Mobile] [int] NULL)

Step 2 - Create a Stored Procedure to Get the Data from Customer Table.
-- Create Get stored procedure
Create Procedure uspGetCustomer @ID int

as

IF @ID < 1
SELECT * FROM Customer
Else
SELECT * FROM Customer WHERE ID = @ID
Create another Stored Procedure to update the Customer Table.
Note - Name of the parameter should be the same as column name of the table with
prefix as @.
There will be one extra parameter named @RowState with int type to check the passed row
need to be deleted, updated or inserted.
For creating this stored procedure, one can extensively use the query generated by SQL
server (Right click on table in Object Explorer -> Script Table as -> use CREATE TO,
UPDATE TO, INSERT TO, DELETE TO).
-- Create Update stored procedure
Create Procedure uspUpdateCustomer @ID int,
@Name varchar (20),
@City varchar (20),
@DOB date,
@Married bit,
@Mobile int,
@RowState int
as

IF @RowState = 4

16 - 33 C# and .NET Programming


ADO .NET and Transactions

INSERT INTO Customer


([Name]
,[City]
,[DOB]
,[Married]
,[Mobile])
VALUES
(@Name
,@City
,@DOB
,@Married
,@Mobile)

IF @RowState is null and @ID is not null


DELETE FROM Customer
WHERE ID = @ID

IF @RowState = 16 and @ID is not null


UPDATE Customer
SET [Name] = @Name
,[City] = @City
,[DOB] = @DOB
,[Married] = @Married
,[Mobile] = @Mobile
WHERE ID = @ID

Step 3 - The C# CODE for ADO .NET statements.


public function of data access layer which could be accessed to get or update data. This
function will need the name of the stored procedure created above. This same function can be
written for any table.
//method to retrieve data
public DataTable GetCustomer()
{
command = new SqlCommand("uspGetCustomer", connection);

command.Parameters.AddWithValue("@ID", -1);

return GetDetails();
}

//method to update data


public void UpdateCustomer(DataTable dtTable)
{
command = new SqlCommand("uspUpdateCustomer", connection);

16 - 34 C# and .NET Programming


ADO .NET and Transactions

UpdateDetails(dtTable);
}
Private functions GetDetails and UpdateDetails. These function won't need
replication for each table if multiple tables are updated.
1 GetDetails function will use Fill functions of SqlDataAdapter to fill the DataTable.
UpdateDetails function will first use GetChanges to get the updated, inserted or
deleted rows so that only those rows are passed which need to changed in the
database.
2. Add one extra column RowState to dtChanges to pass the RowState of the changed
row.
3. For loop will create SqlParameter using the name of columns in datatable and add it
in the SqlCommand.
4. Add common command to SqlDataAdapter for each INSERT, UPDATE, DELETE
and its constructor.
5. Get Inserted, updated and deleted rows and For loop will fill the RowState column
for each row for added and modified rows. As RowState can not be called on deleted
row, no need to set RowState it will become null for each deleted row.
6. Next, call Update function of SqlDataAdapter to update the database.
//Method to get details
private DataTable GetDetails()
{
command.CommandType = CommandType.StoredProcedure;

adapter = new SqlDataAdapter(command);


DataTable dtTable = new DataTable();

try
{
// Fill from database
adapter.Fill(dtTable);
}
catch (InvalidOperationException ioEx)
{

}
catch (Exception ex)
{

}
return dtTable;

16 - 35 C# and .NET Programming


ADO .NET and Transactions

//method to update details


private void UpdateDetails(DataTable dtTable)
{
SqlParameter parameter;

command.CommandType = CommandType.StoredProcedure;

//Get the changes


DataTable dtChanges = dtTable.GetChanges();

//No change return back


if (dtChanges == null)
return;

//Add new column rowstate to hold row


dtChanges.Columns.Add("RowState", typeof(int));

// Add parameter for each column


for (int i = 0; i < dtChanges.Columns.Count; i++)
{
parameter = new SqlParameter();

// Set parameter name


parameter.ParameterName = "@" + dtChanges.Rows[i].Field<string>("name");

//Set source column


parameter.SourceColumn = dtChanges.Rows[i].Field<string>("name");

command.Parameters.Add(parameter);
}

//Update Insert, Update, Delete command to adapter


adapter = new SqlDataAdapter(command);
adapter.InsertCommand = command;
adapter.UpdateCommand = command;
adapter.DeleteCommand = command;

//Get the rows Inserted, updated and deleted


DataTable dtDeletedRows = dtChanges.GetChanges(DataRowState.Deleted);
DataTable dtModifiedRows = dtChanges.GetChanges(DataRowState.Modified);
DataTable dtAddedRows = dtChanges.GetChanges(DataRowState.Added);

// for updated rows set RowState = 16

16 - 36 C# and .NET Programming


ADO .NET and Transactions

if (dtModifiedRows != null)
{
for (int i = 0; i < dtModifiedRows.Rows.Count; i++)
{
dtModifiedRows.Rows[i]["RowState"] = 16;
}
}

// For inserted rows set RowState = 4


if (dtAddedRows != null)
{
for (int i = 0; i < dtAddedRows.Rows.Count; i++)
{
dtAddedRows.Rows[i]["RowState"] = 4;
}
}

try
{
//Update Database
if (dtAddedRows != null)
{
adapter.Update(dtAddedRows);
}
if (dtDeletedRows != null)
{
adapter.Update(dtDeletedRows);
}
if (dtModifiedRows != null)
{
adapter.Update(dtModifiedRows);
}
}
catch (Exception exception)
{
}
}

Step 4 - The complete Data Access Layer code using the above function.
ConnString is the name of connection string in configuration file.
public class DataAccessLayer
{
SqlConnection connection;
SqlCommand command;
SqlDataAdapter adapter;

16 - 37 C# and .NET Programming


ADO .NET and Transactions

public DataAccessLayer()
{
ConnectionStringSettingsCollection settings
= ConfigurationManager.ConnectionStrings;

string connectionString = settings["ConnString"].ConnectionString;

connection = new SqlConnection(connectionString);


}

public DataTable GetCustomer(){...}

public void UpdateCustomer(DataTable dtTable){...}

private DataTable GetDetails(){...}

private void UpdateDetails(DataTable dtTable){...}


}
Example 2

Step 1 - Create table in SQL named Registration with the specified columns.
CREATE TABLE UserRegistration (
C_Id int IDENTITY(1, 1) NOT NULL,
C_Name varchar(100) NULL,
C_Age varchar(100) NULL,
C_Country varchar(100) NULL
);

Step 2 - Create a Stored Procedure to insert, delete or update the Data from
Registration Table.
Create procedure SpMyProcedure (
@Id int = null,
@Name varchar(100)= null,
@Age varchar(100)= null,
@Country varchar(100)= null,
@Action varchar(100)= null
) As begin if @Action = 'Insert' Insert into UserRegistration(C_Name, C_Age, C_Country)
values
(@Name, @Age, @Country) if @Action = 'Update'
Update
UserRegistration
set
C_Name = @Name,
C_Age = @Age,
C_Country = @Countrywhere C_Id = @Id if @Action = 'Delete'
Delete from

16 - 38 C# and .NET Programming


ADO .NET and Transactions

UserRegistration
where
C_Id = @Id end

Step 3 - The C# CODE for ADO .NET statements.


//Call to stored procedure for Insert operation.
protected void btnSave_Click(object sender, EventArgs e)
{
string str = "server=Your Server Name; Initial Catalog=Your Database Name; User
ID=User Id; Password=Your Password";
SqlConnection cn = new SqlConnection(str);
SqlCommand cmd = new SqlCommand("SpMyProcedure", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Action", "Insert");
cmd.Parameters.AddWithValue("@Name", txtName.Text);
cmd.Parameters.AddWithValue("@Age", txtAge.Text);
cmd.Parameters.AddWithValue("@Country", txtCountry.Text);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
//Call to stored procedure for Delete operation.
protected void btnDelete_Click(object sender, EventArgs e)
{
string str = "server=Your Server Name; Initial Catalog=Your Database Name;
User ID=User Id; Password=Your Password";
SqlConnection cn = new SqlConnection(str);
SqlCommand cmd = new SqlCommand("SpMyProcedure", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Action", "Delete");
cmd.Parameters.AddWithValue("@Id", txtId.Text);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
//Call to stored procedure for Update operation.
protected void btnUpdate_Click(object sender, EventArgs e)
{
string str = "server=Your Server Name; Initial Catalog=Your Database Name; User
ID=User Id; Password=Your Password";
SqlConnection cn = new SqlConnection(str);
SqlCommand cmd = new SqlCommand("SpMyProcedure", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Action", "Update");
cmd.Parameters.AddWithValue("@Name", txtName.Text);
cmd.Parameters.AddWithValue("@Age", txtAge.Text);

16 - 39 C# and .NET Programming


ADO .NET and Transactions

cmd.Parameters.AddWithValue("@Country", txtCountry.Text);
cmd.Parameters.AddWithValue("@Id", txtId.Text);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}

16.7 Exception Handling with ADO.NET AU : Dec.-18

1. Database programming involves four very important steps


1. Creating the connection with the database
2. Opening the connection
3. Executing the SQL statements
4. Closing the connection
Out of these four steps the most important step is the last one - closing the connection.
This is because if all the database connections are left open very soon no user will be able to
perform any operation on the database. It is because of the extreme importance of this step it
becomes very critical that one use exception handling while using ADO.net for database
programming using C#.
2. Possible exceptions which can occur during database interaction
Below is the list of some of the exceptions which will be raised very frequently when using
ADO.net code. C# compiler is not able to find these exceptions and they always show up
during runtime.
1) Not able to connect to database
While working with ADO.net code above error comes very frequently. The cause of
this error is a wrong connection string. For removing this exception check the
connection string and make sure that all the required information to connect to the
database. If connection string is correct then make sure that SQL Server is in running
state.
2) Wrong SQL statement
If SQL statement is wrongly written this exception is raised which needs precise
correction.
3) Connection lost while processing
It might happen that application was in the process of reading or writing to the
database and the connection is lost in between. This will generate a runtime
exception.

16 - 40 C# and .NET Programming


ADO .NET and Transactions

3. The .NET Exception hierarchy


All .NET exceptions are derived classes of the System.Exception base class, or
derived from another inherited class therein.
System.SystemException is inherited from the System.Exception class.
System.Runtime.InteropServices. ExternalException is inherited from the
System.SystemException class.
System.Data.Common.DbException is inherited from the System.Runtime.
InteropServices.ExternalExceptionclass.
Finally, System.Data.SqlClient.SqlException is inherited from the System.Data.
Common.DbException class.
SqlException Class

This class resides in namespace System.Data.SqlClient. The exception that is thrown when
SQL Server returns a warning or error. This class cannot be inherited.
Using System.Data.SqlClient.SqlException

Since the occurrence of a System.Data.SqlClient.SqlException is directly related to a


problem with the SQL server, it's important to take a moment to understand how to connect a
C# application to an SQL server, and therefore what scenarios
System.Data.SqlClient.SqlException might occur.
Below code illustrates the SqlException.
using System;
using System.Data;
using System.Data.SqlClient;

class MainClass
{
static void Main()
{
SqlConnection conn = new SqlConnection(@"data source = .\sqlexpress;integrated
security = true;database = northwind");

SqlCommand cmd = conn.CreateCommand();

cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_DbException_1";
try
{
conn.Open();

16 - 41 C# and .NET Programming


ADO .NET and Transactions

cmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException ex)
{
Console.WriteLine("Source: " + ex.Source);
Console.WriteLine("Number: "+ ex.Number.ToString());
Console.WriteLine("Message: "+ ex.Message);
Console.WriteLine("Class: "+ ex.Class.ToString ());
Console.WriteLine("Procedure: "+ ex.Procedure.ToString());
Console.WriteLine("Line Number: "+ex.LineNumber.ToString());
Console.WriteLine("Server: "+ ex.Server.ToString());

}
catch (System.Exception ex)
{
Console.WriteLine("Source: " + ex.Source);
Console.WriteLine("Exception Message: " + ex.Message);
}
finally
{
if (conn.State == ConnectionState.Open)
{
Console.WriteLine("Finally block closing the connection");
conn.Close();
}
}
}
}
Purposeful use of Finally block in ADO .NET exceptions

A finally block is executed whether or not an exception occurs. Hence, it is particularly


useful for cleanup operations. The purpose of a finally statement is to ensure that the
necessary cleanup of objects, usually objects that are holding external resources, happens
immediately, even if an exception is thrown. Consider a open database connection in a try
block. If an exception occurs, it is caught in the catch block just after the try block as shown in
the code snippet below,
string connectionString = …; // Some connection string
SqlConnection sqlConnection = null;
try
{
sqlConnection = new SqlConnection(connectionString);
sqlConnection.Open();
//Some code
}

16 - 42 C# and .NET Programming


ADO .NET and Transactions

catch (Exception ex)


{
//Some exception handling code
}

finally
{
sqlConnection.Close();
}
Using the "using" statement in ADO .NET Exception handling

The using statement can be used to specify a boundary for the object outside of which, the
object is destroyed automatically. The runtime invokes the Dispose method of the objects that
are specified within this statement when the control comes out of this block. This is why this
is a preferred choice when using exceptions for managing resources in .NET. Refer to the
following code that uses the "using" statement :
string connectionString = …; // Some connection string
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
//Some code
}
Note that when the end of the using block would be encountered, the Dispose () method
will be immediately called on the instance. Note that when the Dispose() method is called on
this connection instance, it checks to see if the connection is opened; if open it would close it
implicitly prior to disposing off the instance.
Dispose and Finalize for more information on when and how to use them appropriately.
The above code gets translated implicitly to :
string connectionString = …; // Some connection string
SqlConnection sqlConnection = new SqlConnection(connectionString));
try
{
sqlConnection.Open();
//Some code
}
finally
{
((IDispose)sqlConnection).Dispose();
}
Remember to keep the try block as short as possible. Note that in the code example above,
the connection is just opened in the try block. Do not use any unnecessary code/logic in the try

16 - 43 C# and .NET Programming


ADO .NET and Transactions

block that is not supposed to throw any exception. Do not catch any exception that cannot be
handled and avoid rethrowing exceptions unnecessarily as it is very expensive.
Prevent unnecessary database hit

One of the most useful of all features of ADO.NET is that one can attach messages to each
row of data in a DataSet object. The SqlDataAdapter class attaches error messages to the rows
of a DataSet if a specific database action has not been successfully completed. Then one can
check whether there are any errors in a DataSet prior to sending the same for updating the
database using the HasErrors property of the DataSet instance. This, if used judiciously, can
prevent an unnecessary database hit. Please refer to the code snippet that follows,
DataSet newDataSet = previousDataSet.GetChanges(DataRowState.Modified);
if (newDataSet.HasErrors)
{
// If there are errors take appropriate action
}
else
{
// Necessary code to update the database
}

16.8 Transaction in ADO .NET AU : Dec.-17

A transaction is a single unit of work which means either ALL or NONE. If a transaction is
successful, all of the data operations are committed (saved) and become a durable part of the
database. If a transaction encounters errors/exceptions and must be canceled or rolled back,
then all of the data modifications/operations need to be removed.
Database transaction takes a database from one consistent state to another. At the end of the
transaction the system must be in the prior state if the transaction fails or the status of the
system should reflect the successful completion if the transaction goes through.
16.8.1 Properties of Transaction
Atomicity

A transaction consists of many steps. When all the steps in a transaction get completed, it
will get reflected in DB or if any step fails, all the transactions are rolled back.
Consistency

The database will move from one consistent state to another, if the transaction succeeds
and remains in the original state, or if the transaction fails.

16 - 44 C# and .NET Programming


ADO .NET and Transactions

Isolation

Every transaction should operate as if it is the only transaction in the system.


Durability

Once a transaction is completed successfully, the updated rows/records must be available


for all other transactions on a permanent basis.
16.8.2 Transaction Commands

The transaction commands are only used in SQL DML (Data Manipulation Language) that
has operations like INSERT, UPDATE and DELETE. That is they change the data. The DDL
(Data Definition Language) or DCL (Data Control Language) are used to in creating structure
and SQL security.
The transaction commands are as below,
COMMIT
This command is used to save the changes invoked by the transaction.
ROLLBACK
This command is used to undo the changes made by transaction.
SAVEPOINT
With the help of this command one can roll the transaction back to a certain point without
rolling back the entire transaction.
SET TRANSACTION
This command is used to specify characteristics for the transaction. For example, one can
specify a transaction to be read only, or read write it. Also helps set the name of transaction.
16.8.3 Transaction with ADO.NET

//example to illustrate SQL transaction used in ADO.NET.


Example
string strConnString = "connectionstring"; // can be taken from Web.config file
SqlTransaction objTrans = null;
using (SqlConnection objConn = new SqlConnection(strConnString))
{
objConn.Open();
objTrans = objConn.BeginTransaction();
SqlCommand objCmd1 = new SqlCommand("insert into tblAuthor values(12, 'Ravi')",
objConn);
SqlCommand objCmd2 = new SqlCommand("insert into tblTechMember(MemberID,
TaskID) values(5, 15)", objConn);

16 - 45 C# and .NET Programming


ADO .NET and Transactions

try
{
objCmd1.ExecuteNonQuery();
objCmd2.ExecuteNonQuery(); // Throws exception due to foreign key constraint

objTrans.Commit();
}
catch (Exception)
{
objTrans.Rollback();
}
finally
{
objConn.Close();
}
}

As seen in the above program, first a connection is opened with SQL Database then object
of SqlTransaction class is instantiated. Also the reference of SqlTransaction is preserved with
this transaction object by calling SQL Begin Transaction method. Within the try block two
SQL commands are executed. If no error occurs the transaction will be committed other than
the catch block rolled back the transaction. Finally, database connection is closed.
16.8.4 TransactionScope Class

TransactionScope got introduced with .NET 2.0 as part of System.Transaction. It is a class


which provides a simple way to make a set of operations as part of a transaction without
worrying about the complexity behind the scene. If any of the operation fails in between,
entire transaction would fail and rolled back which undo all the operation that got completed.
All this would be taken care by the framework, ensuring the data consistency.
It can be used in the program as shown below,
try
{
using (TransactionScope scope = new TransactionScope())
{
// Do Operation 1
// Do Operation 2
//...

// if all the operations complete successfully, this would be called


//and commit the trabsaction.
// In case of an exception, it wont be called and transaction is
//rolled back

16 - 46 C# and .NET Programming


ADO .NET and Transactions

scope.Complete();
}
}
catch (ThreadAbortException ex)
{
// Handle exception
}
When TransactionScope is used it makes the code block in transactional mode. It cannot be
inherited. It is present in namespace System.Transactions.TransactionScope
TransactionScope has 3 main properties(IsolationLevel).
• Isolation Level

It defines the locking mechanism to read data in another transaction. Available options are
Read UnCommitted, Read Committed, Repeatable Read, Serializable. Default is Serializable.
• Timeout

How much time transaction object will wait to be completed. SqlCommand Timeout is
different than Transaction Timeout. SqlCommand Timeout defines how much time the
SqlCommand object will wait for a database operation to be completed. Available options are
10 minutes. Default is 1 minute.
• TransactionScopeOption

It is an enum. Following are the options.


Option Description

Disable This component does not participate in a transaction. This is the default
value.
NotSupported This component runs outside the context of a transaction.
Required It is the default value for TransactionScope. If any already exists then it
will join with that transaction otherwise create new one.
RequiresNew When this option is selected a new transaction is always created. This
transaction is independent with its outer transaction.
Suppress When this option is selected, no transaction will be created. Even if is
already there.
To set the default values

The default value for time out can be set in web.config,

16 - 47 C# and .NET Programming


ADO .NET and Transactions

<system.transactions>
<defaultSettings timeout="30"/>
<machineSettings maxTimeout="1200"/>
</system.transactions>
Example to illustrate use of TransactionScope class

// A TransactionScope class object is created and SQL queries are defined to add records to
Author //table, TaskMember table. If no errors then Complete() is called to commit the data. If
exception is //raised it rolls back to previous state.
using (var txscope =new TransactionScope(TransactionScopeOption.RequiresNew))
{
try
{
using (SqlConnection objConn = new SqlConnection(strConnString))
{
objConn.Open();
SqlCommand objCmd1 = new SqlCommand("insert into tblAuthor values(12, 'Ravi')",
objConn);
SqlCommand objCmd2 = new SqlCommand("insert into tblTaskMember(MemberID,
TaskID) values(12, 18)", objConn);

objCmd1.ExecuteNonQuery();
objCmd2.ExecuteNonQuery(); // Throws exception due to foreign key constraint
//The Transaction will be completed
txscope.Complete();
}
}
catch(Exception ex)
{
// Log error
txscope.Dispose();
}
}

16.8.5 Difference between TransactionScope Class and


BeginTranaction() Method

TransactionScope is usually a better choice because it allows to nest calls to other


methods that might require a transaction without having to pass the transaction state
around.
With TransactionScope, as long as the scope exists, it will handle everything that
registers with the current Transaction on the thread, making the code cleaner, and more
maintainable.

16 - 48 C# and .NET Programming


ADO .NET and Transactions

TransactionScope uses MS DTC(Microsoft Distributed Transaction Coordinator) for


transaction management.
Due to its ease of use and efficiency, it is recommended to use TransactionScope class
when developing a transaction application.

Two Marks Questions with Answers

Q.1 What is ADO.NET ?


ADO.net Stands for Microsoft ActiveX Data Object. Ado.net is a database technology
which we can think like a set of classes that can be used to interact with the data sources
like databases and XML files.
Asp.net application, windows application, console application are the few types of .net
applications that use ADO.NET to connect with the databases to execute commands and
retrieve data.
Q.2 What are the key features of ADO.NET ?
Ans. :
Disconnected Data Architecture.
Data cached in DataSet.
Scalability
Data transfer in XML Format.
Strongly typed language.
Q.3 Why is it important to close an ADO.NET application ?
Ans. : Connections need to be closed properly because it affects the scalability and reliability
of the applications.
For open connections it is always vulnerable to attack, so to be short, 'Open connections
as late as possible and close it as early as possible'. We can 'Close' the connections by 'final'
block or 'using' the USING statement.
Q.4 What is Databinding ?
Ans. : Databinding is the process of binding the data with graphical elements (controls in a
window form). After binding the data in a window form, you can navigate through the
records with the help of the Binding Navigator Control.
One of the advantages of data binding is, the user does not need to write the codes
explicitly, for establishing the connections and creating a data set, this feature will write the
necessary ADO.NET code for the user.

16 - 49 C# and .NET Programming


ADO .NET and Transactions

Q.5 What are DataReaders ?


Ans. : DataReader object is 'stream-based', 'read-only' and 'forward-only', which provides a
connection based data access from a database. This contains a 'Read ()' method that
retrieves the data stored in a data source.
A Connection Object has only one DataReader at a time. 'Read ()' method retrieves only
one row at a time. That is data need not be completely read into the application before it is
processed.
Q.6 What is the difference between Connected and Disconnected environment ?
Ans. : Difference between Connected and Disconnected environment is stated in the
following table.

Connected Environment Disconnected Environment

It requires a constant connection to It doesn't require a constant connection


transfer data between the application to transfer data between the application
and database and database
Data concurrency is easy to control Data concurrency is not easy to control
Data is up-to-date since user is always Data is not up-to-date since user is
connected to the database always connected to the database
It has scalability and performance It improves scalability and performance
issues for the client application of the client application
Lead to network traffic logging Less network traffic logging issues
Q.7 What is the use of data set in Ado.net ? AU : Dec.-17

Ans. : It is a collection of data tables that contain the data. It is used to fetch data without
interacting with a Data Source that's why, it also known as disconnected data access
method. It is an in-memory data store that can hold more than one table at the same time.
One can use DataRelation object to relate these tables. The DataSet can also be used to
read and write data as XML document.
ADO.NET provides a DataSet class that can be used to create DataSet object. It contains
constructors and methods to perform data related operations.
Q.8 Define ADO.Net model. AU : May-18

Ans. : ADO.NET stands for ActiveX Data Object is a database access technology
developed by Microsoft as part of its .NET framework that can access any kind of data
source. It’s a set of object-oriented classes that provides a rich set of data components to
create high-performance, reliable and scalable database applications for client- server

16 - 50 C# and .NET Programming


ADO .NET and Transactions

applications as well as distributed environments over the Internet and intranets.


In the ADO.NET model, unlike ADO (in connected state) and previous data access
technologies applications connect to the data sources when they are reading or updating the
data. After that the connection closes. This is important because in client- server or
distributed applications, having connection resources open all the time is one of the most
resource- consuming parts. There is no need to connect to a data source all the time; the
only time one needs to connect to a data source is when one is reading and writing final
changes to a data source.
ADO .NET uses SQL queries and stored procedures to read write update and delete data
from a data source. SQL queries are used through ADO.NET Command object, which
returns data in the form of DataReader or DataSet objects. After connection closes, DataSet
objects are used to work with the data and connect to the data source again when it is
reuqired to update the data source.
Q.9 Give the advantages of stored procedures. AU : May-18

Ans. : Stored procedures are so popular and have become so widely used and therefore
expected of Relational Database Management Systems (RDBMS) that even MySQL finally
caved to developer peer pressure and added the ability to utilize stored procedures to their
very popular open source database. The list below details why stored procedures have
gained such a stalwart following among application developers (and even Database
Administrators for that matter) :
Quick response - Since stored procedures are compiled and stored, whenever a
procedure is called the response is quick.
Grouping related code and avoiding duplication - One can group all the required
SQL statements in a procedure and execute them at once. Using procedures, one can
avoid repetition of code moreover with these one can use additional SQL
functionalities like calling stored functions. Once stored procedure is compiled it can
be used in any number of applications. If any changes are needed one can just change
the procedures without touching the application code.
Maintainability - Because scripts are in one location, updates and tracking of
dependencies based on schema changes becomes easier
Testing - Can be tested independent of the application
Isolation of business rules - Having Stored Procedures in one location means that
there’s no confusion of having business rules spread over potentially disparate code
files in the application

16 - 51 C# and .NET Programming


ADO .NET and Transactions

Speed / Optimization - Stored procedures are cached on the server. Execution plans
for the process are easily reviewable without having to run the application
Utilization of set-based processing - The power of SQL is its ability to quickly and
efficiently perform set-based processing on large amounts of data; the coding
equivalent is usually iterative looping, which is generally much slower
Security - Limit direct access to tables via defined roles in the database. Provide an
“interface” to the underlying data structure so that all implementation and even the
data itself is shielded. Securing just the data and the code that accesses it is easier than
applying that security within the application code itself
Q.10 List the advantages of ADO.NET model. AU : Dec.-18

Ans. : Advantages of ADO .NET


1. System.Data. ADO.NET data components in Visual Studio environment
encapsulate data access functionality in various ways that help to develop
applications more easily and with fewer errors.
2. ADO.Net offers performance advantages by its Disconnected Architecture, it is a
remarkably efficient and scalable architecture. The DataSet class in ADO.Net
operates in an entirely disconnected nature. This model allows for the DataSet class
to be unaware of the origin of its data source, an unlimited number of supported
data sources can be plugged into code without any hassle in the future
3. ADO.NET programs can take advantage of the flexibility and broad acceptance of
Extensible Markup Language (XML) and an improvement over previous ADO
versions due to the disconnected data model. . XML is the format for transmitting
datasets across the network, so any component that can read the XML format can
process data. In fact, many of the classes in ADO.NET, like the DataSet, are so
intertwined with XML that they simply cannot exist or function without utilizing
the technology.
4. The role of ADO.NET data providers is to permit direct manipulation of data
through SQL. ADO.NET includes a SQL Server Data Provider that is highly
optimized for interaction with SQL Server. It uses SQL Server's own Tabular Data
Stream (TDS) format for exchanging information. This is handled by the ADO.NET
Data Provider.
5. ADO.NET has rich object model. The entire ADO.NET architecture is built on a
hierarchy of class inheritance and interface implementation. Once it is traced for
required things within this namespace, one can find that the logical inheritance of
features and base class support makes the entire system extremely easy to use.

16 - 52 C# and .NET Programming


ADO .NET and Transactions

6. Interoperability - ADO.NET has the ability to communicate across heterogeneous


environments.
7. Scalability - The ability to serve a growing number of clients without degrading
system performance.
8. Productivity - The ability to quickly develop robust data access applications using
ADO.NET’s rich and extensible component object model.
Q.11 What is the need for the DataAdapter class ? AU : Dec.-19

Ans. : The DataAdapter class is needed because it works as a bridge between a DataSet
and a data source to retrieve data. DataAdapter is a class that represents a set of SQL
commands and a database connection. It can be used to fill the DataSet and update the data
source.
The DataAdapter enables to connect to a dataset and specify SQL strings for retrieving
data from or writing data to a DataSet. A dataset represents in–memory cached data. An in
memory object frees developers from the confines of the specifics of database and allows
to deal with the data in memory. The DataAdapter serves as an intermediary between the
database and the DataSet.
The DataAdapter can perform Select, Insert, Update and Delete SQL operations in the
Data Source. The Insert, Update and Delete SQL operations, are carried using the
continuation of the Select command perform by the DataAdapter. The SelectCommand
property of the DataAdapter is a Command Object that retrieves data from the data source.
The InsertCommand, UpdateCommand, and DeleteCommand properties of the
DataAdapter are Command objects that manage updates to the data in the data source
according to modifications made to the data in the DataSet. From the following links
describes how to use SqlDataAdapter and OleDbDataAdapter in detail

Long Answered Questions

Q.1 What are the different methods by which we can populate a Dataset ?
(Refer section 16.5)
Q.2 What are DataProviders ? What are components of data provider ?
(Refer section 16.3)
Q.3 Describe ADO.NET object model in detail. (Refer section 16.4)
Q.4 What are the key events of SqlConnection Class ? (Refer section 16.6)
Q.5 What is meant by 'Transaction' in a database and what are the 'Properties of
Transaction' ? (Refer section 16.8)

16 - 53 C# and .NET Programming


ADO .NET and Transactions

Q.6

[Refer section 16.5]


AU : Dec.-17, Marks 16
Q.7
[Refer section 16.8] AU : Dec.-17, Marks 16
Q.8
[Refer section 16.6]
(Refer section 16.6.2)
AU : May-18, Marks 13
Q.9
[Refer secton 16.7]
AU : Dec.-18, Marks 7
Q.10 [Refer sections 16.1 and 16.2] AU : May-19, Marks 13

ADO .NET and Transactions ends …

16 - 54 C# and .NET Programming


C# and .NET Framework - Introduction

Syllabus : Manipulating XML, SAX and DOM.

Section No. Topic Name Page No.


17.1 XML - A Brief Introduction 17 - 2
17.2 XML Syntax 17 - 5
17.3 Reading and Writing XML Files 17 - 9
17.4 Creating XML File using Serialization 17 - 13
17.5 XML Schema 17 - 16
17.6 XML Style Sheet and Transformation 17 - 23
17.7 Searching XML File using XPATH 17 - 25
17.8 XML and ADO.NET for Handling Data 17 - 28
17.9 Manipulating XML using SAX and DOM 17 - 30
Two Marks Questions with Answers 17 - 42
Long Answered Questions 17 - 43

17 - 1 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

17.1 XML - A Brief Introduction

Concept

1. XML is short for eXtensible Markup Language. It is a very widely used format for
exchanging data, mainly because it's easy readable for both humans and machines. It is
basically a stricter version of HTML.
Explanation

2. XML is made for the World Wide Web but the set of tags are not fixed. They can be
extended and hence the name. One can have own tags. The only thing is to maintain a
structural relationship between them. It's written in SGML (Standard Generalized Markup
Language) which is an international standard for defining descriptions across the globe.
3. XML was developed way back in 1996 by an XML Working Group (known originally as
the SGML Editorial Review Board) which was formed under the guidance of the World
Wide Web Consortium (W3C) which was chaired by Jon Bosak of Sun Microsystems.
4. HTML was designed to display data and specify how that data should look where as XML
was designed to describe and structure data. In this way, an XML file itself doesn’t
actually do anything. It doesn’t say how to display the data or what to do with data, just as
a text file doesn’t.
5. XML is made up of tags, attributes and values and looks something like this,
<users>
<user name="Ravi" age="38" />
<user name="Aviw" age="40" />
</users>
Almost every programming language has built-in functions or classes to deal with it. C# is
definitely one of them, with an entire namespace, the System.Xml namespace, to deal with
pretty much any aspect of XML.
6. The .Net technology widely supports XML file format. The .Net Framework provides the
Classes for read, write, and other operations in XML formatted files . These classes are
stored in the namespaces like System.Xml, System.Xml.Schema,
System.Xml.Serialization, System.Xml.XPath, System.Xml.Xsl etc. The Dataset in
ADO.NET uses XML as its internal storage format.
7. Example
myBook.xml

<journal>

17 - 2 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

<book>

<title>C# Programming</title>

<author>Ravi Wani</author>

<chapters>

<chapter name="Introduction to XML"/>

</chapters>

</book>

</journal>
In above example the subject of data is defined in the XML file.
It can be seen clearly that there is a journal containing books, each of which contains some
chapters along with their names.
XML can be less efficient than some other file formats. Still, in many cases, the loss in
efficiency that results from the increased size can be made up by the speed of processing a
well-defined XML file, as parsers (programs that read XML) can predict the structure.
8. Compared to plain text data format/structure file, the XML file shows clearly what each
piece of information represents and where it belongs in the data hierarchy. This "data-
describing data" is known as metadata, and is a great strength of XML in that one can
create own specifications and structure the data to be interpreted by any other system.
9. XML tags identify the data and are used to store and organize the data, rather than
specifying how to display it like HTML tags, which are used to display the data. XML is
not going to replace HTML in the near future, but it introduces new possibilities by
adopting many successful features of HTML.
10. There are few important characteristics of XML that make it useful in a variety of systems
and solutions:
XML is extensible : XML allows to create own self-descriptive tags, or language, that
suits the application.
XML carries the data, does not present it : XML allows to store the data irrespective of
how it will be presented.
XML is a public standard : XML was developed by an organization called the World
Wide Web Consortium (W3C) and is available as an open standard.

17 - 3 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

XML is a markup language much like HTML.


XML was designed to describe data.
XML tags are not predefined in XML. One must define own tags.
XML is self describing.
XML uses a DTD (Document Type Definition) to formally describe the data.
11. XML Application
XML can work behind the scene to simplify the creation of HTML documents for large
web sites.
XML can be used to exchange the information between organizations and systems.
XML can be used for offloading and reloading of databases.
XML can be used to store and arrange the data, which can customize data handling needs.
XML can easily be merged with style sheets to create almost any desired output.
Virtually, any type of data can be expressed as an XML document.
12. What is Markup ?
XML is a markup language that defines set of rules for encoding documents in a format
that is both human-readable and machine-readable. Markup is information added to a
document that enhances its meaning in certain ways, in that it identifies the parts and how they
relate to each other. More specifically, a markup language is a set of symbols that can be
placed in the text of a document to demarcate and label the parts of that document.
Following example shows how XML markup looks, when embedded in a piece of text :
<message>
<text>Welcome To World Of XML!</text>
</message>

This snippet includes the markup symbols, or the tags such as


<message>...</message> and <text>... </text>. The tags <message> and
</message> mark the start and the end of the XML code fragment. The tags <text>
and </text> surround the text Hello, world!.
13. Is XML a Programming Language ?
Answer to this is a ‘NO’. As programming language consists of grammar rules and its own
vocabulary which is used to create computer programs that XML lacks. These programs
instructs computer to perform specific tasks. XML does not qualify to be a programming
language as it does not perform any computation or algorithms. It is usually stored in a simple
text file and is processed by special software that is capable of interpreting XML.

17 - 4 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

17.2 XML Syntax

Fig. 17.2.1 XML syntax

1. XML Declaration
<?xml version="1.0"?>
<note>
<to>RaviW</to>
<from>AviW</from>
<heading>Greetings</heading>
<body>Wish you happy 2017</body>
</note>
The first line in the document :
The XML declaration should always be included. It defines the XML version of the
document, here it is 1.0 specification of XML.
The XML document can optionally have an XML declaration. It is written as below :
<?xml version="1.0" encoding="UTF-8"?>
Where version is the XML version and encoding specifies the character encoding used in
the document.
Rules for XML declaration

The XML declaration is case sensitive and must begin with "<?xml>" where "xml" is
written in lower-case.
If document contains XML declaration, then it strictly needs to be the first statement of
the XML document.
The XML declaration strictly needs be the first statement in the XML document.
An HTTP protocol can override the value of encoding that is put in the XML declaration.

<?xml version="1.0"?>

17 - 5 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

The next line defines the first element of the document (the root element)
<note>
The next lines defines 4 child elements of the root (to, from, heading, and body):
<to>RaviW</to>
<from>AviW</from>
<heading>Greetings</heading>
<body>Wish you happy 2017</body>
The last line defines the end of the root element
</note>
2. XML Tags and elements

1. An XML file is structured by several XML-elements, also called XML-nodes or


XML-tags. XML-elements' names are enclosed by triangular brackets < > as shown
below :
<element>
2. Syntax Rules for Tags and Elements
Element Syntax: Each XML-element needs to be closed either with start or with end
elements as shown below :
<element>....</element>
or in simple-cases, just this way :
<element/>
Nesting of elements : An XML-element can contain multiple XML-elements as its
children, but the children elements must not overlap. i.e., an end tag of an element must have
the same name as that of the most recent unmatched start tag.
<b><i> bold and italic</i></b>
Following is incorrect,
<b><i> bold and italic does not work</b></i>
Root element :

All XML documents must contain a single tag pair to define the root element and rest other
elements must be nested within the root element. All elements can have sub (child) elements.
Sub elements must be in pairs and correctly nested within their parent element.
<root>
<child>
<subchild>
</subchild>
</child>
</root>

17 - 6 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

For example, following is not a correct XML document, because both the x and y elements
occur at the top level without a root element :
<x>...</x>
<y>...</y>
The following example shows a correctly formed XML document :
<root>
<x>...</x>
<y>...</y>
</root>
- All XML elements must have a closing tag

In XML all elements must have a closing tag this,


<p>This is a paragraph</p>
<p>This is another paragraph</p>
- XML tags are case sensitive

XML tags are case sensitive. The tag <Note> is different from the tag <note>.
Opening and closing tags must therefore be written with the same case.
<Note>Wrong</note>
<Note>Correct</Correct>
3. Attributes

An attribute specifies a single property for the element, using a name/value pair.
An XML-element can have one or more attributes.
Syntax Rules for XML Attributes

Attribute names in XML (unlike HTML) are case sensitive. That is, HREF and href are
considered two different XML attributes.
Same attribute cannot have two values in a syntax. The following example shows
incorrect syntax because the attribute b is specified twice :
<a b="x" c="y" b="z">....</a>
Attribute names are defined without quotation marks, whereas attribute values must
always appear in quotation marks. Following example demonstrates incorrect xml syntax :
<a b=x>....</a>
In the above syntax, the attribute value is not defined in quotation marks.
Attribute values must always be quoted
In XML the attribute value must always be quoted.
Following specification is incorrect as date attribute is note quoted.

17 - 7 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

<?xml version="1.0"?>
<note date=12/11/99>
</note>
Following is the correct specification.
<?xml version="1.0"?>
<note date="12/11/99">
</note>
4. XML References

References usually allow to include additional text or markup in an XML document.


References always begin with the symbol "&" ,which is a reserved character and end with the
symbol ";". XML has two types of references :
Entity References : An entity reference contains a name between the start and the end
delimiters. For example &amp; where amp is name. The name refers to a predefined string of
text and/or markup.
Character References : These contain references, such as &#65;, contains a hash mark
(“#”) followed by a number. The number always refers to the Unicode code of a character. In
this case, 65 refers to alphabet "A".
5. XML Text

The names of XML-elements and XML-attributes are case-sensitive.


To avoid character encoding problems, all XML files should be saved as Unicode
UTF-8 or UTF-16 files.
Whitespace characters like blanks, tabs and line-breaks between XML-elements and
between the XML-attributes will be ignored.
Some characters are reserved by the XML syntax itself. Hence, they cannot be used
directly. To use them, some replacement-entities are used, which are listed below :

not allowed character replacement-entity character description

< &lt; less than

> &gt; greater than

& &amp; ampersand

' &apos; apostrophe

" &quot; quotation mark

17 - 8 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

6. XML Namespaces
A XML namespace allows to qualify an element. XML namespaces uses URI, which is
associated with a prefix for the namespace. A namespace is defined using an xmlns
declaration, followed by the prefix, which is equal to a URI that uniquely identifies the
namespace.
xmlns:movie="http://www.enjoypoint.com/movies">
By adding this namespace definition as an attribute to a tag, one can use the prefix
movie in that tag, and any tags it contains, to fully qualify elements:

<movie:film-types xmlns:movie="http://www.enjoypoint.com/movies">

<movie:film-type>Drama</movie:film-type>

<movie:film-type>Romance</movie:film-type>

</movie:film-types>

Parsers can now recognise both meanings of "film type" and handle them accordingly.

17.3 Reading and Writing XML Files

.NET classes for reading and writing XML files

1. XmlTextReader : The XmlTextReader class is just one of the methods of reading XML
files. It approaches an XML file in a similar way to a DataReader, in that the document is
read element by element, making decisions as reading proceeds. It's by far the easiest
class to use to parse an XML file quickly.
2. XmlTextWriter : Similarly, the XmlTextWriter class provides a means of writing XML
files line by line.
3. XmlValidatingReader : XmlValidatingReader is used to validate an XML file against a
schema file.
Reading an XML File In .NET
XmlTextReader. XmlTextReader is based upon the XmlReader class, specially designed
to read byte streams, making it suitable for XML files that are to be located on disk, on a
network, or in a stream.
First create a new instance of the class.
The constructor takes the location of the XML file that it will read.
// file

XmlTextReader reader = new XmlTextReader("first.xml");

// url

17 - 9 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

XmlTextReader reader = new XmlTextReader("http://www.technical.com/first.xml");

// stream (here, a StringReader s)


XmlTextReader reader = new XmlTextReader(s);
Once it’s loaded, one can move through the file in a forward direction. This means parsing
routines structure should be order-independent. If order of elements is not sure, the code must
be able to handle any order.
Moving through the file can be done using the Read method.
while (reader.Read())

{
// parse file
}
The loop continues until the end of the file is reached, or the loop is broken in the middle
explicitly. Each node is inspected, ascertain its type, and the information is gathered. The
NodeType property exposes the current type of node that’s being read.
An XmlReader will see the following element as 3 different nodes :
<book>Programming</book>
The <book> part of the element is recognised as an XmlNodeType.Element node.
The text part is recognised as an XmlNodeType.Text node, and the closing tag </book> is
seen as an XmlNodeType.EndElement node.
The code below shows how to output the XML tag through the reader object that is created
earlier :
while (reader.Read())

{
switch (reader.NodeType)
{
case XmlNodeType.Element:
Console.Write("<"+reader.Name+">");
break;

case XmlNodeType.Text:
Console.Write(reader.Value);
break;

case XmlNodeType.EndElement:
Console.Write("</"+reader.Name+">");
break;
}
}

17 - 10 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Here’s the output of this code :


<book>Programming</book>
Parsing the attributes
An attribute of type XmlNodeType.Attribute, can be parsed in the fashion shown above.
More elegantly however, when an XmlNodeType.Element type is found, one can iterate
through attributes using XmlTextReader.MoveToNextAttribute :
case XmlNodeType.Element:

Console.Write("<"+reader.Name);
while (reader.MoveToNextAttribute())
{
Console.WriteLine(reader.Name+" = "+reader.Value);
}
break;
Now, if it is fed in this XML:
<book first="1" second="2">Programming</foo>
The output is,
<book first="1" second="2">Programming</book>
Earlier, the attributes were ignored, and output was,
<book>Programming</book>
Note that, if an element does not contain any attributes, the loop is never started. This
means that there is no need to first check to see whether there are attributes. The number of
attributes on a node can be found using the AttributeCount property.
Writing XML in .NET
Writing XML is done by the XmlTextWriter class. Again, taking a forward-only approach,
one can build XML files from different node types, which are output in order.
To begin, create an instance of the class :
XmlTextWriter writer = new XmlTextWriter("FirstWrite.xml", null);
The second parameter, which, here, is set to null, allows us to specify the encoding format
to use in the XML file. Setting it to null produces a standard UTF-8 encoded XML file
without an encoding attribute on the document element.
For writing elements and attributes, the methods exposed in the XmlTextWriter are used.
Consider example of book,
myBook.xml

<journal>

<book>

17 - 11 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

<title>C# Programming</title>

<author>Ravi Wani</author>

<chapters>

<chapter name="Introduction to XML"/>

</chapters>

</book>

</journal>

First line is the element journal.


Use the WriteStartElement method to write this to the writer:
writer.WriteStartElement("journal");
Don’t close this element until all Book elements are written. Thus, the next node to add is
an opening Book element :
writer.WriteStartElement("book");
The title element (<title>C# Programming</title>) is to be written.
This type differs from earlier because it has a specific value. As there are no more
attributes on the title element, use the WriteElementString method :
writer.WriteElementString("title", "C# Programming");

writer.WriteElementString("author", "Ravi Wani");


writer.WriteStartElement("chapters");
Now, element, chapters, are with an attribute, name.
Here, first write the start of the element, then write the attributes, and finally, close
element.
writer.WriteStartElement("chapter");

writer.WriteAttributeString("name", "Control Structures");

writer.WriteEndElement();
There is no need to say which element is to be closed, because the writer will automatically
write the closing tag for the last-opened element, which, in this case, is chapter.
Now close the remaining elements in the same fashion,
writer.WriteEndElement();

writer.WriteEndElement();

17 - 12 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Finally, "flush" the writer, or, in other words, output the requested information to XML
file, then close the writer to free file and resources,
writer.Flush()
writer.Close()

17.4 Creating XML File using Serialization

1. Serialization of XML to Common Language Runtime Objects enables one to convert


XML documents into a form where they are easier to process using conventional
programming languages.
2. The .Net technology is widely supported XML file format. The .Net Framework provides
the Classes for read, write, and other operations in XML formatted files .
3. A serialization technique is the one in which an object will be converted/saved into xml
format or stream. To use serialization in xml one need XmlSerializer class. This class is
derived from System.Xml.Serialization.
4. Serialize and Deserialize are the two most important methods that are used to serialize
object to xml and then again deserialize into object.
5. Things to remember while using xml serialization and deserialization in c# -
i) Only public objects can be serialized in XML serialization. And hence it is also
called as Shallow serialization.
ii) Classes inherited from IEnumerable and ICollection can also be serialized, however it
serializes only collections and not public properties.
iii) Private or read-only properties, Methods, Indexers cannot be serialized using this xml
serialization.
6. Vice versa of XML serialization is called as XML deserialization. In XML serialization
the object gets converted into xml stream/file, and converting that xml stream/file to an
object again is called as XML Deserialization. XML Serialization and
DeSerialization in C# are the most important topics in .Net.
7. Example
/* XML Serialization and Deserialization in C# */

using System;
using System.Xml.Serialization;

namespace XMLCreationTest
{
public class XMLTest1

17 - 13 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

{
public String value1;
public String value2;
}

class Program
{
static void Main(string[] args)
{
XMLTest1 xtest = new XMLTest() { value1 = "Value 1", value2 = "Value 2" };
XmlSerializer xs = new XmlSerializer(xtest.GetType());
xs.Serialize(Console.Out, xtest);
Console.ReadKey();
}
}
}
The actual serialization is done by an instance of the class XmlSerializer, from the
System.Xml.Serialization namespace. The serializer’s constructor requires a reference to the
type of object it should work with – which can be obtained by using the GetType() method of
an instanced object, or a call to the function typeof() and specifying the class name as the only
argument.
The Serialize() method takes an object of the defined type, translates that object into XML,
and then writes the information to a defined stream (in this case, the TextWriter object of the
console’s output stream). The XML output of the sample code is shown below :

<?xml version="1.0" encoding="ibm850"?>


<Test xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema">
<value1>Value 1</value1>
<value2>Value 2</value2>
</Test>
The names of elements and attributes in the XML output are set by the names of the
properties and fields from the object.
8. De-serializing XML Data
Deserialization is the process of taking XML-formatted data and converting it to a .NET
framework object: the reverse of the process shown above. Providing that the XML is well-
formed and accurately matches the structure of the target type, deserialization is a relatively
straightforward task.
In the following example, the XML output of the preceding examples is hard-coded into a
string, but it could be fetched from a network stream or external file. The XmlSerializer class

17 - 14 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

is used to deserialize the string to an instance of the Test class, and the example then prints the
fields to the console. To obtain a suitable stream that can be passed into the XmlSerializer’s
constructor, a StringReader (from the System.IO namespace) is declared.

using System;
using System.IO;
using System.Xml.Serialization;

namespace XMLCreationTest

{
public class XMLTest2
{
public String value1;
public String value2;
}

class Program
{
static void Main(string[] args)
{
String xData = "<?xml version=\"1.0\" encoding=\"ibm850\"?><Test
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
mlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><value1>Value
1</value1><value2>Value 2</value2></Test>";
XmlSerializer xs = new XmlSerializer(typeof(Test));
XMLTest2 test = (XMLTest2)xs.Deserialize(new StringReader(xData));
Console.WriteLine("V1: " + test.value1);
Console.WriteLine("V2: " + test.value2);
}
}
}
9. Overriding the Serialization of a Class
As mentioned earlier, all public properties and fields of a class are automatically
serializable, and can usually be converted to XML without using any directives or attributes.
Private properties and fields are not serialized by default. To include these, and for more
precise control over how an object is serialized to XML, one can override the entire
serialization process.
10. Controlling the Serialization using Attributes
When serializing data for exchange with other applications, or when working to a
predefined XML schema, it is useful to be able to change the element and attribute names
used during the process.

17 - 15 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

By default, elements in the XML output are named after the properties or fields that they
are based on.
The root node can be renamed using the XmlRoot attribute, and change the name of child
nodes by using the XmlElement attribute and setting its ElementName.
Multiple properties can be specified for an attribute by separating them with commas
within the parenthesis. This usually takes the form [attributename(property1=value1,
property2=value2…)]
[XmlRoot("XTest")]
public class Test
{
[XmlElement(ElementName="V1")]
public String value1;

[XmlElement(“V2")]
public String value2;
}
Note that when specifying the element name, the property name can be omitted.

17.5 XML Schema

1. While an XML file might conform to the XML specification, it might not be a valid form
of a particular dialect. An XML schema help to verify that certain elements are present,
while making sure that the values presented are of the correct type.
2. There are a few different specifications of schemas: XSD, DTD, and XSX. Though DTD
(Document Type Definition) is the most common schema used today, XSD (XML
Schema Definition) is a newer standard that's gaining acceptance, as it provides the finest
grained control for XML validation.
3. XML Schema is commonly known as XML Schema Definition (XSD) which is used to
describe and validate the structure and the content of XML data.
4. XML schema defines the elements, attributes and data types.
5. Schema element supports Namespaces. It is similar to a database schema that describes
the data in a database.
6. The basic idea behind XML Schemas is that they describe the legitimate format that an
XML document can take.
7. Syntax
- Declare a schema in XML document as,
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

17 - 16 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Example

The following example shows how to use schema :


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="contact">
<xs:complexType>
<xs:sequence>
<xs:element name="Book name" type="xs:string" />
<xs:element name="Publication" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Elements
An element can be defined within an XSD as,
<xs:element name="ele" type="y"/>
Definition Types
XML schema elements can be defined as follows.
- Simple Type - Simple type element is used only in the context of the text. Some of
predefined simple types are: xs:integer, xs:boolean, xs:string, xs:date. For example :
<xs:element name="author_number" type="xs:int" />
- Complex Type - A complex type is a container for other element definitions. This
allows to specify which child elements an element can contain and to provide some
structure within XML documents.
For example :
<xs:element name="Location">
<xs:complexType>
<xs:sequence>
<xs:element name="author" type="xs:string" />
<xs:element name="publication" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
In the above example, Location element consists of child elements. This is a container for
other <xs:element> definitions, that allows to build a simple hierarchy of elements in the
XML document.

17 - 17 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

- Global Types - With global type, one can define a single type in document, which can
be used by all other references.
For example, suppose the author and publication are to be generalized for different
locations of the publication. In such case, define a general type as below :
<xs:element name="LocationType">
<xs:complexType>
<xs:sequence>
<xs:element name="author" type="xs:string" />
<xs:element name="publication" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
- Attributes
Attributes in XSD provide extra information within an element. Attributes have name and
type property as shown below :
<xs:attribute name="x" type="y"/>
Generating XML schema
The XML Schema Definition tool (Xsd.exe) allows to generate an XML schema that
describes a class or to generate the class defined by an XML schema.
8. To generate scheme specific classes

1. Go to command prompt.
2. Pass the XML Schema as an argument to the XML Schema Definition tool, which
creates a set of classes that are precisely matched to the XML Schema, for example:
3. xsd mySchema.xsd
The tool can only process schemas that reference the World Wide Web Consortium XML
specification of March 16, 2001. In other words, the XML Schema namespace must be
"http://www.w3.org/2001/XMLSchema" as shown in the following example.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified"
argetNamespace="" xmlns:xs="http://www.w3.org/2001/XMLSchema">
4. Modify the classes with methods, properties, or fields, as necessary. For more
information about modifying a class with attributes, see Controlling XML Serialization
Using Attributes and Attributes That Control Encoded SOAP Serialization.

17 - 18 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

"XSD" is currently the de facto standard for describing XML documents. There are 2
versions in use 1.0 and 1.1, which are on the whole the same. An XSD schema is itself an
XML document, there is even an a XSD schema to describe the XSD standard.
It is often useful to examine the schema of the XML stream that is generated when
instances of a class (or classes) are serialized. For example, one might publish the schema for
others to use, or might compare it to a schema with which one is trying to achieve conformity.
9. To generate an XML Schema document from a set of classes

1. Compile the class or classes into a DLL.


2. Open a command prompt.
3. Pass the DLL as an argument to Xsd.exe, for example:
4. xsd MyFile.dll
5. The schema (or schemas) will be written, beginning with the name
schema0.xsd".
Example

Sample XSD Sample XML

1. <xs:element name=" Author _dob" 1. <Author_dob>


2. type="xs:date"/> 2. 2000-01-12T12:13:14Z
3. </Author_dob>
1. <xs:element name=" Author _address" 1. < Author _address>
2. type="xs:string"/> 2. 1,MG Marg Camp
3. </ Author _address>
1. <xs:element name="AuthorID" 1. <AuthorID>
2. type="xs:int"/> 2. 2610
3. </AuthorID>
1. <xs:element name="Content" 1. <Content>
2. type="xs:string"/> 2. (a type can be defined as
3. a string but not have any
4. content; this is not true
5. of all data types, however).
6. </Content>

17 - 19 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

10. XML Schema Validation

Validation event handler


The ValidationEventHandler event is used to define an event handler for receiving the
notification about XSD schema validation errors. The validation errors and warnings are
reported through the ValidationEventHandler call-back function. If any validation error
occurs, an exception is thrown, and the XmlValidatingReader cannot be restarted.
XML validation with .NET classes
Microsoft .NET framework classes support the W3C XML schema recommendation. The
classes used to validate the XML document are XmlTextReader, XmlSchemaCollection, and
XmlValidatingReader. The sequence of steps to validate an XML document is given as
follows :
1. The ValidationHandler event handler method is defined.
2. The XSD schema is being parsed using XmlTextReader class.
3. The parsed schema is added to the schema collection using XmlSchemaCollection class.
4. The schema collection is associated with XmlValidatingReader class.
5. The event handler method is associated with XmlValidatingReader class.
6. XmlValidatingReader class validates the XML document using the namespace URI
specified when the schema was added to the collection.
Validation Process
1. Using the XmlValidatingReader class, one can easily validate an XML file against a
schema file. However, there are a few other classes required to be used first.
2. The XmlValidatingReader object can be pointed towards the schema files to be used, by
filling an XmlSchemaCollection with schema files as shown below,
XmlSchemaCollection xsdCollection = new XmlSchemaCollection();
xsdCollection.Add("schemafile", "schema.xsd");
In this example, the schema is contained in the file schema.xsd.
3. The actual XmlValidatingReader class takes an XmlReader in its constructor.
Consequently, an XmlTextReader is created and filled with the XML file required to be
validated,
XmlTextReader reader;

XmlValidatingReader validatingReader;

reader = new XmlTextReader("first.xml");

validatingReader = new XmlValidatingReader(reader);

17 - 20 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

4. Now, schemaCollection is added to the schemas so that the validation reader can use
them.
validatingReader.Schemas.Add(xsdCollection);
5. If an error is found by the validator, an event is fired which should be caught by creating
an event handler, and code so as to respond to the errors,
validatingReader.ValidationEventHandler += new
alidationEventHandler(validationCallBack);

public void validationCallBack (object sender, ValidationEventArgs args)


{
Response.Write("Error:" + args.Message);
}
6. Finally, using the Read method the file can be validated, on the validating reader.
The nodes can be read and processed in the file individually , but, for the validating
purposes, empty while loop to step through the file is also sufficient.
while (validatingReader.Read()){}
7. As errors are found during file processing, the event can be caught and handled through
the validationCallBack method.
Example
//illustration of validating XML document against XSD schema
using System;
using System.Collections;
using System.Data;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Text;

public class XMLValidator


{
// Validation Error Count
static int ErrorsCount = 0;

// Validation Error Message


static string ErrorMessage = "";

public static void ValidationHandler(object sender,


ValidationEventArgs args)
{
ErrorMessage = ErrorMessage + args.Message + "\r\n";
ErrorsCount ++;
}

17 - 21 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

public void Validate(string strXMLDoc)


{
try
{
// Declare local objects
XmlTextReader xtr = null;
XmlSchemaCollection xscl = null;
XmlValidatingReader xvr = null;

// Text reader object


xtr = new XmlTextReader(urlpath);
xscl = new XmlSchemaCollection();
xscl.Add(null, xtr);

// XML validator object

xvr = new XmlValidatingReader( strXMLDoc,


XmlNodeType.Document, null);

xvr.Schemas.Add(xscl);

// Add validation event handler

xvr.ValidationType = ValidationType.Schema;
xvr.ValidationEventHandler +=
new ValidationEventHandler(ValidationHandler);

// Validate XML data


while(xvr.Read());
xvr.Close();
// Raise exception, if XML validation fails
if (ErrorsCount > 0)
{
throw new Exception(ErrorMessage);
}
// XML Validation succeeded
Console.WriteLine("XML validation succeeded.\r\n");
}
catch(Exception error)
{
// XML Validation failed
Console.WriteLine("XML validation failed." + "\r\n" +
"Error Message: " + error.Message);
}
}
}

17 - 22 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

17.6 XML Style Sheet and Transformation

1. If there is one type of XML and need to transform it to another type, then XSLT can be
used for that purposes. XML Stylesheet Transformation(XSLT) is defined as a language
for converting xml documents to other document formats. XSLT processors parse the
input XML document, as well as the XSLT stylesheet and then process the instructions
found in the XSLT stylesheet, using the elements from input XML document. During the
processing of the XSLT instructions, a structured XML output is created.

Fig. 17.6.1 XML stylesheet processing

2. XML stylesheet processing

1. Since XML is used for data representation, it cannot be used for displaying formatted
data. To display formatted data, it uses stylesheet.
2. There are two types of stylesheets, Extensible Stylesheet Language (XSL) and
Cascading Stylesheets (CSS). XSL is a superset of CSS. It supports various functions
which are not supported by CSS. For example, CSS cannot be used to sort elements or do
conditional formatting. Also XSL is written in a different syntax from CSS. XSL follows
the syntax of XML.
3. Following are some of the elements of XSL :
Stylesheet : An XSL file has <stylesheet> as the root element. It is written as follows:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
template : The <template> element is used to specify the formatting rules to be applied
when a particular node is matched. It is written as follows:
<xsl:template match="/">

17 - 23 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

for-each : The <for-each> element is used to loop through a particular XML element. It is
written as follows:
<xsl:for-each select="employees/emp">
value-of : The <value-of> element is used to display the value of a selected node. If the
node is an attribute, it is prefixed with @.
<xsl:value-of select="@id"/>
3. Static and dynamic transformation

An XML file can be transformed statically or dynamically. For statically linking an XML
file to a stylesheet, the following Processing Instruction can be used :
<?xml-stylesheet type="text/xsl" href="filename.xsl"?>
An XML file can be dynamically linked to a stylesheet by using an instance of the
XslCompiledTransform class.
Example
-The .xml file to be transformed.
Books.xml
<?xml version="1.0" encoding="utf-8" ?>
<Books>
<book>
<name>C#</name>
<cost>Rs 500</cost>
</book>
<book>
<name>ASP</name>
<cost>Rs 550</cost>
</book>
</Books>
-Now, frame an XSLT document for the above XML.
Book.xsl
<?xml version="1.0" encoding="iso-8859-1" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<table border="1">
<tr>
<th>Name</th>
<th>Price</th>
</tr>
<xsl:for-each select="Books/book">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="cost"/></td>

17 - 24 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>

4. The transformation part

Tthe XmlUrlResolver and XslTransform class are used to perform the transformation.
XmlUrlResolver class is used to resolve external XML resources such as entities, document
type definitions (DTDs), or schemas. It is also used to process, the include and import
elements found in Extensible StyleSheet Language (XSL) stylesheets or XML Schema
Definition language (XSD) schemas.
The transformation code,
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
XslTransform xsltrans=new XslTransform();
xsltrans.Load( ,resolver);
xsltrans.Transform( , ,resolver);
The Load method is use to load an XSLT document. This method can accept an
XmlReader, a document URL, or a variety of other objects. Then the Transform method is
called. This method is overloaded and can therefore accept a variety of parameters.
The output -

Name Price
C# R.S 500
ASP R.S 500

17.7 Searching XML File using XPATH

1. Searching XML file using XPATH and using Attribute names


To find nodes in an XML file XPath expressions can be used.
Method XmlNode.SelectNodes returns a list of nodes selected by the XPath string.
Method XmlNode.SelectSingleNode finds the first node that matches the XPath
string.
Consider XML file given below,
[XML]
<Names>
<Name>
<FirstName>Ravindra</FirstName>

17 - 25 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

<LastName>Wani</LastName>
</Name>
<Name>
<FirstName>Prakash</FirstName>
<LastName>Deshmukh</LastName>
</Name>
</Names>
To get all <Name> nodes use XPath expression /Names/Name.
The first slash means that the <Names> node must be a root node.
SelectNodes method returns collection XmlNodeList which will contain the <Name>
nodes.
To get value of sub node <FirstName> one can simply index XmlNode with the node
name : xmlNode["FirstName"].InnerText.
Example
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString); // suppose that myXmlString contains
<Names>...</Names>"

XmlNodeList xnList = xml.SelectNodes("/Names/Name");


foreach (XmlNode xn in xnList)
{
string firstName = xn["FirstName"].InnerText;
string lastName = xn["LastName"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
}
Output
Name: Ravindra Wani
Name: Prakash Deshumkh

2. Select XML Nodes by Attribute Value


XML nodes can be selected from XML document by attribute value. For this, use
method XmlNode.SelectNodes to get list of nodes selected by the XPath expression.

Consider XML file below.


[XML]
<Names>
<Name type="M">Ravindra</Name>
<Name type="F">Anu</Name>
<Name type="M">Prakash</Name>
</Names>
To get all name nodes use XPath expression /Names/Name.

17 - 26 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

To get only male names (to select all nodes with specific XML attribute) use XPath
expression /Names/Name[@type='M'].
The code -
XmlDocument xml = new XmlDocument();
xml.LoadXml(str); // suppose that str string contains "<Names>...</Names>"

XmlNodeList xnList = xml.SelectNodes("/Names/Name[@type='M']");


foreach (XmlNode xn in xnList)
{
Console.WriteLine(xn.InnerText);
}
Output
Ravindra
Prakash
Select Top XML Nodes using XPath
To select nodes from XML use method XmlNode.SelectNodes. Pass XPath expression as a
parameter and the method returns a list of selected nodes.
Consider the XML file below,
[XML]
<Names>
<Name>Ravi</Name>
<Name>Shyam</Name>
<Name>Avi</Name>
<Name>Lucky</Name>
<Name>Sandy</Name>
<Name>Sam</Name>
<Name>Niru</Name>
</Names>
To get all <Name> nodes use XPath expression /Names/Name.
If all nodes are not to be selected, but only top 5 nodes, uses XPath expression,
/Names/Name[position() <= 5].
Example
XmlDocument xml = new XmlDocument();
xml.LoadXml(str); // suppose that str string contains "<Names>...</Names>"

XmlNodeList xnList = xml.SelectNodes("/Names/Name[position() <= 5]");


foreach (XmlNode xn in xnList)
{
Console.WriteLine(xn.InnerText);
}

17 - 27 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Output
Ravi
Shyam
Avi
Lucky
Sandy

17.8 XML and ADO.NET for Handling Data

There are two approaches to work with XML and ADO, namely, one, use ADO.NET to
access XML documents or two, use XML and ADO.NET to access XML. Also, relational
database can be accessed using ADO.NET and XML.NET.
Reading XML using Data Set
The DataSet class can be used to access data. This class implements methods and
properties to work with XML documents.
- The Read xml Method

ReadXml is an overloaded method; used for reading a data stream, TextReader,


XmlReader, or an XML file and to store into a DataSet object, which can later be used to
display the data in a tabular format. The ReadXml method has eight different overloaded
forms. It can read a text, string, stream, TextReader, XmlReader, and their combination
formats. Remember to add a reference to System.Data and the System.Data.Common
namespace before using DataSet and other common data components.
Example
//1. Create a DataSet object
DataSet ds = new DataSet();
// 2. Fill with the data with file
ds.ReadXml("media.xml");
The ReadXmlSchema method

The ReadXMLSchema method reads an XML schema in a DataSet object (which has four
overloaded forms) with which Text Reader, string, stream, and XmlReader can be used
Example
//illustrates how to use a file as direct input and call the ReadXmlSchema method to read
he file

DataSet ds = new DataSet();


ds.ReadSchema(@"c:\media.xml");

17 - 28 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Example
//illustration of reading the file XmlReader and use XmlTextReader as the input of
/ReadXmlSchema

//Create a dataset object


DataSet ds = new DataSet("New DataSet");
// Read xsl in an XmlTextReader
XmlTextReader myXmlReader = new XmlTextReader(@"c:\media.Xml");
// Call Read xml schema
ds.ReadXmlSchema(myXmlReader);
myXmlReader.Close();
Writing XML using Data Set
The DataSet class contains methods to write XML file from a DataSet object and fill the
data to the file.
The Writexml Method
The WriteXml method writes the current data (the schema and data) of a DataSet object to
an XML file. This is overloaded method. By using this method, data can be written to a file,
stream, TextWriter, or XmlWriter.
Example
//illustration writing the data to an XML file using DataSet
using System;
using System.IO;
using System.Xml;
using System.Data;
namespace XmlandADO
{
class XmlAndDataSetDemo
{
public static void Main()
{
Try
{
// Create a DataSet, namespace and Media table
// with Name and Type columns
DataSet ds = new DataSet("DS");
ds.Namespace = "StdNamespace";
DataTable mdTable = new DataTable("Media");
DataColumn col1 = new DataColumn("Name");
DataColumn col2 = new DataColumn("Type");
mdTable.Columns.Add(col1);
mdTable.Columns.Add(col2);
ds.Tables.Add(mdTable);
//Add media Data to the table

17 - 29 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

DataRow newRow; newRow = mdTable.NewRow();


newRow["Name"] = "C# Guide";
newRow["Type"] = "Book";
mdTable.Rows.Add(newRow);
newRow = mdTable.NewRow();
newRow["Name"] = "XML";
newRow["Type"] = "CD";
mdTable.Rows.Add(newRow);
newRow = mdTable.NewRow();
ds.AcceptChanges();
// Create a new StreamWriter
System.IO.StreamWriter mdStreamWriter = new
System.IO.StreamWriter(@"c:\mediaData.xml");

// Writer data to DataSet which actually creates the file


ds.WriteXml(mdStreamWriter);
mdStreamWriter.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e.ToString());
}
return;
}
}
}
Output of above code snippet
<?xml version="1.0" ?>
<DS xmlns="StdNamespace">
<Media>
<Name>C# Guide</Name>
<Type>Book</Type>
</Media>
<Media>
<Name>XML</Name>
<Type>CD</Type>
</Media>
</DS>

17.9 Manipulating XML using SAX and DOM

An XML parser is a software library or package that provides interfaces for client
applications to work with an XML document. The XML Parser is designed to read the

17 - 30 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

XML and create a way for programs to use XML. XML parser validates the document and
check that the document is well formatted. XML parsers can be of two main types
DOM parser or SAX parser.
17.9.1 The DOM Approach

A DOM document is an object which contains all the information of an XML document.
It is composed like a tree structure. The DOM Parser implements a DOM API. This API is
very simple to use.
17.9.1.1 Features of DOM Parser

A DOM Parser creates an internal structure in memory which is a DOM document object
and the client applications get information of the original XML document by invoking
methods on this document object.
DOM Parser has a tree based structure.
Advantages

1) It supports both read and write operations and the API is very simple to use.
2) It is preferred when random access to widely separated parts of a document is required.
Disadvantages

1) It is memory inefficient. (consumes more memory because the whole XML document
needs to loaded into memory).
2) It is comparatively slower than other parsers.
Manipulating the contents of an XML document includes traversing the list of nodes
in the document, setting and querying attribute values, and manipulating the tree
itself by creating and inserting new nodes. This section discusses XML documents
manipulation using the Document Object Model (DOM) modeled by the
XmlDocument class in the System.Xml namespace. The DOM is recursive, meaning
that each node has the same properties and methods as every other node in the
document.
17.9.1.2 Important Basic XML Related Concepts

1. XSL - Extensible Stylesheet Language, is designed for expressing stylesheets for


XML documents. XSL is to XML as CSS is to HTML.
2. XML Transformation - is a user-defined algorithm that transforms a given XML
document to another format, such as XML, HTML, XHTML. The algorithm is
described by XSL.

17 - 31 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

3. XSLT - is designed for use as part of XSL, transforming an XML document into
another XML document, or another type of document that is recognized by a
browser, like HTML or XHTML. XSLT uses XPath.
4. XPath - is a set of syntax rules for defining parts of an XML document.
17.9.1.3 XMLNode Class
XMLNode class is used to manipulate nodes in DOM. The XML node is the most basic
unit of abstraction within a DOM-modeled document.
Commonly Used XmlNode Properties
Attributes - The attributes of the node (XmlAttributeCollection).
ChildNodes - The list of child nodes of the current node (XmlNodeList).
FirstChild - Returns the first child of the XML node (first being first in document
order).
HasChildNodes - A Boolean that indicates whether the node has child nodes.
InnerText - Gets or sets the text inside the node.
InnerXml - Gets or sets the XML within the node.
LastChild - Returns the last child (document order relative) of the node.
Name - The name of the node.
NodeType - Indicates the type of the node. This can be several things, including (but
not limited to): Document, DocumentFragment, Element, EndElement, Entity,
Notation, Text, Whitespace, or XmlDeclaration.
OuterXml - The XML representing the current node and all its child nodes.
OwnerDocument - The document to which the current node belongs.
ParentNode - The parent node of the current node, if any.
PreviousSibling - Gets the node immediately preceding the current node in document
order.
Value - Gets or sets the value of the current node.
Commonly Used XmlNode Methods
AppendChild - Adds a child node to the end of the current list of child nodes.
Clone - Creates a duplicate of the node.
CreateNavigator - Creates an XPathNavigator for this node.
InsertAfter - Inserts the given node immediately after the current node.
InsertBefore - Inserts the given node immediately before the current node.
PrependChild - Adds the given child node at the beginning of the child node list.

17 - 32 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

RemoveAll - Removes all child nodes.


RemoveChild - Removes the given child from the current node.
SelectNodes - Selects a list of nodes matching the XPath expression (discussed in the
following section).
SelectSingleNode - Selects a single node that matches the XPath expression.
17.9.1.4 XMLDocument Class

The XmlDocument class, deals with the entire document, is also itself an XmlNode. The
XmlDocument class, inherits from XmlNode. This fits with the DOM pattern in that the
document is a node that can have child nodes. The methods in the following list show
some of the additional methods available to the XmlDocument that are not part of a
standard node class.
XmlDocument Class Methods
CreateAttribute - Creates an XmlAttribute with the given name.
CreateCDataSection - Creates a CData section with the given data.
CreateComment - Creates an XmlComment.
CreateDocumentFragment - Creates a document fragment.
CreateElement - Creates an XmlElement, an XmlNode with element-specific
functionality.
CreateNode - Creates an XmlNode.
CreateTextNode - Creates an XmlText node.
CreateWhitespace - Creates whitespace for insertion into the document.
ImportNode - Imports a node from another document.
Load - Loads the XML from the given file.
LoadXml - Loads the XML from the given XML string.
Save - Saves the XML document.
Validate - Validates the XML document against a schema.
Program 1
//Add node/xml value to existing XML
string tempXml = @"<states>
<State ID='1' Name='Punjab' />
< State ID='2' Name=' Rajasthan' />
< State ID='3' Name=' Gujrat' />
< State ID='4' Name=' Maharashtra' />
< State ID='5' Name=' Tamilnadu' />
</State>";

17 - 33 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Program 2
// to illustrate different ways to add the node, using XMLDocument and XDocument
class.
Using XmlDocument
// Option1: Using InsertAfter()
// Adding Node to XML
XmlDocument docstate1 = new XmlDocument();
docstate1.LoadXml(tempXml);
XmlNode root1 = docstate1.DocumentElement;
//Create a new attrtibute.
XmlElement elem = docstate1.CreateElement("State");
XmlAttribute attr = docstate1.CreateAttribute("ID");
attr.Value = "6";
elem.Attributes.Append(attr);
//Create a new attrtibute.
XmlAttribute attr2 = docstate1.CreateAttribute("Name");
attr2.Value = "Karnatak";
elem.Attributes.Append(attr2);
//Add the node to the document.
root1.InsertAfter(elem, root1.LastChild);
docstate1.Save(Console.Out);
Console.WriteLine();

// Option2: Using AppendChild()


XmlDocument docstate2 = new XmlDocument();
docstate2.LoadXml(tempXml);
XmlElement XEle = docstate2.CreateElement("State");
XEle.SetAttribute("Name", "Karnatak");
XEle.SetAttribute("ID", "6");
docstate2.DocumentElement.AppendChild(XEle.Clone());
docstate2.Save(Console.Out);
Console.WriteLine();

Output of above Program2


<?xml version="1.0" encoding="IBM437"?>
<States>
<State ID='1' Name='Punjab' />
< State ID='2' Name=' Rajasthan' />
< State ID='3' Name=' Gujrat' />
< State ID='4' Name=' Maharashtra' />
< State ID='5' Name=' Tamilnadu' />
< State ID='6' Name=' Karnatak' />

</State>

17 - 34 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Program 3
//Edit/Update XML data - to change/update XML node value
Using XDocument
// Option1: Using SetAttributeValue()
XDocument xmlDoc = XDocument.Parse(tempXml);
// Update Element value
var items = from item in xmlDoc.Descendants("State")
where item.Attribute("ID").Value == "3"
select item;
foreach (XElement itemElement in items)
{
itemElement.SetAttributeValue("Name", "NewGujrat");
}
xmlDoc.Save(Console.Out);
Console.WriteLine();

// Option2: Using Attribute.Value()


var doc = XElement.Parse(tempXml);
var target = doc.Elements("State")
.Where(e => e.Attribute("ID").Value == "2")
.Single();
target.Attribute("Name").Value = "NewRajasthan";
doc.Save(Console.Out);
Console.WriteLine();
// Option3: Using ReplaceWith()
XDocument xmlDoc1 = XDocument.Parse(tempXml);
XElement xObj = xmlDoc1.Root.Descendants("State").FirstOrDefault();
xObj.ReplaceWith(new XElement("Project", new XAttribute("ID", "1"),
new XAttribute("Name", "New_Punjab")));
xmlDoc1.Save(Console.Out);
Console.WriteLine();
Program 4
//Using XmlDocument
int nodeId = 2;
XmlDocument xmlDocstate = new XmlDocument();
xmlDocstate.LoadXml(tempXml);
//node["Node2"].InnerText = "Value2";
XmlNode node = xmlDocstate.SelectSingleNode("/States/State[@ID=" + nodeId + "]");
node.Attributes["Name"].Value = "State2_Update";
xmlDoc1.Save(Console.Out);
Console.WriteLine();

17 - 35 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Program 5
Select node value from XML

When XML data is used, data is fetched based on the node value. Suppose it is required to
get the state name whose ID is 2. For this XMLDocument class or
XDocument(System.XML.Linq namespace) can be used.
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(tempXml);
int nodeId = 2;
XmlNode nodeObj = xmldoc.SelectSingleNode("/States/State[@ID=" + nodeId + "]");
//string id = nodeObj["State"].InnerText; // For inner text
string pName = nodeObj.Attributes["Name"].Value;

// Select Node based on XPath


XmlNodeList xnList = xmldoc.SelectNodes("/States/State");
foreach (XmlNode xn in xnList)
{
string stateName = xn.Attributes["Name"].Value;
}
// Select nodes by TagName
XmlNodeList nodeList = xmldoc.GetElementsByTagName("State");
foreach (XmlNode node in nodeList)
{
var ID = node.Attributes["ID"].Value;
var Name = node.Attributes["Name"].Value;
}

17.9.1.5 XmlDocument vs XDocument

XmlDocument or XDocument classes are widely used to manipulate XML data. However,
there are some differences between them as listed below,
XDocument(System.Xml.Linq) is from the LINQ to XML API and
XmlDocument(System.Xml.XmlDocument) is the standard DOM-style API for XML.
If .NET version 3.0 or lower is used, then XmlDocument I to be used, the classic DOM
API. On the other hand, while using .NET version 3.5 onwards, XDocument should be
used.
Performance wise XDocument is faster than XmlDocument because it (XDocument) is
newly developed to get better usability with LINQ. It's (XDocument) much simpler to
create documents and process them.

17 - 36 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

17.9.2 SAX Approach

SAX (Simple API for XML) is a serial access parser API for XML. SAX provides a
mechanism for reading data from an XML document. It is a popular alternative to the DOM.
SAX parser for XML processing is a parser which implements SAX (SAX parser) functions as
a stream parser, with an event-driven API. The user defines a number of call back methods
that will be called when event occur during parsing.
The SAX events include,
a) XML text nodes.
b) XML element nodes.
c) XML processing instructions.
d) XML comments.
A SAX Parser implements SAX API. This API is an event based API and less intuitive.
17.9.2.1 Features of SAX Parser

It does not create any internal structure.


Clients does not know what methods to call, they just overrides the methods of the API
and place his own code inside method.
It is an event based parser, it works like an event handler in Java.
Advantages
1) It is simple and memory efficient.
2) It is very fast and works for huge documents.
Disadvantages
1) It is event-based so its API is less intuitive.
2) Clients never know the full information because the data is broken into pieces.
17.9.2.2 Writing XML file via SAX

SAX (stands for Simple API for XML) is actually a simple extension of the text file reader.
Writing is simple in which the elements and attributes are written in the same order as they are
present in the file (the tree structure is ignored in this approach). .NET provides the
XmlWriter class to carry writing into the XML though it is a text file. It works around the
elements, more accurately, nodes. This class is in the System.Xml namespace.
17.9.2.3 XmlTextWriter Class

Now in order to use SAX, XmlTextWriter object is to be instantiated. XmlTextWriter has


three constructors overload as follows :

17 - 37 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Constructor Description

Creates an instance of the XmlTextWriter


XmlTextWriter (TextWriter)
class using the specified TextWriter.

Creates an instance of the XmlTextWriter


XmlTextWriter (Stream, Encoding)
class using the specified stream and encoding.

Creates an instance of the XmlTextWriter


XmlTextWriter (String, Encoding)
class using the specified file and encoding.

Example
//the classfile for writing in to xml file
using System.xml;
class User
{
public string Name { get; private set; }
public int Age { get; private set; }
public DateTime Registered { get; private set; }

public User(string name, int age, DateTime registered)


{
Name = name;
Age = age;
Registered = registered;
}
public override string ToString()
{
return Name;
}
}
// a collection of test users
List<User> users = new List<User>();
users.Add(new User("Ravi", 42, new DateTime(2020, 3, 1)));
users.Add(new User("Ram", 41, new DateTime(2020, 4, 2)));
users.Add(new User("Raj", 40, new DateTime(2020, 6, 3)));

// the XmlWriter settings


XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;

// writes the users


using (XmlWriter xw = XmlWriter.Create(@"users.xml", settings))
{
xw.WriteStartDocument(); // the header

17 - 38 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

xw.WriteStartElement("users"); // opens the root users element

// writes individual users


foreach (User u in users)
{
xw.WriteStartElement("user");
xw.WriteAttributeString("age", u.Age.ToString());
xw.WriteEndElement();
}

xw.WriteEndElement(); // closes the root element


xw.WriteEndDocument(); // closes the document
xw.Flush();
}

Below is the output of the file users.xml


<?xml version="1.0" encoding="utf-8"?>
<users>
<user age="42" />
<user age="41" />
<user age="40" />
</users>

17.9.2.4 Reading XML via SAX

Reading is performed just like writing. XML as a text file is read line by line, from top to
bottom. SAX gives what are known as nodes (XMLNode) which it gets while reading. A node
can be an element, an attribute, or a value. The nodes are received in a loop in the same order
that they're written in the file. The .NET framework provides the XmlReader class is used to
read XML files. This class is in the System.Xml namespace.
Example
//Reading XML file
//Below is XML file to be parsed, users.xml
<?xml version="1.0" encoding="utf-8"?>
<users>
<user age="42">
<name>Ravi </name>
<registered>3/2/2020</registered>
</user>
<user age="41">
<name>Raj </name>
<registered>2/1/2020</registered>
</user>
<user age="42">

17 - 39 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

<name>Ram </name>
<registered>1/2/2020</registered>
</user>
</users>
User.cs class is as below,
class User
{
public string Name { get; private set; }
public int Age { get; private set; }
public DateTime Registered { get; private set; }

public User(string name, int age, DateTime registered)


{
Name = name;
Age = age;
Registered = registered;
}
public override string ToString()
{
return Name;
}
}
The XML file reading code is as below,
using (XmlReader xr = XmlReader.Create(@"users.xml"))
{
string name = "";
int age = 0;
DateTime registered = DateTime.Now;
string element = "";
while (xr.Read())
{
// reads the element
if (xr.NodeType == XmlNodeType.Element)
{
element = xr.Name; // the name of the current element
if (element == "user")
{
age = int.Parse(xr.GetAttribute("age"));
}
}
// reads the element value
else if (xr.NodeType == XmlNodeType.Text)
{
switch (element)

17 - 40 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

{
case "name":
name = xr.Value;
break;
case "registered":
registered= DateTime.Parse(xr.Value);
break;
}
}
// reads the closing element
else if ((xr.NodeType == XmlNodeType.EndElement) && (xr.Name == "user"))
users.Add(new User(name, age, registered));
}
}

17.9.3 DOM vs SAX

Sr. No. DOM SAX

1. Stores the entire XML document into Parses node by node.


memory before processing.

2. Nodes can be inserted or deleted. Nodes can not be inserted or deleted.

3. Stores entire document in the memory Does not store XML in memory, It is
before processing, Occupies more memory, no compulsory for the entire xml tree
The entire xml tree must be in memory to be loaded before the parser begins to
before the parser begins to parse. parse, it can work with the maximum
depth of the given xml tree.

4. Traversing can be done in any direction. Traversing can be done top to bottom.

5. There are formal specifications for the There aren't formal specifications
DOM. within SAX.

6. Streamed reading from the disk is Streamed reading from the disk is
impossible. possible.

7. Less problems during the XML validation. More problems during the XML
validation.

8. It is not event triggered parser. It is event triggered parser.

17 - 41 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Two Marks Questions with Answers

Q.1 What are the features of XML ?


Ans. : Main features of XML are :
• Very easy to learn and implement.
• XML files are text files, and no editor is required.
• Minimal and a limited number of syntax rules in XML.
• It is extensible, and it specifies that structural rules of tags.
Q.2 Which tag is used to find the version of XML and the syntax ?
Ans. : Declaring the XML version is very important for each XML document and platform
needs to be specified in which it is running.
<?xml version=”1.1” encoding=”|ISO-8859-1|”?>
Q.3 What is XML DOM Document ?
Ans. : XML Document object represents the whole XML document, and it is the root of a
document tree. It gives access to entire XML document – Nodes and Elements, and it has
its own properties.
Q.4 What is XPath ?
Ans. : XPath is used to find information in an XML document and contains standard
functions. XPath is the major element in XSLT, and it is w3c recommendation.
Q.5 What is an attribute ?
Ans. : An attribute provides more or additional information about an element than
otherwise.
Example -
<Person name = ‘‘Bharat” >
Q.6 Define XML. Give example. AU : Dec.-17
Ans. : Extensible Markup Language (XML) is used to describe data. The XML
standard is a flexible way to create information formats and electronically share
structured data via the public Internet, as well as via corporate networks.
The basic building block of an XML document is an element, defined by tags.

For example,

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


<conversation>
<greeting>Hello!</greeting>
<response>It is AUT Question Paper !</response>
</conversation>

17 - 42 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

Long Answered Questions

Q.1 Discuss XML. (Refer section 17.1)


Q.2 What is XML element ? (Refer section 17.2)
Q.3 How to manipulate XML using DOM ? (Refer section 17.9)
Q.4 How to manipulate XML using SAX ? (Refer section 17.9)
Q.5 What is XML schema ? (Section 17.5)

XML, Manipulating XML, SAX and DOM ends …

17 - 43 C# and .NET Programming


XML, Manipulating XML, SAX and DOM

17 - 44 C# and .NET Programming


C# and .NET Framework - Introduction

Syllabus : Peer-to-Peer Networking, Building P2P Applications, PNRP.

Section No. Topic Name Page No.


18.1 Peer-to-Peer (P2P) Networking - Introduction 18 - 2

18.2 P2P Terminology 18 - 2

18.3 P2P Architectural Challenges 18 - 3

18.4 Uses of P2P Network 18 - 4

18.5 Benefits of a P2P Network 18 - 4

18.6 PNRP - Peer Name Resolution Protocol 18 - 5

18.7 Building P2P Application 18 - 13

18.8 Application Model for Peer-to-Peer 18 - 22

18.9 Firewalls and Ports 18 - 23

Two Marks Questions with Answers 18 - 23

Long Answered Questions 18 - 24

18 - 1 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

18.1 Peer-to-Peer (P2P) Networking - Introduction

P2P stands for Peer-To-Peer. A P2P network is created when two or more computers are
connected and share resources without going through a separate server computer. All
computers in a P2P network have the equal privilege. In a P2P network, a computer is
both a server and client. There is no need for central coordination. A computer in a P2P
network is usually called a node.

Fig. 18.1.1 A typical Peer to Peer Network

18.2 P2P Terminology

In P2P network peer is how clients are referred to. The word "client" makes no sense in
a P2P network because there is not necessarily a 'server' to be a client of.
Groups of peers that are connected to each other are known by the interchangeable
terms meshes, clouds, or graphs. A given group can be said to be well-connected if,
1. There is a connection path between every pair of peers, so that every peer can
connect to any other peer as required.
2. There are a relatively small number of connections to traverse between any pair of
peers.
3. Removing a peer will not prevent other peers from connecting to each other.
It should be noted that this does not mean every peer must be able to connect to every
other peer. In fact, if a network is closely mathematically analyzed it will be found that

18 - 2 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

peers need to connect only to a relatively small number of other peers in order for these
conditions to be met.

18.3 P2P Architectural Challenges

Main challenge in P2P network is discovering the potential clients in the network and
locating chunks of the file that other clients might have. Another challenge is finding
optimal communication between clients that may be separated by entire continents.
Every client participating in a P2P network application must be able to perform the
following operations to overcome these problems,
1. It must be able to discover other clients.
2. It must be able to connect to other clients.
3. It must be able to communicate with other clients.
The discovery problem has two obvious solutions. One is to keep the list of the clients
on the server so that all the clients can obtain this list and contact other clients (known
as peers). Another way is to maintain A PNRP (Peer Name Resolution Protocol)
infrastructure so as to discover the clients in the network. Most file sharing systems use
the "list on a server" solution, by using servers know as trackers. Also, in file sharing
systems any client may act as a server declaring that it has a file available and
registering it with a tracker. In fact, a pure P2P network needs no server at all, just peers
are sufficient to work in the network.
The connection problem is a more critical one, and concerns the overall structure of the
networks used by a P2P application. If there is one group of clients, all of which can
communicate with one another, the topology of the connections between these clients
can become extremely complex. The performance can be improved by having more than
one group of clients, each of which consists of connections between clients in that
group, but not to clients in other groups, a kind of hierarchical network. Locale-based
groups can be build to get an additional performance boost, because clients can
communicate with each other with fewer hops between networked computers.
Communication is perhaps a problem of lesser importance, because communication
protocols such as TCPlIP are well established and can be reused here. There is,
however, scope for improvement in both high-level technologies (for example, WCF
services can be used and therefore all the functionality that WCF offers) and low-level
protocols (such as multicast protocols to send data to multiple endpoints
simultaneously).
Discovery, connection, and communication are central to any P2P implementation.

18 - 3 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

Apart from above concerns P2P network should be aware of is that of flooding.
Flooding is the way in which a single piece of data may be propagated through a
network to all peers, or of querying other nodes in a network to locate a specific piece of
data. In unstructured P2P networks this is a fairly random process of contacting nearest
neighbor peers, which in turn contact their nearest neighbors, and so on until every peer
in the network is contacted. It is also possible to create structured P2P networks such
that there are well-defined pathways for queries and data flow among peers.

18.4 Uses of P2P Network

Once infrastructure for P2P network is established network applications can be


developed those are not just improved versions of client-server applications, but
entirely new applications. P2P is particularly suited to the following application areas,
1. Content distribution applications, including the file-sharing applications.
2. Collaboration applications, such as desktop sharing and shared whiteboard
applications.
3. Multi-user communication applications that allow users to communicate and
exchange data directly rather than through a server.
4. Distributed processing applications, as an alternative to super-computing applications
that process enormous amounts of data.
5. Web 2.0 applications that combine some or all of the above in dynamic next-
generation Web applications.

18.5 Benefits of a P2P Network

It is resilient. If one computer is down in the network, other computers can continue to
work and communicate. There is no single point of failure.
It is efficient. Because any computer on the network is both a client and a server, so a
computer can get data from the closest peer computer.
A network of peers is easily scaled and more reliable than a single server. A single
server is subject to a single point of failure or can be a bottleneck in times of high
network utilization.
P2P technology to prevent the Web server from crashing or flooding due servicing
client requests. Instead of sending the requested files directly from the server to all the
clients, files can be sent to just a few clients. The remaining clients then download the
files from the clients that already have received the files, a few more clients download

18 - 4 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

from those second-level clients, and so on. In fact, this process is made even faster by
splitting the file into chunks and dividing these chunks between clients, some of whom
download it directly from the server, and some of whom download chunks from other
clients. This is how file-sharing technologies work.

18.6 PNRP - Peer Name Resolution Protocol

For a name publication and resolution mechanism, Windows Peer-to-Peer Networking


uses PNRP. PNRP is an efficient, protected, low cost, dynamic protocol that uses an
iterative, server-less method for name resolution.
Microsoft's entire Peer-to-Peer technology is exposed through the latest Platform SDK
as C/C++ API calls. That is great for anyone who still develops applications in
unmanaged code or managed C++. .NET managed code can also import API calls into
C# and create a managed framework to simplify peer-to-peer application development
in .NET environment.
In peer-to-peer environments, peers rely on name resolution systems to resolve each
other's network locations (addresses, protocols, and ports) from names or other types of
identifiers. Peer-to-peer name resolution has been complicated by transient connectivity
and shortcomings in the Domain Name System (DNS).
PNRP is Peer Name Resolution Protocol that is a basic need in P2P network to locate
any peer machine (node) over the network. It is also a serverless DNS technology that
allows nodes to discover each other. By this it means that it allows Windows XP box to
become its own DNS server. No need to pay to register each domain name. But it is
limited to the domain name pnrp.net.
The Microsoft® Windows® Peer-to-Peer Networking platform solves this problem with
the Peer Name Resolution Protocol (PNRP), a secure, scalable, and dynamic name
registration and name resolution protocol first developed for Windows XP and then
upgraded in Windows Vista™. PNRP works very differently from traditional name
resolution systems, opening up exciting new possibilities for application developers.
18.6.1 PNRP Properties
Distributed and server-less for incredible scalability and reliability : PNRP is
almost entirely serverless (servers are required only for bootstrapping). PNRP easily
scales to billions of names. The system is fault tolerant and there are no bottlenecks.
Effortless name publication without third parties : DNS name publication requires
updates to DNS servers. Most people must contact a server administrator. This takes
time and incurs costs. PNRP name publication is instantaneous, effortless, and free.

18 - 5 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

Real time updates : DNS relies heavily on caching to improve performance.


Unfortunately, this means names cannot be reliably updated in real time. PNRP is much
more efficient than DNS and can process updates almost instantaneously. Name
resolutions will never return stale addresses, making PNRP an excellent solution for
finding mobile users.
Name more than just computers : A PNRP resolution includes an address, port, and
possibly an extended payload. With PNRP you can name more than just computers. You
can also name services.
Protected name publication : Names can be published as secured (protected) or
unsecured (unprotected) with PNRP. PNRP uses public key cryptography to protect
secure peer names against spoofing.
18.6.2 PNRP Clouds

PNRP uses multiple clouds, in which a cloud is a grouping of computers that are able to
find each other. PNRP provides two clouds,
The global cloud corresponds to the global IPv6 address scope and global addresses and
represents all the computers on the entire IPv6 Internet. There is only a single global
cloud.
The link-local cloud corresponds to the link-local IPv6 address scope and link-local
addresses. A link-local cloud is for a specific link, which is typically the same as the
locally attached subnet. There can be multiple link-local clouds.
A third cloud, the site-specific cloud, corresponds to the site IPv6 address scope and site-
local addresses. This cloud has been deprecated, although it is still supported in PNRP.
18.6.3 PNRP Names and IDs

As the first letter in PNRP suggests, every node must register a Peer Name on the
network. Peer names are fixed names for resources such as computers, users, groups, or
services. This is similar to today's DNS except, instead of just IP addresses, the
resources can be more granular (specific).
A peer name is an endpoint for communication, which can be a computer, a user, a
group, a service, or anything else that is required to resolve to an IPv6 address. Peer
names can be registered as unsecured or secured. Unsecured names are just text strings
that are subject to spoofing, as anyone can register a duplicate unsecured name.
Unsecured names are best used in private or otherwise protected networks. Secured
names are protected with a certificate and a digital signature. Only the original publisher
will be able to prove ownership of a secured name.
18 - 6 C# and .NET Programming
Peer to Peer Networking, PNRP, Building P2P Applications

A Peer Name is a case-sensitive text string that has the format "Authority.Classifier".
The value of Authority depends on whether the name is secured or unsecured. The value
is always 0 for an unsecured Authority. The value of Classifier is a text string name
given for the resource and cannot contain spaces. The following list shows some
examples of peer names,
o 0.techtest
o 0.tech.peername
o 8412c005a63ec1964b7d8f2cabebd4916ae7f33d.demotest
PNRP uses peer names to identify resources in a peer network. The key here is "Peer
Network". This is not the whole IPv6 network that the computer is connected to, it is
limited to just the resources available within a Cloud. Registering any resource not
managed by the Peer-to-Peer networking APIs either will result in an error or will not be
resolved later.
PNRP IDs are 256 bits long and are composed of the following,
The high-order 128 bits, known as the peer-to-peer (P2P) ID, are a hash of a peer name
assigned to the endpoint.
The peer name of an endpoint has the following format: Authority.Classifier. For
secured names, Authority is the Secure Hash Algorithm 1 (SHA1) hash of the public
key of the peer name in hexadecimal characters. For unsecured names, the Authority is
the single character "0". Classifier is a string that identifies the application and can be
any Unicode string up to 150 characters long.
The low-order 128 bits are used for the Service Location, which is a generated number
that identifies different instances of the same P2P ID in the same cloud. The 256-bit
combination of P2P ID and Service Location allows multiple PNRP IDs to be registered
from a single computer.
For each cloud, each peer node manages a cache of PNRP IDs that includes both its own
registered PNRP IDs and the entries cached over time. The entire set of PNRP IDs
located on all the peer nodes in a cloud comprises a distributed hash table. It is possible
to have entries for a given PNRP ID located on multiple peers. Each entry in the PNRP
cache contains the PNRP ID, a Certified Peer Address (CPA), and the IPv6 address of
the publishing node. The CPA is a self-signed certificate that provides authentication
protection for the PNRP ID and contains application endpoint information such as
addresses, protocol numbers, and port numbers.
Therefore, the name resolution process for PNRP consists of resolving a PNRP ID to a
CPA. After the CPA is obtained, communication with desired endpoints can begin.

18 - 7 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

There are two different methods of performing PNRP name resolution based on the
version of PNRP. PNRP version 1 was included in Windows XP Service Pack 2 (SP2),
Windows XP Professional x64 Edition, and Windows XP with Service Pack 1 (SP1) and
the Advanced Networking Pack for Windows XP. It used a recursive system for name
resolution, and is not discussed in this paper. PNRP version 2 was redesigned in for
Windows Vista and Windows XP Service Pack 3 to reduce network bandwidth by using
an iterative approach to name resolution. The two versions of PNRP are not compatible.
18.6.4 PNRP Name Resolution - Searching for a Peer Name
PNRP name resolution uses the following two phases as describe below,
Endpoint determination : In this phase, a peer that is attempting to resolve the PNRP
ID of a service on a peer computer first determines the IPv6 address of the peer that
published the PNRP ID of the PNRP service running on that peer.
PNRP ID resolution : After locating and confirming the availability of the peer with
the PNRP ID corresponding to the PNRP service of the desired endpoint, the requesting
peer sends a PNRP Request message to that peer for the PNRP ID of the desired service.
The endpoint sends a reply confirming the PNRP ID of the requested service, a
comment, and up to 4 kilobytes of additional information that the requesting peer can
use for future communication. For example, if the desired endpoint is a gaming server,
the additional data can contain information about the game, the level of play, and the
current number of players.
During endpoint determination, PNRP uses an iterative process for locating the node
that published the PNRP ID, in which the node performing the resolution is responsible
for contacting nodes that are successively closer to the target PNRP ID.
To perform name resolution in PNRP, the peer examines the entries in its own cache for
an entry that matches the target PNRP ID. If found, the requesting peer sends a PNRP
Request message to the peer- to be connected and waits for a response. If an entry for
the PNRP ID is not found, the peer sends a PNRP Request message to the peer that
corresponds to the entry that has a PNRP ID that most closely matches the target PNRP
ID. The node that receives the PNRP Request message examines its own cache and
does the following :
If the PNRP ID is found, the requested peer replies directly to the requesting peer.
If the PNRP ID is not found and a PNRP ID in the cache is closer to the target PNRP
ID, the requested peer sends a response to the requesting peer containing the IPv6
address of the peer that corresponds to the entry that has a PNRP ID that most closely
matches the target PNRP ID. From the IP address in the response, the requesting node
sends another query to the IPv6 address referred to by the first node.

18 - 8 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

If the PNRP ID is not found and there is no PNRP ID in its cache that is closer to the
target PNRP ID, the requested peer sends the requesting peer a response that indicates
this condition. The requesting peer then chooses the next-closest PNRP ID.
The requesting peer continues this process with successive iterations, eventually
locating the node that registered the PNRP ID.
In PNRP, to resolve a Peer Name, the Peer Name, search criteria and optional cloud
name (Global by default) and IP address hint is to be provided. Typically, a lookup is
used to determine if a Peer Name already exists or to contact it directly. The following
search criteria options are supported,
Default
NonCurrentProcessPeerName
AnyPeerName The matching peer name can be
registered locally or remotely.
NearestNonCurrentProcessName The matching peer name can be
registered locally or remotely, but the
resolve request excludes any peer name
registered by the process making the
resolve request and looks for the service
closest to the local IP address.
NearestPeerName The matching peer name can be
registered locally or remotely, but the
resolve request looks for the service
closest to the local IP address.
NearestRemotePeerName The resolve request excludes any peer
name registered locally on this computer
and looks for the service closest to the
local IP address.
NonCurrentProcessPeerName The matching peer name can be
registered locally or remotely, but the
resolve request excludes any peer name
registered by the process making the
resolve request.
RemotePeerName The resolve request excludes any peer
name registered locally on this computer.

18 - 9 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

Again, a series of Windows Socket calls are used to synchronously begin a lookup.
Call WSALookupServiceBegin to begin the enumeration and return a handle.
Call WSALookupServiceNext to resolve the peer name.
Call WSALookupServiceEnd to complete the enumeration.
DNS Name Corresponding to a Peer Name
Since PNRP is a serverless DNS, it makes sense to be able to lookup the DNS name
associated with a Peer Name. It is also useful to determine the Peer Name when
provided with a DNS name. In Windows Vista, two additional Peer-to-Peer APIs are
provided to do just this.
An Endpoint Determination Scenario in a peer-to-peer network for PNRP
In a P2P network, Peer Machine 3 has entries for its own PNRP ID (1500) and the
PNRP ID of 2500 and 3000. The set of peer nodes is shown in Fig. 18.6.1. An arrow
from one node to another means that the node from which the arrow originates has an
entry in its cache for the node to which the arrow is pointing.

Fig. 18.6.1 An endpoint determination scenario in a peer-to-peer network for PNRP

When Peer Machine 3 wants to determine the endpoint for the PNRP ID of 6000, the
following process occurs,
1. Because 3000 is numerically closer to 6000, Peer Machine 3 sends a PNRP Request
message to the node that registered the PNRP ID of 3000 (Peer Machine 4).

18 - 10 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

2. Peer Machine 4 does not have an entry for the PNRP ID of 6000 and does not have
any entries that are closer to 6000. Peer Machine 4 sends a response back to Peer
Machine 3 indicating that it could not find an entry closer to 6000.
3. Because 2500 is the next numerically closer PNRP ID to 6000, Peer Machine 3 sends
a PNRP Request message to the node that registered the PNRP ID of 2500 (Peer
Machine 1).
4. Because Peer Machine 1 has an entry in its cache for the PNRP ID of 6000, it sends
the IPv6 address of Peer Machine 2 to Peer Machine 3.
5. Peer Machine 3 sends a PNRP Request to Peer Machine 2.
6. Peer Machine 2 sends a positive name resolution response back to Peer Machine 3.

Fig. 18.6.2 PNRP endpoint determination scenario flow

After endpoint determination, Peer Machine 3 sends a PNRP name resolution request
for the service with which Peer Machine 3 wants to establish communication to Peer
Machine 2. Peer Machine 2 sends back a response that contains optional data about the
service for the requesting application.

18 - 11 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

18.6.5 Registering and Unregistering a Peer Name

To register on the network an unsecured Peer Name, a valid unsecured Peer Name and
an IP address is to be provided. Optionally, the Cloud name (Global by default) can be
mentioned and an additional comment or description associated with the resource can be
supplied. This information is stored in the WSAQUERYSET data structure and passed
to the WSASetService with the Register option.
To unregister on the network an unsecured Peer Name, a valid unsecured Peer Name
and optionally the Cloud name (Global by default) is required to be provided. This
information is stored in the WSAQUERYSET data structure and passed to the
WSASetService with the Delete option.
PNRP Name Publication
To publish a new PNRP ID, a peer performs the following :
o Sends PNRP publication messages to its cache neighbors (the peers that have
registered PNRP IDs in the lowest level of the cache) to seed their caches.
o Chooses random nodes in the cloud that are not its neighbors and sends them
PNRP name resolution requests for its own P2P ID. The resulting endpoint
determination process seeds the caches of random nodes in the cloud with the
PNRP ID of the publishing peer.
PNRP version 2 nodes do not publish PNRP IDs if they are only resolving other P2P
IDs. The HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\PeerNet\PNRP\IPV6-Global\SearchOnly=1 registry value
(REG_DWORD type) allows you to specify that peers only use PNRP for name
resolution, never for name publication. This registry value can also be configured
through Group Policy.
18.6.6 Scaling Peer Name Resolution with a Multi-Level Cache
To keep the sizes of the PNRP caches small, peer nodes use a multi-level cache, in
which each level contains a maximum number of entries. Each level in the cache
represents a one tenth smaller portion of the PNRP ID number space (2256). The
lowest level in the cache contains a locally registered PNRP ID and other PNRP IDs
that are numerically close to it. As a level of the cache is filled with a maximum of 20
entries, a new lower level is created.
The maximum number of levels in the cache is on the order of log10 (Total number of
PNRP IDs in the cloud). For example, for a global cloud with 100 million PNRP IDs,
there are no more than 8 (=log10(100,000,000)) levels in the cache and a similar
number of hops to resolve a PNRP ID during name resolution. This mechanism allows

18 - 12 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

for a distributed hash table for which an arbitrary PNRP ID can be resolved by
forwarding PNRP Request messages to the next-closest peer until the peer with the
corresponding CPA is found. The result of this multi-level caching scheme is that
each peer does not have to store a large amount of cache entries. Even for a large
number of PNRP IDs, the local storage and network traffic to resolve an arbitrary
PNRP ID is not substantial.
To ensure that resolution can complete, each time a node adds an entry to the lowest
level of its cache, it floods a copy of the entry to all the nodes within the last level of
the cache. The cache entries are refreshed over time. Cache entries that are stale are
removed from the cache. The result is that the distributed hash table of PNRP IDs is
based on active endpoints, unlike DNS in which address records and the DNS
protocol provide no guarantee that the node associated with the address is actively on
the network.
PNRP Cache Initialization

To initialize the PNRP cache when a peer node starts up, the node can use the following
methods,
1. Persistent cache entries - Previous cache entries that were present when the node
was shut down are loaded from hard disk storage.
2. PNRP seed nodes - PNRP allows administrators to specify the addresses or DNS
names of PNRP seed nodes that contain CPAs for current participants in the cloud.
3. Simple Service Discovery Protocol - PNRP nodes are required to register
themselves using the Universal Plug-and-Play (UPnP) Simple Service Discovery
Protocol (SSDP). A node joining a cloud can use an SSDP Msearch message to
locate nearby SSDP nodes.

18.7 Building P2P Application

A Simple Peer to Peer Network Chat Application example


The simple WCF chat application discussed below uses netTcpPeerBinding. Using this
binding, it is very easy to create a simple intranet chat application. TCP end point is used for
the communication. All most all the coding is encapsulated in,
System.ServiceModel;
System.ServiceModel.Channels;
System.ServiceModel.PeerResolvers;

18 - 13 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

1. Chat Server

A chat server code is as below,


<CODE>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.PeerResolvers;

namespace ChatServer
{
public partial class ChatServer : Form
{
private CustomPeerResolverService cprs;
private ServiceHost host;

public ChatServer()
{
InitializeComponent();
btnStop.Enabled = false;
}

private void btnStart_Click(object sender, EventArgs e)


{
try
{
cprs = new CustomPeerResolverService();
cprs.RefreshInterval = TimeSpan.FromSeconds(5);
host = new ServiceHost(cprs);
cprs.ControlShape = true;
cprs.Open();
host.Open(TimeSpan.FromDays(1000000));
lblMessage.Text = "Server started successfully.";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{

18 - 14 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

btnStart.Enabled = false;
btnStop.Enabled = true;
}
}

private void btnStop_Click(object sender, EventArgs e)


{
try
{
cprs.Close();
host.Close();
lblMessage.Text = "Server stopped successfully.";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
btnStart.Enabled = true;
btnStop.Enabled = false;
}
}
}
}
Explanation - An object of CustomPeerResolverService class is created and passed as
an input parameter to the ServiceHost class. Then peer resolver service is opened and
host is started. The code is very simple and no new classes and no end points are
required.
2. The Server's config file

The config file plays the most important role of specifying the required details as shown
below,
<CODE>
?xml version="1.0" encoding="utf-8" ?
<configuration>
system.serviceModel
services
service name="System.ServiceModel.PeerResolvers.
CustomPeerResolverService"
host
baseAddresses
add baseAddress="net.tcp://10.34.34.241/ChatServer"/
baseAddresses

18 - 15 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

host
endpoint address="net.tcp://10.34.34.241/ChatServer"
binding="netTcpBinding"
bindingConfiguration="TcpConfig"
contract="System.ServiceModel.PeerResolvers.
IPeerResolverContract"
endpoint
service
services

bindings
netTcpBinding
binding name="TcpConfig"
security mode="None"/security
binding
netTcpBinding
bindings
system.serviceModel
</configuration>
Config file is very simple. A .NET predefined service is used in this,
System.ServiceModel.PeerResolvers.CustomPeerResolverService.
The base address is provided for hosting the resolver service as shown. The important
thing about the end point is that it uses, System.ServiceModel.PeerResolvers.
IPeerResolverContract contract which is already available in the foundation. Here, TCP
end point is used for the communication. Hence the endpoint is provided with TCP
binding and it is configured it security mode as none. Now the server is ready for chat
client. Just start the server.
3. Chat Client
As compared to the Chat server, the client becomes little bit complicated. It does
everything on its own. It needs something common that the server will use to communicate
with clients and that can be established using interfaces.
The client code is as below,
<CODE>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
using System.ServiceModel.Channels;

18 - 16 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

namespace ChatClient
{
// This is the service contract at client side which uses
// the same contract as call back contract.
// Using CallbackContract, server sends message to clients
[ServiceContract(CallbackContract = typeof(IChatService))]
public interface IChatService
{
// All operation contracts are one way so that client
// can fire the message and forget
// When server responds, client catches it acts accordingly
[OperationContract(IsOneWay = true)]
void Join(string memberName);
[OperationContract(IsOneWay = true)]
void Leave(string memberName);
[OperationContract(IsOneWay = true)]
void SendMessage(string memberName, string message);
}

// An interface to create a channel for communication


public interface IChatChannel : IChatService, IClientChannel
{
}

public partial class ChatClient : Form, IChatService


{
// Different delegates that are used internally to raise
// events when client joins,
// leaves or sends a message
private delegate void UserJoined(string name);
private delegate void UserSendMessage(string name, string message);
private delegate void UserLeft(string name);

// Events are made static because it is required to create only once


// when client joins
private static event UserJoined NewJoin;
private static event UserSendMessage MessageSent;
private static event UserLeft RemoveUser;

private string userName;


private IChatChannel channel;
// As it is required to establish duplex communication
// DuplexChanelFactory is used
private DuplexChannelFactory<ichatchannel /> factory;

18 - 17 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

public ChatClient()
{
InitializeComponent();
this.AcceptButton = btnLogin;
}

public ChatClient(string userName)


{
this.userName = userName;
}

private void btnLogin_Click(object sender, EventArgs e)


{
if (!string.IsNullOrEmpty(txtUserName.Text.Trim()))
{
try
{
// Register an event
NewJoin += new UserJoined(ChatClient_NewJoin);
MessageSent += new UserSendMessage
(ChatClient_MessageSent);
RemoveUser += new UserLeft(ChatClient_RemoveUser);

channel = null;
this.userName = txtUserName.Text.Trim();
// Create InstanceContext to handle call back interface
// Pass the object of the CallbackContract implementor
InstanceContext context = new InstanceContext(
new ChatClient(txtUserName.Text.Trim()));
// create a participant with the given end point
// The communication is managed with CHAT MESH and
// each client creates a duplex
// end point with the mesh. Mesh is nothing but the
// named collection of nodes.
factory =
new DuplexChannelFactory<ichatchannel />(context, "ChatEndPoint");
channel = factory.CreateChannel();
channel.Open();
channel.Join(this.userName);
grpMessageWindow.Enabled = true;
grpUserList.Enabled = true;
grpUserCredentials.Enabled = false;
this.AcceptButton = btnSend;
rtbMessages.AppendText
("****WEL-COME to Chat Application*****\r\n");
txtSendMessage.Select();

18 - 18 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

txtSendMessage.Focus();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}

void ChatClient_RemoveUser(string name)


{
try
{
rtbMessages.AppendText("\r\n");
rtbMessages.AppendText(name + " left at " +
DateTime.Now.ToString());
lstUsers.Items.Remove(name);
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.ToString());
}
}

void ChatClient_MessageSent(string name, string message)


{
if (!lstUsers.Items.Contains(name))
{
lstUsers.Items.Add(name);
}
rtbMessages.AppendText("\r\n");
rtbMessages.AppendText(name + " says: " + message);
}

void ChatClient_NewJoin(string name)


{
rtbMessages.AppendText("\r\n");
rtbMessages.AppendText(name + " joined at:
[" + DateTime.Now.ToString() + "]");
lstUsers.Items.Add(name);
}

#region IChatService Members

public void Join(string memberName)


{

18 - 19 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

if (NewJoin != null)
{
NewJoin(memberName);
}
}

public new void Leave(string memberName)


{
if (RemoveUser != null)
{
RemoveUser(memberName);
}
}

public void SendMessage(string memberName, string message)


{
if (MessageSent != null)
{
MessageSent(memberName, message);
}
}

#endregion

private void btnSend_Click(object sender, EventArgs e)


{
channel.SendMessage(this.userName, txtSendMessage.Text.Trim());
txtSendMessage.Clear();
txtSendMessage.Select();
txtSendMessage.Focus();
}

private void ChatClient_FormClosing(object sender,


FormClosingEventArgs e)
{
try
{
if (channel != null)
{
channel.Leave(this.userName);
channel.Close();
}
if (factory != null)
{
factory.Close();
}

18 - 20 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
4. The Client's Config file
The important details are mentioned in the config file as shown below,
<CODE>
?xml version="1.0" encoding="utf-8" ?
<Configuration>
system.serviceModel
client
endpoint name="ChatEndPoint" address="net.p2p://chatMesh/ChatServer"
binding="netPeerTcpBinding"
bindingConfiguration="PeerTcpConfig"
contract="ChatClient.IChatService"endpoint

client

bindings
netPeerTcpBinding
binding name="PeerTcpConfig" port="0"
security mode="None"security
resolver mode="Custom"
custom address="net.tcp://10.34.34.241/ChatServer"
binding="netTcpBinding"
bindingConfiguration="TcpConfig"custom
resolver
binding
netPeerTcpBinding
netTcpBinding
binding name="TcpConfig"
security mode="None"security
binding
netTcpBinding
bindings
system.serviceModel
</configuration>
In the config file the endpoint names "ChatEndpoint" have been mentioned, which point
to a chat mesh and use netPeerTcpBinding. Here, when the binding is configured, the
custom resolver mode is sued and the custom TCP address is provided where actual
server is running.

18 - 21 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

Giving port number as zero will automatically detect the free port for
communication. The security mode is mentioned as none. Thus using this configuration the
clients can be started and are able to send a message across the intranet.

18.8 Application Model for Peer-to-Peer

When writing a peer-to-peer application, it is important to understand how it will be


used. This will make it easier to decide which .NET application model to use. In the
case of peer-to-peer, four powerful application models (or application types) are
available as discussed in below section.
1. Web Services - are in the System.Web.Services namespace, the Web Services
technology provides an excellent way to handle registration, discovery, and content
lookup for a peer-to-peer application. A Web Service allows to quickly write a class
that listens for incoming requests, processes them as they arrive, and sends back
useful information in the form of objects that are easily understood by the peer
application.
2. Windows Forms - are in the System.WinForms namespace, Windows® Forms is the
.NET Framework solution for writing the type of rich Windows-based GUI
applications that help to make the peer-to-peer experience much more exciting.
Windows Forms is the ideal technology for writing the GUI for the peer that allows
end users log in, request, and share content.
3. Web Forms - are in the System.Web namespace, the Web Forms technology makes
it very easy to return HTML content to a peer application. This can be useful if the
peer-to-peer application need be full of media contents, is having very interactive
services or advertisements about using the services. When the peer-to-peer
application starts up and registers with the Web Service, it can also call a Web Forms
application to get the latest HTML content from the server.
4. Service Process - are in the System.ServiceProcess namespace, a service process
(also known as a Windows NT® service) is useful in peer-to-peer scenarios as a
long-lived discovery server. In most cases, a Web Service is better for fulfilling the
role of the discovery service. However, in cases where the discovery mechanism is
not using the HTTP protocol, a service process listening for some other protocol
might be the best way to go.
In addition to providing rich choices for application models, the .NET Framework
drastically simplifies the networking side of peer-to-peer application creation, using the
classes found in the System.Net namespace and the System.Web.Services namespace.

18 - 22 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

Let's take a closer look at each of these namespaces, the classes they provide, and
applications built around each.

18.9 Firewalls and Ports

The selection of ports and the protocol used by the peers should be taken into account
when designing the application because firewalls are often designed to allow
communication only over a particular port. While designing a peer-to-peer application
for a corporate environment, it might be useful to discuss with the network administrator
about which ports are open or recommended for application use. If the application is
designed for users who will most likely not be going through a firewall to find other
peers, just about any port that is not already reserved for another protocol will work. In
general, port numbers are divided into three ranges,
1. Well-known ports (from 0 through 1023)
2. Registered ports (from 1024 through 49151)
3. Dynamic and/or private ports (from 49152 through 65535)

Two Marks Questions with Answers

Q.1 What makes a network effective and efficient ?


Ans. : There are mainly two criteria which make a network effective and efficient :
Performance : performance can be measured in many ways like transmit time and
response time.
Reliability : reliability is measured by frequency of failure.
Robustness : robustness specifies the quality or condition of being strong and in good
condition.
Security : It specifies how to protect data from unauthorized access and viruses.
Q.2 What is bandwidth ?
Ans. : Every signal has a limit of upper range frequency and lower range frequency. The
range of limit of network between its upper and lower frequency is called bandwidth.
Q.3 What is DNS ?
Ans. : DNS is an acronym stands for Domain Name System.
DNS was introduced by Paul Mockapetris and Jon Postel in 1983.
It is a naming system for all the resources over the internet which includes physical
nodes and applications. It is used to locate to resource easily over a network.
DNS is an internet which maps the domain names to their associated IP addresses.

18 - 23 C# and .NET Programming


Peer to Peer Networking, PNRP, Building P2P Applications

Without DNS, users must know the IP address of the web page that you wanted to
access.
Q.4 What is a node in P2P network ?
Ans. :
Two or more computers are connected directly by an optical fiber or any other cable.
A node is a point where a connection is established. It is a network component that is
used to send, receive and forward the electronic information.
A device connected to a network is also termed as Node. Let's consider that in a
network there are 2 computers, 2 printers, and a server are connected, then we can
say that there are five nodes on the network.
Q.5 How are networks classified based on their connections ?
Ans. : Networks are classified into two categories based on their connection types. They are
mentioned below :
Peer-to-peer networks (P2P) : When two or more computers are connected
together to share resources without the use of a central server is termed as a peer-to-
peer network. Computers in this type of network act as both server and client. It is
generally used in small companies as they are not expensive.
Server-based networks : In this type of network, a central server is located to store
the data, applications, etc of the clients. The server computer provides the security
and network administration to the network.

Long Answered Questions

Q.1 Discuss P2P network with neat diagram. (Refer section 18.1)
Q.2 Explain PNRP with name resolution process. (Refer section 18.6)
Q.3 What are PNRP clouds ? (Refer section 18.6)
Q.4 Discuss P2P terminology. (Refer section 18.2)
Q.5 What are uses and benefits of P2P ? (Refer section 18.5)

Peer to Peer Networking, PNRP, Building P2P Applications ends …

18 - 24 C# and .NET Programming


C# and .NET Framework - Introduction

Syllabus : WPF - Windows Presentation Foundation.

Section No. Topic Name Page No.


19.1 Introduction to WPF 19 - 2
19.2 WPF Architecture 19 - 2
19.3 Features of WPF 19 - 3
19.4 Various WPF Tools 19 - 8
19.5 Various WPF Assemblies and Namespaces 19 - 8
19.6 WPF Other Facilities 19 - 8
19.7 WPF and XAML 19 - 9
19.8 WPF and C# 19 - 9
19.9 WPF Advantages 19 - 9
Two Marks Questions with Answers 19 - 10
Long Answered Questions 19 - 11

19 - 1 C# and .NET Programming


WPF - Windows Presentation Foundation

19.1 Introduction to WPF

Concept :

1. Windows Presentation Foundation (WPF), is Microsoft's latest approach to a Graphical


User Interface (GUI) framework, used with the .NET framework.
Explanation :
2. A GUI framework allows to create an application with a wide range of GUI elements, like
labels, textboxes and other well known elements. Without a GUI framework these
elements are required to be drawn manually and events on them like keyboard and mouse
input should be dealt with seperately. GUI framework saves all these developers efforts.
3. Though different approaches, WinForms and WPF are current popular GUI
development frameworks.
4. WinForms is a layer on top of the standard Windows controls (e.g. a TextBox),
where as WPF is built from scratch and doesn't rely on standard Windows controls
in almost all situations.
For example, WinForms will not allow a button with text and image as is basically not
supported for standard Windows control. Instead, WPF allows to draw and have image on
button and design the button the way one wants. WPF, treats a button as a border with
content and various states and other properties.
5. While using WPF, the appearance is specified in the ExtensibleApplicationMarkup
Language (XAML), the behavior is implemented in a managed programming language
like C# or Visual Basic. The two parts are tied together by data binding, events and
commands.

19.2 WPF Architecture

WPF Architecture

1. Earlier, user interface frameworks offered by Microsoft such as MFC and Windows
forms, were simply the wrappers around User32 and GDI32 DLLs. WPF makes least
use of User32.
2. WPF is more than just a wrapper and it is a part of the .NET framework.
3. It contains a mixture of managed and unmanaged code.
4. Components of WPF architecture

19 - 2 C# and .NET Programming


WPF - Windows Presentation Foundation

The most important code part of WPF are,


I. Presentation Framework II. Presentation Core III. Milcore

Fig. 19.2.1 WPF architecture

I. The presentation framework and the presentation core have been written in managed
code.
II. Milcore is a part of unmanaged code which allows tight integration with DirectX
(responsible for display and rendering the objects).
III. Common language runtime makes the development process more productive by offering
many features such as memory management, error handling.

19.3 Features of WPF

1. Resolution independence

WPF Application is resolution independent. An application developed in WPF is


independent of screen resolution. It auto uses the DirectX components. Resolution of
WPF is always same with any type of screen resolution. The WPF user interface will look
better even on a screen with low resolution. WPF framework has the Media Integration
Layer (MIL) in order to talk to the DirectX components. The direct components impose a
vector based graphics on the WPF user interface.
2. Separation of concerns

In WPF application, there is two part appearance of UI and its behavior. By appearance it
means application's User Interface and it is specified by XAML. By behavior it means
how the application work and it is handled by .NET language like C# orVB.Net etc.
So it is very easy to customize the look of controls and its functionality. XAML holds
same position in WPF applications like CSS in HTML holds in web applications.

19 - 3 C# and .NET Programming


WPF - Windows Presentation Foundation

3. Add control inside a control


WPF introduced a very handy feature to add a control inside another control. WPF
provides not only the text but it also allows to define a control as a content of another
basic control like a Button. This feature is truly astonishing fact for the developers and
this lets the world know, what the power of WPF is when it comes to user interfaces. So a
TextBox can be embedded inside a Button as shown in Fig. 19.3.1. This is not possible in
Windows application.

Fig. 19.3.1 Textbox Control embedded in Button Control

4. Control templates
What if the user wants to change the shape of a button, this will definitely sound weird
for .NET developers. Now it can be done in WPF by defining the control template. For
example a Button can be declared on for WPF window and its shape can be changed to
elliptic. Templates are an integral part of user interface design in WPF.
WPF has the following three types of templates, Control Template, Items Panel
Template, and Data Template.
5. Control transforms : WPF contains a handful of 2D transforms which enables to
change the size, position, rotation angle and also allows skewing. Control transforms
can be performed in two ways Layout Transform and Render Transform.
Layout Transform - Transform is applied before the control is laid out on the form
Render Transform - Transform is applied after the control is laid on the form

19 - 4 C# and .NET Programming


WPF - Windows Presentation Foundation

There are 5 kinds of transforms available,


1. Rotate Transform - It will rotate the controls to a specified angle
2. Scale Transform - It enlarges or shrinks the controls in x and y axis
3. Skew Transform - It slants the control
4. Translate Transform - It moves the control based on x and y values
5. Matrix Transform - It combines all the above transforms
6. WPF resources
WPF supports two types of resources namely static and dynamic.
Static resources - A Static Resource will be resolved and assigned to the property
during the loading of the XAML that occurs before the application actually runs. It
will only be assigned once and any change to the resource dictionary is ignored.
Dynamic resources - A Dynamic Resource assigns an Expression object to the
property during loading but does not actually lookup the resource until runtime
when the Expression object is asked for the value. This defers looking up the
resource until it is needed at runtime. A good example would be a forward
reference to a resource defined later on in the XAML. Another example is a
resource that will not even exist until runtime. It will update the target if the
source's resource dictionary is changed.
7. Data binding : WPF provides a mechanism to display and interact with data between
UI elements and data object on user interface. Binding allows to link a source object
to some control. There are the following two types of bindings,
One-Way Binding : Binds a source to the interface.
Two-Way Binding : Binds a source to the interface and back to the source.
INotifyPropertyChanged interface allows sources to interact with the interface
and update it as the values change.
To bind an object or a list to an element the DataContext property is set.
It is possible to bind an object or a list of objects, also one element can bind to
another element.
To customize how bound data will be displayed the DataTemplate from a control
can be set.
It is possible to set Data Converters to convert the source type to another type.
8. Triggers in WPF : Triggers are used to perform certain actions when a specified
condition is fulfilled. Triggers are used to create visual effects on controls and
framework elements. Triggers are parts of styles and are always defined inside a style.

19 - 5 C# and .NET Programming


WPF - Windows Presentation Foundation

Types of Triggers :
Basically, there are 3 types of triggers namely,
1. Property Trigger
2. Data Trigger
3. Event Trigger
9. WPF styles : Style is a way to group similar properties in a single Style object and
apply to multiple objects. The Style element in XAML represents a style. A Style is
usually added to the resources of a FrameworkElement. The x:Key is the unique key
identifier of the style.
10. Different types of layout : Layout is used to separate the control on the User
Interface. It provides a way to develop a neat and user friendly application that is
having lot of controls in UI.
1. Grid - Grid as name suggested is same as table. It has rows and columns. Controls can
be placed inside grid cell. It is same as in web application GridView.
2. Dock panel - Using docking control can be placed either to top, right, left or bottom.
The dock panel provide this type of functionality in WPF. A Dock Panel is used to
dock child elements in the left, right, top, and bottom positions of the relative
elements. The position of child elements is determined by the Dock property of the
respective child elements and the relative order of those child elements. The default
value of Dock property is left. The Dock property is of type Dock enumeration that
has Left, Right, Top, and Bottom values.
3 Stack panel - Inside Stack Panel a control is managed either horizontally or vertically.
A control can be set on any other scale.
4. Canvas - It provides a layout where controls can be placed anywhere as required.
Developer has complete control on the layout.
5. Wrap panel - A Wrap panel lays the child controls from left to right and as the name
suggests it goes to the new line once it fills up the container width.
11. 2D and 3D graphics and animation : WPF comes with entire rich component all in
one. In WPF controls can be used as 3D layout or 2D layout. In this animation, media
file and graphics can be used. It supports playing video or audio file with the help of
Media player. Custom themes are possible to use with WPF.
12. Media in WPF : WPF has two classes to work with audio, video and video with audio
namely, MediaElement b MediaPlayer. The MediaElement is a part of XAML
UIElement and is supported by both XAML and WPF code behind but MediaPlayer is
available in WPF code behind only.

19 - 6 C# and .NET Programming


WPF - Windows Presentation Foundation

13. Charting in WPF : WPF supports common charts including line, bar, curve and
others.
14. WPF DatePicker control : A DatePicker control is used to create a visual DatePicker
that let user to pick a date and fire an event on the selection of the date.
15. WPF ListBox : The XAML ListBox element represents a ListBox control.
<ListBox></ListBox>
The Width and Height properties represent the width and the height of a ListBox. The
Name property represents the name of the control, which is a unique identifier of a
control. The Margin property tells the location of a ListBox on the parent control. The
HorizontalAlignment and VerticalAlignment properties are used to set horizontal and
vertical alignments.
16. WPF ComboBox : A ComboBox control is an items control that works as a ListBox
control but only one item from the collection is visible at a time and clicking on the
ComboBox makes the collection visible and allows users to pick an item from the
collection. Unlike a ListBox control, a ComboBox does not have multiple item
selection. A ComboBox control is a combination of three controls - A Button, a
Popup, and a TextBox. The Button control is used to show or hide available items and
Popup control displays items and lets user select one item from the list. The TextBox
control then displays the selected item.
17. WPF MessageBox : The MessageBox class in WPF represents a modal message box
dialog, which is defined in the System.Windows namespace. The Show, a static
method of the MessageBox is the only method that is used to display a message box.
The Show method returns a MessageBoxResult enumeration that has the values
None, OK, Cancel, Yes, and No. MessageBoxResult is used to determine what button
was clicked on a MessageBox and take an appropriate action.
18. WPF DataGrid : DataGrid element represents WPF DataGrid control in XAML.
<DataGrid />
When a DataGrid control is dragged and dropped from Toolbox to designer, it
positions the control and adds certain startup code XA.
The Width and Height properties represent the width and the height of a DataGrid.
The Name property represents the name of the control, which is a unique identifier of
a control. The Margin property sets the margin of placement of DataGrid on the
window.
19. WPF ProgressBar : The ProgressBar tag in XAML represents a WPF ProgressBar
control.

19 - 7 C# and .NET Programming


WPF - Windows Presentation Foundation

<ProgressBar></ProgressBar>
The Width and Height properties represent the width and the height of a ProgressBar.
The Name property represents the name of the control, which is a unique identifier of
a control. The Margin property tells the location of a ProgressBar on the parent
control. The HorizontalAlignment and VerticalAlignment properties are used to set
horizontal and vertical alignments.
20. WPF TreeView : A TreeView represents data in a hierarchical view in a parent child
relationship where a parent node can be expanded or collapsed. The left side bar of
Windows Explorer is an example of a TreeView.

19.4 Various WPF Tools

While working in WPF below tools can be used,


Microsoft Visual Studio
Microsoft Visual Studio Express 2008
Microsoft Expression Blend
Microsoft Expression Design
XAMLPad

19.5 Various WPF Assemblies and Namespaces

Below is the list of various WPF assemblies and namespaces,


Primary Assemblies
o PresentationCore
o PresentationFramework
o WindowsBase
Namespaces
o Windows

19.6 WPF Other Facilities

Apart from enhanced UI and data binding services WPF also provides below facilities,
Provides the capability to setup generic host communication with two parties.
Allows setting up service properties.
Allows to make the settings in order to have a service in C# as well as a Java client.
Allows creating standard HTTP SOAP web service with the help of WPF.

19 - 8 C# and .NET Programming


WPF - Windows Presentation Foundation

Provides easy options to process business transactions.


Supplies current data to various other services

19.7 WPF and XAML

XAML is a new descriptive programming language developed by Microsoft to write user


interfaces for next-generation managed applications. XAML is used to build user
interfaces for Windows and Mobile applications that use Windows Presentation
Foundation (WPF), UWP, and Xamarin Forms.
The purpose of XAML is simple, to create user interfaces using a markup language that
looks like XML. Most of the time, a designer is used to create the XAML but XAML can
manipulated manually as well.
XAML uses the XML format for elements and attributes. Each element in XAML
represents an object which is an instance of a type. The scope of a type (class,
enumeration etc.) is defined a namespace that physically resides in an assembly (DLL) of
the .NET Framework library.
Similar to XML, a XAML element syntax always starts with an open angle bracket (<)
and ends with a close angle bracket (>). Each element tag also has a start tag and an end
tag. For example, a Button object is represented by the <Button> object element. The
following code snippet creates a Button object element.
<Button></Button>
Alternatively, a self-closing format can be used to close the bracket.
<Button />

19.8 WPF and C#

While XAML is used to build user interfaces in WPF, C# is used as the code-behind
language in WPF. While Windows and their controls are created in XAML at design-
time, they can also be created at runtime using C# language. C# is also used to write all
events programming and business logic. All actions, events and rendering are done in the
code behind C# code.

19.9 WPF Advantages

1. It's more compatible with current standards.


2. It is flexible, many things could be achieved without having to write or purchse new
controls.

19 - 9 C# and .NET Programming


WPF - Windows Presentation Foundation

3. In WPF, UI elements are designed in XAML while behaviors can be implemented in


procedural languages such C# and VB.Net. So it is very easy to separate behavior
from the designer code.
4. XAML (Extensible Application Markup Language ) makes it easy to create and edit
GUI, and allows the work to be split between a designer part (XAML) and a
programming part (C#, VB.NET etc.). Graphical design tools can work on simple
XML documents instead of parsing code.
5. WPF supports databinding, which allows to get a more clean separation of data and
layout.
6. WPF makes use of hardware acceleration for drawing the GUI, for better performance.
7. WPF supports user interfaces framework for both windows applications and web
applications (Silverlight/XBAP).
8. With XAML, the programmers can work in parallel with the designers. The separation
between a GUI and its behavior can allow us to easily change the look of a control by
using styles and templates.
9. Rich composition of controls - Controls in WPF are highly composable. Almost any
type of controls can be defined as content of another. Put an image into a button to
create an image button, or put a list of videos into a list box to choose a video file.

Two Marks Questions with Answers

Q.1 What are the capabilities of WPF ?


Ans. :
It has all the equivalent common user controls like buttons, checkboxes, sliders etc.
It has all the capabilities of HTML and Flash.
It supports fix and flow format document.
It provides the facility of data binding, animation and multimedia.
Q.2 What are resources in WPF ?
Ans. : In WPF, resources are used to provide a simple way to reuse commonly defined
objects and values. They also facilitate you to set the properties of multiple controls at
a time. For example, you can set the background property on several elements in a
WPF application using a single resource.
Q.3 What is XAML ? What is the use of XAML ?
Ans. :
XAML is a declarative XML based language. It facilitates you to define objects and
properties in XML. Its documents are loaded by XAML parser.

19 - 10 C# and .NET Programming


WPF - Windows Presentation Foundation

XAML is used to describe the objects, properties and their relation in between them. It
makes you able to create any type of objects i.e. graphical and non-graphical.
Q.4 What are the different types of layout controls in WPF ?
Ans. : Following are the different types of layout controls :
Grid
DockPanel
WrapPanel
Canvas
UniformGrid
StackPanel
Q.5 What is the difference between Dynamic Resource and Static Resource ?
Ans. :
Sr. No. Static Resource Dynamic Resource
1. Static Resources evaluate the resource Dynamic Resource evaluates the
one time only. resources every time they are required.
2. Static Resource is light. Dynamic Resource is heavy due to
frequently evaluated.

Long Answered Questions

Q.1 Explain WPF architecture. (Refer section 19.2)


Q.2 Discuss various features of WPF. (Refer section 19.3)
Q.3 What are namespaces provided in WPF ? (Refer section 19.5)
Q.4 What are benefits of WPF ? (Refer section 19.9)
Q.5 What are WPF assemblies ? (Refer section 19.5)

WPF - Windows Presentation Foundation ends...

19 - 11 C# and .NET Programming


WPF - Windows Presentation Foundation

19 - 12 C# and .NET Programming

You might also like