Sie sind auf Seite 1von 337

ASP.

NET MATERIAL

INTRODUCTION TO WEB TECHNOLOGIES


Introduction to scripts:

Html & Java Script:

A client-side script is a program that may accompany an HTML document or be embedded directly in it. The program executes on the client's machine when the document loads, or at some other time such as when a link is activated. HTML's support for scripts is independent of the scripting language. Scripts offer authors a means to extend HTML documents in highly active and interactive ways. For example:

Scripts may be evaluated as a document loads to modify the contents of the document dynamically. Scripts may accompany a form to process input as it is entered. Designers may dynamically fill out parts of a form based on the values of other fields. They may also ensure that input data conforms to predetermined ranges of values, that fields are mutually consistent, etc. Scripts may be triggered by events that affect the document, such as loading, unloading, element focus, mouse movement, etc. Scripts may be linked to form controls (e.g., buttons) to produce graphical user interface elements.

There are two types of scripts authors may attach to an HTML document:

Those that are executed one time when the document is loaded by the user agent. Scripts that appear within a SCRIPT element are executed when the document is loaded. For user agents that cannot or will not handle scripts, authors may include alternate content via the NOSCRIPT element. Those that are executed every time a specific event occurs. These scripts may be assigned to a number of elements via the intrinsic event attributes.

The SCRIPT Element:


<!ELEMENT SCRIPT - - %Script; <!ATTLIST SCRIPT -- script statements -->

Page 1

ASP.NET MATERIAL
charset type src defer %Charset; #IMPLIED -- char encoding of linked resource --

%Content Type; #REQUIRED -- content type of script language %URI; (defer) #IMPLIED -- URI for an external script -#IMPLIED -- UA may defer execution of script --

Script Technologies:

The following table lists the Windows script technologies and describes the functionality included in each technology.

JScript:
The powerful Microsoft scripting language targeted specifically at the Internet. JScript 5.8 is the Microsoft implementation of the ECMA 262 language.

VBScript:
Microsoft Visual Basic Scripting Edition brings active scripting to a wide variety of environments. These include Web client scripting in Microsoft Internet Explorer and Web server scripting in Microsoft Internet Information Services.

Script Runtime:
A Dictionary object is the equivalent of a PERL associative array. Items can be any form of data, and are stored in the array. The FileSystemObject (FSO) object model lets you use the familiar object. method syntax with a rich set of properties, methods, and events to process folders and files.

Script Encoder is a simple command-line tool that enables script designers to encode
their final script so that Web hosts and Web clients cannot view or modify their source.

Windows Script Components:


Microsoft Windows Script Components give you an easy way to create COM components using scripting languages such as Microsoft Visual Basic Scripting Edition (VBScript) and Microsoft JScript.

Page 2

ASP.NET MATERIAL

Windows Script Host:


The Microsoft Windows Script Host (WSH) is a tool that lets you run Visual Basic Scripting Edition and JScript natively in the base operating system.

Windows Script Interfaces:


Microsoft Windows Script Interfaces provide a way for an application to add scripting and OLE Automation capabilities.

Client side scripting & Server side scripting Client-side:


Client-side scripting enables interaction within a webpage. The code required to process user-input is downloaded and compiled by the browser or plug-in. An example of a client-side interaction is a rollover (typically triggered when choosing a navigation option). Client-side scripting languages include JavaScript.

Server-side:
With server-side scripting, completing an activity involves sending information to another computer (server) across the internet. The server then runs a program that processes the information and returns the results, typically a webpage. Search engines use server-side processing. When a keyword is sent, a program on a server matches the word or phrase entered against an index of website content. (To complete the same search as a client-side process would require the browser to download the entire search engine program and index.) Server-side scripting languages include ASP and PHP.

Page 3

ASP.NET MATERIAL

Client-side vs. Server-side Client-side interaction:


Response to interaction may be more immediate (once the program code has been downloaded) Services are secure (as no information is sent from the browser) Reliant on the user having using a specific browser and/or plug-in on their computer Affected by the processing speed of the users computer

Server-side interaction:
Complex processes are often more efficient (as the program and the associated resources are not downloaded to the browser) There are security considerations when sending sensitive information Does not rely on the user having specific browser or plug-in Affected by the processing speed of the host server.

Architecture in ASP.NET (IIS 6.0)


This section provides an overview of the ASP.NET infrastructure and subsystem relationships, as they relate to the subject of security. The following illustration shows the relationships among the security systems in ASP.NET.

Page 4

ASP.NET MATERIAL

As the illustration shows, all Web clients communicate with ASP.NET applications through Internet Information Services (IIS). IIS deciphers and optionally authenticates the request. If Allow Anonymous is set to true, no authentication occurs. IIS also finds the requested resource (such as an ASP.NET application), and, if the client is authorized, returns the appropriate resource. In addition to the built-in ASP.NET features, an ASP.NET application can use the lowlevel security features of the .NET Framework. For more information, see the "Key Security Concepts" topic in .NET Framework Help.

Integrating with IIS:


When considering ASP.NET authentication, you should understand the interaction with IIS authentication services. IIS always assumes that a set of credentials maps to a Microsoft Windows NT account and uses them to authenticate a user. There are three different kinds of authentication available in IIS 5.0 through IIS 6.0: basic, digest, and Integrated Windows Authentication (NTLM or Kerberos). You can select the type of authentication to use in IIS administrative services. If you request a URL containing an ASP.NET application, the request and authentication information are handed off to the application. ASP.NET provides the two additional types of authentication described in the following table. ASP.NET authentication provider Forms authentication Description A system by which unauthenticated requests are redirected to an HTML form using HTTP client side redirection. The user provides credentials and submits the form. If the application authenticates the request, the system issues an authentication ticket in a cookie that contains the credentials or a key for reacquiring the identity. Subsequent requests are issued with the cookie in the request headers; they are authenticated and authorized by an ASP.NET handler using whatever validation method the application developer specifies.

Passport

Centralized authentication service provided by Microsoft that

Page 5

ASP.NET MATERIAL
ASP.NET authentication provider Description

authentication

offers a single logon and core profile services for member sites.

ASP Objects Introduction


Objects are a way of encapsulating multiple methods (they're like functions) and variables in one easy to manage Uber-Variable (an Object). Objects in ASP resemble other Object Oriented Programming languages. In this lesson we will be using the ASP CDO.Message object as our example object to be dissected.

ASP Object Overview:


Objects were created to combat the increasing complexity of programming. The rationale for understanding and using Objects in your programming is to make programming easier and your code more human readable.

ASP Create an Object - Server.CreateObject:


An object in ASP is created by passing a name string to the Server.CreateObject function (actually referred to as a method). The string to create a Message object is "CDO.Message". We will be creating a CDO.Message object in this example. Note: Because objects are special there is a special way that you create and destroy them using the Set keyword. These areas are marked in red in the example below.

ASP Code:
<% Dim myObject Set myObject = Server.CreateObject ("CDO.Message") 'You must Set your objects to "nothing" to free up the 'the computer memory that was allocated to it Set myObject = nothing %>

Page 6

ASP.NET MATERIAL
Objects are a collection of related things that are combined into this blob of programming go that can be created and destroyed whenever we may need it. For example say that you wanted to make an object that allowed you to send an email...

ASP Object Properties:


These smaller variables are commonly referred to as an object's properties and the format for setting these properties is nearly identical to setting a variable equal to a value. The correct syntax for setting an object's properties is: objectName.propertyName = someValue In this tiny example below we are creating a new mail object and setting its To and From properties.

ASP Code:
<% Dim myObject Set myObject = Server.CreateObject("CDO.Message") 'Then we set the To and From properties myObject.To = "little.timmy@example.com" myObject.From = "huge.jill@example.com" 'You must Set your objects to "nothing" to free up the 'the computer memory that was allocated to it Set myObject = nothing %> Now I know we didn't DO anything in the above example, but we still need to learn a bit more about objects before we can get anything done! Objects, besides having a clump of associated common variables, may also have a collection of functions(which become referred to as methods) associated with them. These methods are processes that you would want to commonly do to either manipulate the variables of the object or to use the variables to do something. In our Message object we have a collection of information that, when put together into the proper email form and sent to an email service will become an email.

Page 7

ASP.NET MATERIAL
All this complex code has been programmed by Microsoft employees and stored into the Message objects Send method.

ASP Object Methods:


We cannot see the code that was used to program the Send method, but that's one of the great things about using object programming. You know what you need to know and nothing more. In our example below we create a Message object and set the necessary properties and send it off with the Send method.

ASP Code:
<% Dim myObject Set myObject = Server.CreateObject("CDO.Message") 'Then we set the To and From properties myObject.To = "little.timmy@example.com" myObject.From = "huge.jill@example.com" myObject.Subject = "Can you see me?" myObject.TextBody = "I'm really really big!" myObject.Send() 'You must Set your objects to "nothing" to free up the 'the computer memory that was allocated to it Set myObject = nothing %>

ASP Object Summary:


In this lesson you learned how to create and destroy an object in ASP. You also learned how to access the properties and utilize the methods of an object. If you still have no idea what this lesson was about, hopefully there's enough information for you to hack out what you need to do in your ASP project.

Page 8

ASP.NET MATERIAL

ASP.NET INTRODUCTION
What is ASP.Net?
ASP.NET, the next version of ASP, is a programming framework used to create enterprise-class Web Applications. These applications are accessible on a global basis leading to efficient information management. The advantage ASP.NET offers is more than just the next version of ASP.

Why ASP.NET?
Since 1995, Microsoft has been constantly working to shift it's focus from Windows-based platforms to the Internet. As a result, Microsoft introduced ASP (Active Server Pages) in November 1996. ASP offered the efficiency of ISAPI applications along with a new level of simplicity that made it easy to understand and use. However, ASP script was an interpreted script and consisted unstructured code and was difficult to debug and maintain. As the web consists of many different technologies, software integration for Web development was complicated and required to understand many different technologies. Also, as applications grew bigger in size and became more complex, the number of lines of source code in ASP applications increased dramatically and was hard to maintain. Therefore, an architecture was needed that would allow development of Web applications in a structured and consistent way. The .NET Framework was introduced with a vision to create globally distributed software with Internet functionality and interoperability. The .NET Framework consists of many class libraries, includes multiple language support and a common execution platform. It's a very flexible foundation on which many different types of top class applications can be developed that do different things. Developing Internet applications with the .NET Framework is very easy. ASP.NET is built into this framework; we can create ASP.NET applications using any of the built-in languages. Unlike ASP, ASP.NET uses the Common Language Runtime (CLR) provided by the .NET Framework. This CLR manages execution of the code we write. ASP.NET code is a compiled CLR code instead of interpreted code (ASP). CLR also allows objects written in different languages to interact with each other. The CLR makes development of Web applications simple.

Page 9

ASP.NET MATERIAL
Advantages Using ASP.NET:

ASP.NET drastically reduces the amount of code required to build large applications ASP.NET makes development simpler and easier to maintain with an eventdriven, server-side programming model ASP.NET pages are easy to write and maintain because the source code and HTML are together The source code is executed on the server. The pages have lots of power and flexibility by this approach The source code is compiled the first time the page is requested. Execution is fast as the Web Server compiles the page the first time it is requested. The server saves the compiled version of the page for use next time the page is requested The HTML produced by the ASP.NET page is sent back to the browser. The application source code you write is not sent and is not easily stolen ASP.NET makes for easy deployment. There is no need to register components because the configuration information is built-in The Web server continuously monitors the pages, components and applications running on it. If it noticies memory leaks, infinite loops, other illegal software or activities, it seamlessly kills those activities and restarts itself. ASP.NET validates information (validation controls) entered by the user without writing a single line of code ASP.NET easily works with ADO .NET using data-binding and page formatting features ASP.NET applications run fater and counters large volumes of users without performance problems

Differences between ASP.NET and Client-Side Technologies:


Client-side refers to the browser and the machine running the browser. Server-side on the other hand refers to a Web server.

Client-Side Scripting:
JavaScript and VBScript and generally used for Client-side scripting. Client-side scripting executes in the browser after the page is loaded. Using client-side scripting you can add some cool features to your page. Both, HTML and the script are together in the same file and the script is downloading as part of the page which anyone can view.

Page 10

ASP.NET MATERIAL
A client-side script runs only on a browser that supports scripting and specifically the scripting language that is used. Since the script is in the same file as the HTML and as it executes on the machine you use, the page may take longer time to download.

Server-Side Scripting:
ASP.NET is purely server-side technology. ASP.NET code executes on the server before it is sent to the browser. The code that is sent back to the browser is pure HTML and not ASP.NET code. Like client-side scripting, ASP.NET code is similar in a way that it allows you to write your code alongside HTML. Unlike client-side scripting, ASP.NET code is executed on the server and not in the browser. The script that you write alongside your HTML is not sent back to the browser and that prevents others from stealing the code you developed.

Difference between Asp and Asp.Net:

Introduction:
In 1996 I was programming web applications using the old HTX/IDC method. Hopefully, not too many people remember this type of programming. It was bulky and did not have anything to offer outside database connectivity. ASP was a big improvement over this method and I quickly moved to it. I do not see ASP to ASP.net as quite a big jump as HTX/IDC to ASP, but it still requires a bit of education. ASP.net is the next rendition of ASP with a little bit of a twist and in this document we will touch upon some of the differences between ASP and ASP.net. ASP is no longer an interpreted language; rather it is now a compiled language. What does that mean? It means that when a page is called in ASP the script is read and executed by a command line interpreter one line at a time. With ASP.net the pages are compiled common language code executing on the server. This allows for advantages and forces some changes in the traditional ASP programming.

Pros and Cons:


This new type of ASP coding allows for added performance benefit. This type of functionality is seen with COM Objects. Since COM Objects are pre-compiled they did not need to be interpreted every time the script was executed on the server. They are already in machine code and ready to go and thus give any code in COM Objects a performance boost. This also added a security benefit to COM Objects.

Page 11

ASP.NET MATERIAL
Since ASP scripts were always interpreted the code needed to be in the web pages themselves. Since COM Objects are pre-compiled the source code is much harder to hack and thus is not as susceptible to security breaches. ASP.net, being compiled has similar increased the security in the new framework. Another added benefit of ASP.net is its additional features that are included in the package. The functionality of these features can created in COM Objects, and some have been in the past. They have simply been included as part of the base package. Lastly, ASP.net adds another language to the fold, C#, known as C sharp. All the following examples will use VBScript, but I encourage a look at this new language. Now For the specific differences.

Rendered Ineffective:
The largest basic programming difference between ASP and ASP.net is the lost ability to program page-render functions. This means there will no longer be ASP functions with HTML intertwined throughout. I perceive this as the most radical change for current ASP programmers. One of the strengths of ASP was to easily drop functions into existing HTML web pages without much re-coding. ASP.net requires any HTML that appears within functions to be written to the screen using the response. write function. ASP: <% Option Explicit Function PrintHello Dim i For i= 1 to 5 %> <font size=<%=i%>>Hello</font>> <% Next End Function %>

Page 12

ASP.NET MATERIAL
Asp.net: <% Option Explicit Function PrintHello() Dim i For i= 1 to 5 response.write("<font size=" & i & "> Hello") <% Next End Function %>

Declaration of Independence from <% :


When a function is declared in ASP.net it must appear in a <script runat=server> block with the language declared. The days of <% %> whenever ASP was needed are gone. We must be careful to make sure our functions exist in these blocks or else they will generate an error. ASP: <% Sub HelloWrite() Response.Write "Hello World" End Sub HelloWrite %> Asp.net: <script language="VB" runat=server> Sub HelloWrite() Response.Write "Hello World" End Sub </script>

Page 13

ASP.NET MATERIAL
<% HelloWrite() %> An added change that you may notice as well is that function calls require that the parentheses () appear after the function name. I have gotten it to work without the parentheses but I think officially it is required.

Array of Sunlight (or not):


ASP allowed array values to be passed via a querystring or form post and then received by a request on the receiving page. In order to access these values you simply had to request the variable with the array position following. This type of system was based upon a 1-index, meaning the first value was always in the 1 position. There are two big changes here. First of all, it has changed to a 0-index, meaning the first value will be in the 0 position. This is more concurrent with other compiled languages. Secondly, in order to access the values in an array from a querystring or the like the GetValues method must be called. ASP: <% Variable1=Request.QueryString("values")(1) %> Asp.net: <% variable1=(Request.QueryString.GetValues("values")(0) %>

Ready, Set, Go! :


With ASP whenever an object was created or a database connection needed to be made a variable was usually assigned using Set". In Asp.net there is no more need for variables to be Set, the variable must be simply made to be equal. This also applies to "Let".

ASP:

Page 14

ASP.NET MATERIAL
<% Dim Connection Set Connection = Server.CreateObject("ADODB.Connection") %> Asp.net: <% Dim Connection Connection = Server.CreateObject("ADODB.Connection") %>

I need an index please:


With some components, such as the ADO component, a default non-indexed property could be referred by simply referring to the object itself. This allowed for a shortcut in programming. However, in this more structured environment, this is no longer allowed. When an object is referred to the property must be called. ASP: <% Connection = Server.CreateObject("ADODB.Connection") Connection .Open("MyDatabase") RS = Connection .Execute("Select * from Operations") Response.Write(RS("ID")) %> Asp.net: <% Connection = Server.CreateObject("ADODB.Connection") Connection .Open("MyDatabase") RS = Connection .Execute("Select * from Operations") Response.Write(RS("ID").Value) %> In the above ASP.net example the "Value" property must be explicitly indicated or it would not recognize what value to write to the screen and would generate an error.

Page 15

ASP.NET MATERIAL
Oops!:
When an ASP.net page is run, if you are on the machine that the code is being executed on, or you have a web.config file in the root directory of the website configured properly, error messages that appear are a little more intuitive than the current error messages. In ASP error messages can be somewhat vague, but with ASP.net, the specific line of code that is causing the error is displayed with a little better description. This allows for an easier debugging time than before.

Bi-lingual I am not:
One large difference between ASP and ASP.net is ASP.net does not contain the capability to have multiple languages on a single page. This means you can not switch between VBScript to JScript and then back again. You still can have different languages on different pages within the same application, however.

I have a new extension, please forward all my calls:


The one last final and perhaps most minute change is ASP.net pages require a different extension. When a page is created in ASP.net it requires an .aspx extension, which you may notice this web page has as well. When a page has this extension IIS knows to treat it as an ASP.net page instead of an older ASP page.

Conclusion:
As you can see there are some changes to ASP, but with a little education you can easily move into the realm of ASP.net. I know a large concern for me is whether all the old ASP programming will need to be changed. Eventually, perhaps, but for now the old asp.dll is still available and has not been altered by these new improvements. Instead, Microsoft has put these changes into other libraries. All the old code you know and love will still run under ASP, but if you want to change to ASP.net there will be some time involved. For now, I think I will stick to updating my old code in ASP and writing new code in ASP.net.

Page 16

ASP.NET MATERIAL

In page and Code behind technique

Microsoft recommends dealing with dynamic program code by using the code-behind model, which places this code in a separate file or in a specially designated script tag. Code-behind files typically have names like MyPage.aspx.cs or MyPage.aspx.vb while the page file is MyPage.aspx (same filename as the page file (ASPX), but with the final extension denoting the page language). This practice is automatic in Microsoft Visual Studio and other IDEs. When using this style of programming, the developer writes code to respond to different events, like the page being loaded, or a control being clicked, rather than a procedural walk through the document. ASP. Nets code-behind model marks a departure from Classic ASP in that it encourages developers to build applications with separation of presentation and content in mind. In theory, this would allow a web designer, for example, to focus on the design markup with less potential for disturbing the programming code that drives it. This is similar to the separation of the controller from the view in model-view-controller frameworks.

Example:
<%@ Page Language="C#" CodeFile="SampleCodeBehind.aspx.cs" Inherits="Website.SampleCodeBehind" AutoEventWireup="true" %> The above tag is placed at the beginning of the ASPX file. The CodeFile property of the @ Page directive specifies the file (.cs or .vb) acting as the code-behind while the Inherits property specifies the Class the Page derives from. In this example, the @ Page directive is included in SampleCodeBehind.aspx, then SampleCodeBehind.aspx.cs acts as the code-behind for this page: using System; namespace Website { public partial class SampleCodeBehind : System.Web.UI.Page { Protected void Page_ Load (object sender, EventArgs e) { Response. Write ("Hello, world"); } } }

Page 17

ASP.NET MATERIAL

SERVER SIDE CONTROLS


In ASP.Net you have server side controls apart from the ordinary html controls that are used in the web page. The server side controls are executed on the server and they have an attribute runat=server. This attribute that is found in the control indicates that it is a server side control. The main advantage of using the server side control is that you can separate the code that is executed and the code that is used for display. By using the object oriented programming model of the server side control you can even create complex server side controls. They have rich set of properties, methods, and events. There are basically three types of server side controls in ASP.Net. They are HTML Server Controls, Web Server Controls, and Validation Server Controls. The html server controls are ordinary html controls with an added attribute runat=server. The web server controls have the syntax, <tag_prefix:control_name attributes runat="server"/> The validation server controls also have the same syntax and they are used to validate the input that is given by the user in the forms. With this validation server controls you can also throw some error message to the user if their input is invalid.

Client Side Controls Vs Server Side Controls:

I receive an excessive number of questions asking for help and asking how to do certain coding tasks. One question this week caught me by surprise. In a prior article, I presented a method for separating the scripting code form your actual HTML files. This raised the question about running the JavaScript on the server rather than on the client so that the client could not see the code. This question raised a critical issue for understanding Web programs to understand the different types of Web applications that can be created, you should understand the difference between client-side and server-side code. Web pages are displayed in your browser on your local machine. Just like a customer or client for a restaurant, you and your browser are a client using a Web site. The Web site is displayed by your browser, which interprets code that was sent to it. In general this code will be primarily HTML, but may also contain anything supported by your browser such as JavaScript, flash movies, and more.

Page 18

ASP.NET MATERIAL
The machine where the Web site actually resides is called a Web server. When you send a request for a Web page by entering a Web site address, this request is sent to a Web Server. The Web server then sends the Web page to your browser. The interesting thing about a Web server is that it can manipulate the code within a Web page before sending it to your browser. For most Web pages, no manipulation is done. Rather, the server simply sends a copy to the browser and the browser does the work of displaying the code. A Web Server can manipulate what is included in a Web page before sending it. When the request is made to a server to send a Web page, the server can actually execute a program instead. This can be a program written in a variety of languages. Some of the programming languages and technologies that can be used are Active Server Pages (ASP), PHP, C/C++, and ISAPI, Java Server Pages (JSP), and more. Of course, in order to use any of these languages. An important issue when working with Web applications is to remember that the Web server is separate from the Web browsers that will use a Web site's pages. The Web server can be located anywhere in the world -- or even off the world! The browser is generally on a machine you are using. Stated a different way, you can act as a customer, or client, using a browser to access a Web site that is located on a Web server. The programs running on the Web Server are server side programs because they are on the side of the internet that the Web server is on. The browser being used to access the Web site is on the same side of the Web as you, the client side. If code is executed on the Web server, it is considered server side code. If code is executed on your browser, it is considered client-side. Because the internet is vast, the client side and server side programs are not constantly in contact with each other. Because of this, there is code that you can use on the server and there is code that you can use on the client.

What do you do on the server?


There are a number of types of programming things that can be done on the server. One of the primary functions you can do with code is to prepare the code that is to be sent to the Web browser. This includes such tasks as building pages customized for the type of browser that requested a page. It could also include doing tapping into a database to create information for a Web page. A very popular server side program is a Visitor Counter that keeps track of the number of people who have accessed a Web Site. The counter program would keep track of people who have come and store the information. It would also provide the actual number for any Web pages that are sent back to a browser.

What do you do on the client?


HTML, JavaScript, Flash files, ActiveX controls, Java applets, and a number of other technologies can be executed on the client side. You can execute any technology

Page 19

ASP.NET MATERIAL
supported by your browser. Client side programming is used because the browser is separate from the server. By including code within a web page, a number of features can be added to a Web page without the need to send information to the Web Server which takes time. Tasks done on the client side include data validation, special formatting features that go beyond HTML, controls that take care of page navigation and ad presentation, and more.

Types of Server Side Controls (Html Server Controls, Web Server Controls)
When you create Web Forms pages, you can use these types of controls:

HTML server controls HTML elements exposed to the server so you can
program them. HTML server controls expose an object model that maps very closely to the HTML elements that they render. Web server controls Controls with more built-in features than HTML server controls. Web server controls include not only form-type controls such as buttons and text boxes, but also special-purpose controls such as a calendar. Web server controls are more abstract than HTML server controls in that their object model does not necessarily reflect HTML syntax. Validation controls Controls that incorporate logic to allow you to test a user's input. You attach a validation control to an input control to test what the user enters for that input control. Validation controls are provided to allow you to check for a required field, to test against a specific value or pattern of characters, to verify that a value lies within a range, and so on. User controls Controls that you create as Web Forms pages. You can embed Web Forms user controls in other Web Forms pages, which is an easy way to create menus, toolbars, and other reusable elements.

HTML Server Controls:


HTML server controls are HTML elements containing attributes that make them visible to and programmable on the server. By default, HTML elements on a Web Forms page are not available to the server; they are treated as opaque text that is passed through to the browser. However, by converting HTML elements to HTML server controls, you expose them as elements you can program on the server.

The object model for HTML server controls maps closely to that of the corresponding elements. For example, HTML attributes are exposed in HTML server controls as properties.

Page 20

ASP.NET MATERIAL
Any HTML element on a page can be converted to an HTML server control. Conversion is a simple process involving just a few attributes. As a minimum, an HTML element is converted to a control by the addition of the attribute RUNAT="SERVER". This alerts the ASP.NET page framework during parsing that it should create an instance of the control to use during server-side page processing. If you want to reference the control as a member within your code, you should also assign an ID attribute to the control. The page framework provides predefined HTML server controls for the HTML elements most commonly used dynamically on a page: forms, the HTML <INPUT> elements (text box, check box, Submit button, and so on), list box (<SELECT>), table, image, and so on. These predefined HTML server controls share the basic properties of the generic control, and in addition, each control typically provides its own set of properties and its own event.

HTML server controls offer the following features:

An object model that you can program against on the server using the familiar object-oriented techniques. Each server control exposes properties that allow you to manipulate the control's HTML attributes programmatically in server code. A set of events for which you can write event handlers in much the same way you would in a client-based form, except that the event is handled in server code. The ability to handle events in client script. Automatic maintenance of the control's state. If the form makes a round trip to the server, the values that the user entered into HTML server controls are automatically maintained when the page is sent back to the browser. Interaction with validation controls so you can easily verify that a user has entered appropriate information into a control. Data binding to one or more properties of the control. Support for HTML 4.0 styles if the Web Forms page is displayed in a browser that supports cascading style sheets. Pass-through of custom attributes. You can add any attributes you need to an HTML server control and the page framework will read them and render them without any change in functionality. This allows you to add browser-specific attributes to your controls.

Page 21

ASP.NET MATERIAL

Web Server Controls:


Web server controls are a second set of controls designed with a different emphasis. They do not map one-to-one to HTML server controls. Instead, they are defined as abstract controls in which the actual HTML rendered by the control can be quite different from the model that you program against. For example, a RadioButtonList Web server control might be rendered in a table or as inline text with other HTML. Web server controls include traditional form controls such as buttons and text boxes as well as complex controls such as tables. They also include controls that provide commonly used form functionality such as displaying data in a grid, choosing dates, and so on. Web server controls offer all of the features described above for HTML server controls (except one-to-one mapping to HTML elements) and these additional features:

A rich object model that provides type-safe programming capabilities. Automatic browser detection. The controls can detect browser capabilities and create appropriate output for both basic and rich (HTML 4.0) browsers. For some controls, the ability to define your own look for the control using templates. For some controls, the ability to specify whether a control's event causes immediate posting to the server or is instead cached and raised when the form is submitted. Ability to pass events from a nested control (such as a button in a table) to the container control.

Validation Server Controls:


Validation server controls enable you to check user input in ASP.NET server controls such as a Textbox and to display a custom message if validation fails. Each validation control performs a specific type of validation. For example, you can check for a specific value or a range of values by using the CompareValidator and RangeValidator controls, respectively. You can also define your own validation criteria using the CustomValidator control. You can specify the location of an error message on the Web page by placing a validation control where you want the message to appear. You can also display a summary of the results from all validation controls on the page by using the Validation Summary control.

Page 22

ASP.NET MATERIAL
By default, validation is performed when a button control such as Button, Image Button, or Link Button is clicked. You can prevent validation from being performed when a button control is clicked by setting the button control's Causes Validation property to false. This property is normally set to false for a cancel or clear button to prevent validation from being performed when the button is clicked.

User Controls:
At times, you might need functionality in a control that is not provided by the built-in ASP.NET Web server controls. In those cases, you can create your own controls. You have two options. You can create:

User controls. User controls are containers into which you can put markup and Web server controls. You can then treat the user control as a unit and define properties and methods for it. Custom controls. A custom control is a class that you write that derives from Control or Web Control.

User controls are substantially easier to create than custom controls, because you can reuse existing controls. They make it particularly easy to create controls with complex user interface elements.

User Control Structure:


An ASP.NET Web user control is similar to a complete ASP.NET Web page (.aspx file), with both a user interface page and code. You create the user control in much the same way you create an ASP.NET page and then add the markup and child controls that you need. A user control can include code to manipulate its contents like a page can, including performing tasks such as data binding. A user controls differs from an ASP.NET Web page in these ways:

The file name extension for the user control is .ascx. Instead of an @ Page directive, the user control contains an @ Control directive that defines configuration and other properties. User controls cannot run as stand-alone files. Instead, you must add them to ASP.NET pages, as you would any control. The user control does not have html, body, or form elements in it. These elements must be in the hosting page.

Page 23

ASP.NET MATERIAL HTML Server Controls Programming using in page technique.


ASP.NET HTML Server Controls are the HTML controls that run at the server-side i.e. they have runat=server attribute. You can also have normal HTML controls in your ASP.NET page, but these controls will run only at the client-side. Therefore, using ASP.NET HTML Server Controls you can make full use of the .Net Framework utilities such as ViewState management and validation. ASP.NET HTML Server Controls must have the <form> tags enclosing them with runat=server attribute. The ASP.NET HTML Server Controls that you can apply in ASP.NET page are as follows: HTMLAnchor: Creates a server-side control that links to the <a> HTML element. The <a> element is used to create a link to another page. You can place an HTMLAnchor control within the HTMLForm control. HTMLButton: Creates a server-side control button that maps to the <button> HTML element. This ASP.NET HTML Server Control has various methods to modify the appearance of an HtmlButton control. You can assign style attributes to the button, include formatting elements or assign property value. You can also include images within the button elements themselves, or even include other Web Forms controls. HTMLImage: Creates a server-side control that allows you to view an image. In addition, you can set and retrieve the image's source, width, height, border width, alternate text, and alignment by using the Src, Width, Height, Border, Alt, and Align properties of this ASP.NET HTML Server Control. The HTMLImage control does not require a closing tag. HTMLForm: Creates a server-side control that allows you to place multiple controls in it. The HTMLForm control must have an opening and closing tags. If both the tags are not available, either the elements in it will not be viewed or run in the browser window or the compilation error message will occur. HTMLGeneric: Creates a server-side control for the HTML elements such as <body>, <div>, <span>, and <font>. This control links the tags of the particular element to be used as an HTML control to ASP.NET through the TagName property. This ASP.NET HTML Server Control has functionality of the HtmlContainerControl class, which allows you to dynamically change inner content of HTML control tags.

Page 24

ASP.NET MATERIAL ASP.NET Page Execution Architecture


The ASP .Net is proved to be a worth while time spent by programmers to create applications, by providing a very rich Framework Class Library (FCL), Performance tuning, Security, Manageability etc., It has been said and written that ASP .Net follows a compiled execution model. Sometimes we used to get some doubts about whether writing the code inside the code behind file is faster, some times we are not aware of how the compilation of the code happens etc., This article tries to take a brief look at some of the internals about the ASP .Net Compiled Page Rendering and Execution model along with some other related concepts, clearing such doubts. Compilation of ASP .Net Pages: It is a well known fact that ASP .Net pages functional logic can be written in two ways. The ASP .Net code can either be written inside the ASPX page or it can be included as a asp_net_code.cs or vb .net file. When the ASPX page is embedded with the code of either C# or VB .Net, the ASP .Net run time automatically compiles the code into an assembly and loads it. If the code is kept in a separate source file either as a VB or C# file, it has to be compiled by the programmer, which will be used by the run time for further execution. Compilation of Script Inside the aspx pages: When a page is created with the tags inside the .aspx page itself, the code can be written at two locations. It can either be placed inside the <script runat="server">...</script> tag or any where inside the page within the <%.. %> server code blocks. When the code is placed inside the script tag, it is treated to be class level code and any other code found is considered to be a part of the method that renders the web page. When a the aspnet_wp.exe gets a request for an aspx page which is written without a code behind class file, it generates a class file dynamically for the corresponding page and places it inside the Temporary ASP .Net Files somewhere under the tree structure of the .Net installation path. Then it compiles this into a DLL and finally deletes the class file after successful compilation. It will render the pages from the same binary DLL for any subsequent requests. If it sees any change in the time stamp of the .aspx file, it recognizes that there is some change and recompiles it again for further use.

Page 25

ASP.NET MATERIAL
So ultimately the compilation is only once and all the subsequent requests are entertained only by using the compiled code/DLL. Writing ASP .Net Apps with Code behind files: The compilation of these Code Behind files is usually done manually either using the csc.exe command line compiler or by using the Build feature in Microsoft Visual Studio .Net, which produces an output as a library with an extension of .DLL. Now the job of aspnet_wp.exe is very simple. It can directly execute the compiled code and return the HTML page to the web server. Execution Flow of ASPX Pages by IIS: The execution of ASP .Net pages are not singly handled by the Internet Information Server or in short hand form IIS. It is taken care by the worker process aspnet_wp.exe. Whenever the IIS receives a request from a web browser or a client requesting for a page, it delegates the job to the aspnet_wp.exe process, which takes care of the subsequent jobs and finally returns the HTML page back to the IIS. When ASP .Net is installed, installation process creates an association for .aspx files with the aspnet_isapi.dll files. When the IIS receives a request from the clients or web browsers for an aspx page, the IIS web server hands this request over to the aspnet_isapi.dll, which in turn instantiates the aspnet_wp.exe job. This aspnet_wp.exe finalizes any unfinished jobs like run time compilation etc., as explained above and then executes the asp .net application in a new application domain. Finally the output page is generated and returned back to the web server, which in-turn sends the file over to the client. Conclusion: The above is a very robust model of executing an application extending support to both the code behind and code embedded inside aspx pages. Ultimately writing the code in any place be it inside the code behind files or inside the aspx page will always be faster and will not have any performance difference between the two approaches.

Page 26

ASP.NET MATERIAL ASP.NET Worker Process


ASP.NET runs within a process known as the ASP.NET worker process. All ASP.NET functionality runs within the scope of this process. A regular Web server contains only a single ASP.NET worker process. This is different from both Web farms and Web gardens:

A Web farm contains multiple ASP.NET worker processes. Each server in the group of servers handles a separate ASP.NET worker process.

A Web garden contains multiple ASP.NET worker processes. Each CPU in the SMP server handles a separate ASP.NET worker process.

Choosing an ASP.NET worker process: When a Web client connects to a Web farm or Web garden, one of the multiple ASP.NET worker processes is selected to run the request.

In a Web farm, Network Load Balancing determines the ASP.NET worker process selected. In a Web garden, the ASP.NET worker process selected is determined by ASP.NET.

State management with multiple ASP.NET worker processes: When moving from a scenario with a single ASP.NET worker process (a normal Web server) to a scenario with multiple ASP.NET worker processes (a Web farm or Web garden), complications with state management are introduced. Web pages are stateless, so a Web server must persist state through other means. Typical means to manage state on the Web server include Session State and the ASP.NET Cache.

Page 27

ASP.NET MATERIAL ASP.NET Page Life Cycle Events

When an ASP.NET page runs, the page goes through a life cycle in which it performs a series of processing steps. These include initialization, instantiating controls, restoring and maintaining state, running event handler code, and rendering. It is important for you to understand the page life cycle so that you can write code at the appropriate life-cycle stage for the effect you intend. If you develop custom controls, you must be familiar with the page life cycle in order to correctly initialize controls, populate control properties with view-state data, and run control behavior code. The life cycle of a control is based on the page life cycle, and the page raises many of the events that you need to handle in a custom control. This topic contains the following sections:

General Page Life-cycle Stages Life-cycle Events Additional Page Life Cycle Considerations Catch-Up Events for Added Controls Data Binding Events for Data-Bound Controls Login Control Events

General Page Life-Cycle Stages: In general terms, the page goes through the stages outlined in the following table. In addition to the page life-cycle stages, there are application stages that occur before and after a request but are not specific to a page.. Some parts of the life cycle occur only when a page is processed as a postback. For postbacks, the page life cycle is the same during a partial-page postback (as when you use an UpdatePanel control) as it is during a full-page postback.

Page 28

ASP.NET MATERIAL

Stage

Description The page request occurs before the page life cycle begins. When the page is requested by a user, ASP.NET determines whether the page needs to be Page request parsed and compiled (therefore beginning the life of a page), or whether a cached version of the page can be sent in response without running the page. In the start stage, page properties such as Request and Response are set. At this stage, the page also determines whether the request is a postback or Start a new request and sets the IsPostBack property. The page also sets the UICulture property. During page initialization, controls on the page are available and each control's UniqueID property is set. A master page and themes are also Initialization applied to the page if applicable. If the current request is a postback, the postback data has not yet been loaded and control property values have not been restored to the values from view state. During load, if the current request is a postback, control properties are Load loaded with information recovered from view state and control state. If the request is a postback, control event handlers are called. After that, Postback event the Validate method of all validator controls is called, which sets the handling IsValid property of individual validator controls and of the page. Before rendering, view state is saved for the page and all controls. During the rendering stage, the page calls the Render method for each control, Rendering providing a text writer that writes its output to the OutputStream object of the page's Response property. The Unload event is raised after the page has been fully rendered, sent to Unload the client, and is ready to be discarded. At this point, page properties such as Response and Request are unloaded and cleanup is performed. Life-Cycle Events: Within each stage of the life cycle of a page, the page raises events that you can handle to run your own code. For control events, you bind the event handler to the event, either declaratively using attributes such as onclick, or in code. Pages also support automatic event wire-up, meaning that ASP.NET looks for methods with particular names and automatically runs those methods when certain events are raised. If the AutoEventWireup attribute of the @ Page directive is set to true, page events are automatically bound to methods that use the naming convention of

Page 29

ASP.NET MATERIAL
Page_event, such as Page_Load and Page_Init. For more information on automatic event wire-up. The following table lists the page life-cycle events that you will use most frequently. There are more events than those listed; however, they are not used for most pageprocessing scenarios. Instead, they are primarily used by server controls on the ASP.NET Web page to initialize and render themselves. If you want to write custom ASP.NET server controls, you need to understand more about these events. For information about creating custom controls. Page Event Typical Use Raised after the start stage is complete and before the initialization stage begins. Use this event for the following:

PreInit

Check the IsPostBack property to determine whether this is the first time the page is being processed. The IsCallback and IsCrossPagePostBack properties have also been set at this time. Create or re-create dynamic controls. Set a master page dynamically. Set the Theme property dynamically. Read or set profile property values. Note

Init InitComplete

If the request is a postback, the values of the controls have not yet been restored from view state. If you set a control property at this stage, its value might be overwritten in the next event. Raised after all controls have been initialized and any skin settings have been applied. The Init event of individual controls occurs before the Init event of the page. Use this event to read or initialize control properties. Raised at the end of the page's initialization stage. Only one operation takes place between the Init and InitComplete events: tracking of view state changes is turned on. View state tracking enables controls to persist any values that are programmatically added to the ViewState collection. Until view state tracking is turned on, any values added to view state are lost across postbacks. Controls

Page 30

ASP.NET MATERIAL
typically turn on view state tracking immediately after they raise their Init event. Use this event to make changes to view state that you want to make sure are persisted after the next postback. Raised after the page loads view state for itself and all controls, and after it processes postback data that is included with the Request instance. The Page object calls the OnLoad method on the Page object, and then recursively does the same for each child control until the page and all controls are loaded. The Load event of individual controls occurs after the Load event of the page. Use the OnLoad event method to set properties in controls and to establish database connections. Use these events to handle specific control events, such as a Button control's Click event or a TextBox control's TextChanged event. Control events Note In a postback request, if the page contains validator controls, check the IsValid property of the Page and of individual validation controls before performing any processing. Raised at the end of the event-handling stage. Use this event for tasks that require that all other controls on the page be loaded. Raised after the Page object has created all controls that are required in order to render the page, including child controls of composite controls. (To do this, the Page object calls EnsureChildControls for each control and for the page.) The Page object raises the PreRender event on the Page object, and then recursively does the same for each child control. The PreRender event of individual controls occurs after the PreRender event of the page.

PreLoad

Load

LoadComplete

PreRender

Use the event to make final changes to the contents of the page or its controls before the rendering stage begins. Raised after each data bound control whose DataSourceID property PreRenderComplete is set calls its DataBind method. For more information, see Data Binding Events for Data-Bound Controls later in this topic. SaveStateComplete Raised after view state and control state have been saved for the page

Page 31

ASP.NET MATERIAL
and for all controls. Any changes to the page or controls at this point affect rendering, but the changes will not be retrieved on the next postback. This is not an event; instead, at this stage of processing, the Page object calls this method on each control. All ASP.NET Web server controls have a Render method that writes out the control's markup to send to the browser. If you create a custom control, you typically override this method to output the control's markup. However, if your custom control incorporates only standard ASP.NET Web server controls and no custom markup, you do not need to override the Render method. For more information, see Developing Custom ASP.NET Server Controls. A user control (an .ascx file) automatically incorporates rendering, so you do not need to explicitly render the control in code. Raised for each control and then for the page. In controls, use this event to do final cleanup for specific controls, such as closing control-specific database connections. For the page itself, use this event to do final cleanup work, such as closing open files and database connections, or finishing up logging or other request-specific tasks. Note During the unload stage, the page and its controls have been rendered, so you cannot make further changes to the response stream. If you attempt to call a method such as the Response.Write method, the page will throw an exception. Additional Page Life Cycle Considerations: Individual ASP.NET server controls have their own life cycle that is similar to the page life cycle. For example, a control's Init and Load events occur during the corresponding page events. Although both Init and Load recursively occur on each control, they happen in reverse order. The Init event (and also the Unload event) for each child control occur before the

Render

Unload

Page 32

ASP.NET MATERIAL
corresponding event is raised for its container (bottom-up). However the Load event for a container occurs before the Load events for its child controls (top-down). When you create a class that inherits from the Page class, in addition to handling events raised by the page, you can override methods from the page's base class. For example, you can override the page's InitializeCulture method to dynamically set culture information. Note that when an event handler is created using the Page_event syntax, the base implementation is implicitly called and therefore you do not need to call it in your method. For example, the base page class's OnLoad method is always called, whether you create a Page_Load method or not. However, if you override the page OnLoad method with the override keyword (Overrides in Visual Basic), you must explicitly call the base method. For example, if you override the OnLoad method on the page, you must call base.Load (MyBase.Load in Visual Basic) in order for the base implementation to be run. The following illustration shows some of the most important methods of the Page class that you can override in order to add code that executes at specific points in the page life cycle. (For a complete list of page methods and events, see the Page class.) The illustration also shows how these methods relate to page events and to control events. The sequence of methods and events in the illustration is from top to bottom, and within each row from left to right.

Page 33

ASP.NET MATERIAL

Page 34

ASP.NET MATERIAL
Catch-Up Events for Added Controls: If controls are created dynamically at run time or declaratively within templates of databound controls, their events are initially not synchronized with those of other controls on the page. For example, for a control that is added at run time, the Init and Load events might occur much later in the page life cycle than the same events for controls created declaratively. Therefore, from the time that they are instantiated, dynamically added controls and controls in templates raise their events one after the other until they have caught up to the event during which it was added to the Controls collection. Data Binding Events for Data-Bound Controls: To help you understand the relationship between the page life cycle and data binding events, the following table lists data-related events in data-bound controls such as the GridView, DetailsView, and FormView controls. Control Event Typical Use Raised after the control's PreRender event, which occurs after the page's PreRender event. (This applies to controls whose DataSourceID property is set declaratively. Otherwise the event happens when you call the control's DataBind method.) This event marks the beginning of the process that binds the control to the data. Use this event to manually open database connections, if required, and to set parameter values dynamically before a query is run. Raised after the control's DataBinding event.

DataBinding

RowCreated (GridView only) or ItemCreated (DataList, Use this event to manipulate content that is not DetailsView, SiteMapPath, dependent on data binding. For example, at run time, DataGrid, FormView, Repeater, you might programmatically add formatting to a and ListView controls) header or footer row in a GridView control. Raised after the control's RowCreated or ItemCreated event. RowDataBound (GridView only) or ItemDataBound (DataList, When this event occurs, data is available in the row SiteMapPath, DataGrid, Repeater, or item, so you can format data or set the and ListView controls) FilterExpression property on child data source controls in order to display related data within the row or item.

Page 35

ASP.NET MATERIAL
Raised at the end of data-binding operations in a data-bound control. In a GridView control, data binding is complete for all rows and any child controls. DataBound Use this event to format data-bound content or to initiate data binding in other controls that depend on values from the current control's content. (For more information, see Catch-Up Events for Added Controls earlier in this topic.)

Nested Data-Bound Controls: If a child control has been data bound, but its container control has not yet been data bound, the data in the child control and the data in its container control can be out of sync. This is true particularly if the data in the child control performs processing based on a data-bound value in the container control. For example, suppose you have a GridView control that displays a company record in each row, and it displays a list of the company officers in a ListBox control. To fill the list of officers, you would bind the ListBox control to a data source control (such as SqlDataSource) that retrieves the company officer data using the company ID in a query. If the ListBox control's data-binding properties, such as DataSourceID and DataMember, are set declaratively, the ListBox control will try to bind to its data source during the containing row's DataBinding event. However, the CompanyID field of the row does not contain a value until the GridView control's RowDataBound event occurs. In this case, the child control (the ListBox control) is bound before the containing control (the GridView control) is bound, so their data-binding stages are out of sync. To avoid this condition, put the data source control for the ListBox control in the same template item as the ListBox control itself, and do not set the data binding properties of the ListBox declaratively. Instead, set them programmatically at run time during the RowDataBound event, so that the ListBox control does not bind to its data until the CompanyID information is available. Login Control Events: The Login control can use settings in the Web.config file to manage membership authentication automatically. However, if your application requires you to customize how the control works, or if you want to understand how Login control events relate to the page life cycle, you can use the events listed in the following table.

Page 36

ASP.NET MATERIAL
Control Event LoggingIn Use this event for tasks that must occur prior to beginning the authentication process. Raised after the LoggingIn event. Authenticate Use this event to override or enhance the default authentication behavior of a Login control. Raised after the user name and password have been authenticated. Use this event to redirect to another page or to dynamically set the text in the control. This event does not occur if there is an error or if authentication fails. Raised if authentication was not successful. Use this event to set text in the control that explains the problem or to direct the user to a different page. Typical Use Raised during a postback, after the page's LoadComplete event has occurred. This event marks the beginning of the login process.

LoggedIn

LoginError

ASP.NET standard controls:

The topics in this section describe how to work with ASP.NET standard controls. These include controls that you can use to display buttons, lists, images, boxes, hyperlinks, labels, and tables, in addition to more complicated controls that work with static and dynamic data, and controls that act as containers for other controls.

AdRotator control : The AdRotator control can be used to display graphics that are linked to other pages. The list of graphics to be displayed, and the target links associated with them, is maintained in a data source such as an XML file or database. For more information about the AdRotator control. BulletedList control: The BulletedList control creates an unordered or ordered (numbered) list of items, which render as HTML UL or OL elements, respectively. For a full description of all Bulleted List control properties. Button control: The Button control enables users to post a page to the server and to trigger an event on a page. For details about writing code for button controls. Calendar control: The Calendar control can display selectable dates in a calendar and data associated with specific dates. For more information about the Calendar control.

Page 37

ASP.NET MATERIAL

Checkbox control: The Checkbox control enables users to specify yes/no (true/false) choices for individual items. For more information about managing Checkbox and Checkbox List controls. CheckBoxList control : The Checkbox List control enables users to specify yes/no (true/false) choices for items in a list. For more information about managing Checkbox and Checkbox List controls. ContentPlaceholder control : The ContentPlaceholder control defines a region for content in an ASP.NET master page. For more information about the ContentPlaceHolder control. DropDownList control : The DropDownList control enables users to select a single item from a predefined drop-down list. For a full description of all DropDownList control properties. FileUpload control: The FileUpload control enables you to give users a way to send files from their computers to the server. For more information about the FileUpload control. HiddenField control: The HiddenField control gives you a way to store information in the page without displaying it. For more information about the HiddenField control. HyperLink control: The HyperLink control creates links that enable users to move from page to page in an application. For more information about working with the HyperLink control. Image control: The Image control enables you to display images on an ASP.NET web page and manage these images in your own code. For more information about working with the Image control. ImageButton control: The ImageButton control displays an image and responds to mouse clicks on the image. For a full description of all ImageButton control properties. ImageMap control: The ImageMap control enables you to create an image that has individual regions, called hot spots. Each of these hot spots can be a separate hyperlink or postback event. For a full description of all ImageMap control properties. Label control: The Label control lets you programmatically set text in an ASP.NET web page. For a full description of all Label control properties. LinkButton control: The LinkButton control displays a hyperlink-style button that contains client-side script to post form data back to the server. For a full description of all LinkButton control properties. ListBox control: The ListBox control enables users to select one or more items from a predefined list. For a full description of all ListBox control properties. Literal control: The Literal control is used as a container for other content on the page. For a full description of all Literal control properties. Localize control: The Localize control lets you display localized text in a specific area on your page. For information about localizing text using resource strings and the Localize control.

Page 38

ASP.NET MATERIAL

MultiView control: The MultiView and View controls act as containers for other controls and markup, and enable you to easily present alternative views of information. For more information about using MultiView and View controls. Panel control: The Panel control provides a container control in an ASP.NET web page that you can use as a parent for static text and for other controls. For more information about the Panel control. PlaceHolder control: The PlaceHolder control lets you place an empty container control in the page and then dynamically add child elements to it at run time. For a full description of all PlaceHolder control properties. RadioButton control: The RadioButton control and the RadioButtonList control enable users to select from a small set of mutually exclusive, predefined choices. For a full description of all RadioButton control properties. RadioButtonList control: The RadioButton control and the RadioButtonList control enable users to select from a small set of mutually exclusive, predefined choices. For a full description of all RadioButton control properties. Substitution control: The Substitution control lets you create areas on the page that can be updated dynamically and then integrated into a cached page. For a full description of all Substitution control properties. Table control: The Table control enables you to create tables that you can program in server code. For a full description of all Table control properties. TextBox control: The TextBox control enables users to type information into an ASP.NET web page, including text, numbers, and dates. For a full description of all TextBox control properties. View control: The MultiView and View controls act as containers for other controls and markup, and enable you to easily present alternative views of information. For more information about using MultiView and View controls. Wizard control: The Wizard control simplifies many of the tasks that are associated with building a series of forms to collect user input. For more information about using the Wizard control. XML control: The XML control is used to display the contents of an XML document, either without formatting or by using XSL transformations. For more information about using the XML control.

File Upload Control:


Finally ASP.NET 2.0 has a File Upload control, which allows developers to drop the control on a page and let it browse a file and upload it on the server. To create a control, simply drop the FileUpload control from Toolbox to a Web page. The following code adds the FileUpLoad control: <asp:FileUpLoad id="FileUpLoad1" runat="server" />

Page 39

ASP.NET MATERIAL
To support file upload , we need to add a Button control: <asp:Button id="UploadBtn" Text="Upload File" OnClick="UploadBtn_Click" runat="server" Width="105px" /> Now on this button click event handler, we need to call SaveAs method of FileUpLoad control, which takes a full path where the file will be uploaded. protected void UploadBtn_Click(object sender, EventArgs e) { if (FileUpLoad1.HasFile) { FileUpLoad1.SaveAs(@"C:\temp\" + FileUpLoad1.FileName); Label1.Text = "File Uploaded: " + FileUpLoad1.FileName ; } else { Label1.Text = "No File Uploaded."; } } The final page looks like Figure 1.

Working with Rich Controls-Calendar, Ad rotator:

Page 40

ASP.NET MATERIAL
Introduction: In the last article we saw some of the simple controls. Those included validation controls, TextBox, Label and other simple controls. Microsoft.net framework provides the developer with more advanced controls. Among those are the Calendar, AdRotator and the Xml Control. In this Tutorial we will see how we can make use of the rich controls providedbytheframework. Calendar Control:

Calendar control as it sounds like is used to pick a date from a visual calendar. By using the calendar control the developer can easily pick a date which can later be used by other operations. Lets see how we can place a simple calendar control on a page. In the toolbox which normally appears on the left hand side of the Visual Studio.NET 2003 window you can find the Calendar control. Just drag and drop the control on the form. After you drop the calendar your display will look like this:

As you see above the calendar control appears with no colors. Although it will work as expected but sometimes we need to make things pretty. If you want to apply a certain style quickly on the calendar control just right click on it and select Auto Format. Here you can choose different styles. Once you have chosen the style that you like apply it.

Page 41

ASP.NET MATERIAL

Lets see how we can get the selected date from the calendar control. Whenever you click a mouse on the date in the calendar control the Selection_Changed event is fired. Hence if we want to change something on the calendar date click event we have to place it in the Selection_Changedmethod. Private void Calendar1_SelectionChanged (object sender, System.EventArgs e) { Response.Write(Calendar1.SelectedDate.ToShortDateString()); } so, now when we click on the date in the calendar it displays the selected date as you can see in the image below. There are countless number of methods available for the calendar control. Please also keep in mind that whenever you select a date from the Calendar control the post back happens which sends all the data to the server and wait for the return. If you like the post back to not happen than you can use JavaScript calendars or the DHTML Calendars.

Page 42

ASP.NET MATERIAL

Lets see what else we can do with the calendar control. Lets make a calendar control that will allow us to select dates depending on the whole week. For this example we will add System.Text namespace since it contains the string builder class. Remember that whenever you do concatenation always use the stringbuilder class since it does not create a new string each time you concatenate. The line: string newstring = oldstring + "world"; will create a new object in the memory and will waste the precious resources which we don't want. For this example to work we have to set certain properties of the calendar control. First of all right click on the calendar and set the NextPrevFormat property to ShortMonth, SelectionMode property to DayWeekMonth, SelectMonthText property to Month, and SelectWeekText property to Week. After doing all these changes your calendar will have the month link and the week link on it. Now you can also select all the days in the week and all the days in a month with a single click. Below is the code to Select all the days in a week/month. This code is also available in the project files.

Page 43

ASP.NET MATERIAL
private void Calendar1_SelectionChanged(object sender, System.EventArgs e) { StringBuilder sbMessage = new StringBuilder(); sbMessage.Append("The Selected date(s) "); for(int i = 0; i sbMessage.Append(Calendar1.SelectedDates[i].ToShortDateString() + " "); Response.Write(sbMessage.ToString()); } So now you see that the Calendar control provided by the .NET Framework is very rich in features. AdRotatorControl: The Ad Rotator control is used to display ads on your website. The ads will also change randomly or at a sequence that you define. Ad Rotator control uses an xml file to store the information about ads. Lets first see how we can make the xml file and what tags does it contain.

Validation Controls:

Back when we had only ASP, developers who had to write webpages for forms knew that the most tedious part is writing code to validate the user input. User input had to be validated so that malicious use of the pages couldn't be achieve. User input had to be validated so that an incorrect piece of information would not be entered. User input had to be validated so that the information stored was standardized. Yeah, some people had libraries of ASP functions to validate common things such as postal codes (zip codes for you Americans), e-mail addresses, phone numbers, etc. The developers of ASP.NET saw the tedium in always having to check user input. They decided that to simplify our life by including validation controls. ASP.NET validation controls also provide two ways of validation: Server-side or Clientside. The nice thing about these Validation controls is that it will preform client-side validation when it detects the browser is able (unless client-side validation has been disabled). Thus reducing roundtrips. And it will perform server-side where necessary.

Page 44

ASP.NET MATERIAL
This client-side/server-side detection and validation is done without extra work by the developer! With ASP.NET, there are six(6) controls included. They are:

The RequiredFieldValidation Control The CompareValidator Control The RangeValidator Control The RegularExpressionValidator Control The CustomValidator Control

Validator Control Basics


All of the validation controls inherit from the base class BaseValidator so they all have a series of properties and methods that are common to all validation controls. They are:

ControlToValidate - This value is which control the validator is applied to. ErrorMessage - This is the error message that will be displayed in the validation summary. IsValid - Boolean value for whether or not the control is valid. Validate - Method to validate the input control and update the IsValid property. Display - This controls how the error message is shown. Here are the possible options: o None (The validation message is never displayed.) o Static (Space for the validation message is allocated in the page layout.) o Dynamic (Space for the validation message is dynamically added to the page if validation fails.)

TheRequiredFieldValidationControl:
The first control we have is the RequiredFieldValidation Control. As it's obvious, it make sure that a user inputs a value. Here is how it's used:
Required field: <asp:textbox id="textbox1" runat="server"/> <asp:RequiredFieldValidator id="valRequired" runat="server" ControlToValidate="textbox1" ErrorMessage="* You must enter a value into textbox1" Display="dynamic">* </asp:RequiredFieldValidator>

Page 45

ASP.NET MATERIAL
In this example, we have a textbox which will not be valid until the user types something in. Inside the validator tag, we have a single *. The text in the innerhtml will be shown in the controltovalidate if the control is not valid. It should be noted that the ErrorMessage attribute is not what is shown. The ErrorMessage tag is shown in the Validation Summary.

TheCompareValidatorControl:
Next we look at the CompareValidator Control. Usage of this CompareValidator is for confirming new passwords, checking if a departure date is before the arrival date, etc. We'll start of with a sample:
Textbox 1: <asp:textbox id="textbox1" runat="server"/><br /> Textbox 2: <asp:textbox id="textbox2" runat="server"/><br /> <asp:CompareValidator id="valCompare" runat="server" ControlToValidate="textbox1" ControlToCompare="textbox2" Operator="Equals" ErrorMessage="* You must enter the same values into textbox 1 and textbox 2" Display="dynamic">* </asp:CompareValidator>

Here we have a sample where the two textboxes must be equal. The tags that are unique to this control is the ControlToCompare attribute which is the control that will be compared. The two controls are compared with the type of comparison specified in the Operator attribute. The Operator attribute can contain Equal, GreterThan, LessThanOrEqual,etc. Another usage of the ComapareValidator is to have a control compare to a value. For example:
Field: <asp:textbox id="textbox1" runat="server"/> <asp:CompareValidator id="valRequired" runat="server" ControlToValidate="textbox1" ValueToCompare="50" Type="Integer" Operator="GreaterThan" ErrorMessage="* You must enter the a number greater than 50" Display="dynamic">* </asp:CompareValidator>

Page 46

ASP.NET MATERIAL
The data type can be one of: Currency, Double, Date, Integer or String. String being the default data type.

The RangeValidator Control:


Range validator control is another validator control which checks to see if a control value is within a valid range. The attributes that are necessary to this control are: MaximumValue, MinimumValue, and Type. Sample:
Enter a date from 1998: <asp:textbox id="textbox1" runat="server"/> <asp:RangeValidator id="valRange" runat="server" ControlToValidate="textbox1" MaximumValue="12/31/1998" MinimumValue="1/1/1998" Type="Date" ErrorMessage="* The date must be between 1/1/1998 and 12/13/1998" Display="static">*</asp:RangeValidator>

The RegularExpressionValidator Control:


The regular expression validator is one of the more powerful features of ASP.NET. Everyone loves regular expressions. Especially when you write those really big nasty ones... and then a few days later, look at it and say to yourself. What does this do? Again, the simple usage is:
E-mail: <asp:textbox id="textbox1" runat="server"/> <asp:RegularExpressionValidator id="valRegEx" runat="server" ControlToValidate="textbox1" ValidationExpression=".*@.*\..*" ErrorMessage="* Your entry is not a valid e-mail address." display="dynamic">* </asp:RegularExpressionValidator>

The CustomValidator Control:


The final control we have included in ASP.NET is one that adds great flexibility to our validation abilities. We have a custom validator where we get to write out own functions and pass the control value to this function.

Page 47

ASP.NET MATERIAL
Field: <asp:textbox id="textbox1" runat="server"> <asp:CustomValidator id="valCustom" runat="server" ControlToValidate="textbox1" ClientValidationFunction="ClientValidate" OnServerValidate="ServerValidate" ErrorMessage="*This box is not valid" dispaly="dynamic">* </asp:CustomValidator>

We notice that there are two new attributes ClientValidationFunction and OnServerValidate. These are the tell the validation control which functions to pass the controltovalidate value to. ClientValidationFunction is usually a javascript funtion included in the html to the user. OnServerValidate is the function that is server-side to check for validation if client does not support client-side validation. Client Validation function:
&ltscript language="Javascript"> <!-/* ... Code goes here ... */ --> </script>

Server Validation function:


Sub ServerValidate (objSource As Object, objArgs As ServerValidateEventsArgs) ' Code goes here End Sub

Validation Summary:
ASP.NET has provided an additional control that complements the validator controls. This is the validation summary control which is used like:
<asp:ValidationSummary id="valSummary" runat="server" HeaderText="Errors:" ShowSummary="true" DisplayMode="List" />

The validation summary control will collect all the error messages of all the non-valid controls and put them in a tidy list. The list can be either shown on the web page (as shown in the example above) or with a popup box (by specifying ShowMessageBox="True")

THEME AND SKINSTYLE SHEETSADO.NET

Page 48

ASP.NET MATERIAL
Introduction To Ado.Net Providers
AnoverviewofADO.NET: ADO.NET (ActiveX Data Objects .NET) is the primary data access API for the .NET Framework. It provides the classes that you use as you develop database applications with Visual Basic .NET as well as other .NET languages. In the two topics that follow, youll learn about how ADO.NET uses these classes to provide access to the data in a database and the two ways you can create ADO.NET objects in your Visual Basic programs. HowADO.NETworks: To work with data using ADO.NET, you use a variety of ADO.NET objects. Figure 2-1 shows the primary objects youll use to develop Windows-based ADO.NET applications in Visual Basic. To start, the data used by an application is stored in a dataset that contains one or more data tables. To load data into a data table, you use a data adapter. The main function of the data adapter is to manage the flow of data between a dataset and a database. To do that, it uses commands that define the SQL statements to be issued. The command for retrieving data, for example, typically defines a Select statement. Then, the command connects to the database using a connection and passes the Select statement to the database. After the Select statement is executed, the result set it produces is sent back to the data adapter, which stores the results in the data table. To update the data in a database, the data adapter uses a command that defines an Insert, Update, or Delete statement for a data table. Then, the command connects to the database and performs the requested operation. Although its not apparent in this figure, the data in a dataset is independent of the database that the data was retrieved from. In fact, the connection to the database is typically closed after the data is retrieved from the database. Then, the connection is opened again when its needed. Because of that, the application must work with the copy of the data thats stored in the dataset. The architecture thats used to implement this type of data processing is referred to as disconnected data architecture. Although this is more complicated than a connected architecture, the advantages offset the complexity. One of the advantages of using disconnected data architecture is improved system performance due to the use of fewer system resources for maintaining connections. Another advantage is that it makes ADO.NET compatible with ASP.NET web

Page 49

ASP.NET MATERIAL
applications, which are inherently disconnected. Youll learn more about developing ASP.NET web applications that use ADO.NET in chapters 12 through 14 of this book. The ADO.NET classes that are responsible for working directly with a database are provided by the .NET data providers. These data providers include the classes you use to create data adapters, commands, and connections. As youll learn later in this chapter, the .NET Framework currently includes two different data providers, but additional providers are available from Microsoft and other third-party vendors such as IBM and Oracle. Basic ADO.NET objects:

How ADO.NET works Description

Figure 1

ADO.NET uses two types of objects to access the data in a database: datasets, which can contain one or more data tables, and .NET data provider objects, which include data adapters, commands, and connections. A dataset stores data from the database so that it can be accessed by the application. The .NET data provider objects retrieve data from and update data in the database. To retrieve data from a database and store it in a data table, a data adapter object issues a Select statement thats stored in a command object. Next, the command object uses a connection object to connect to the database and retrieve the data. Then, the data is passed back to the data adapter, which stores the data in the dataset. To update the data in a database based on the data in a data table, the data adapter object issues an Insert, Update, or Delete statement thats stored in a command object. Then, the command object uses a connection to connect to the database and update the data.

Page 50

ASP.NET MATERIAL

The data provider remains connected to the database only long enough to retrieve or update the specified data. Then, it disconnects from the database and the application works with the data via the dataset object. This is referred to as disconnected data architecture. All of the ADO.NET objects are implemented by classes in the System.Data namespace of the .NET Framework. However, the specific classes used to implement the connection, command, and data adapter objects depend on the .NET data provider you use.

Two ways to create ADO.NET objects:


Figure 2 shows two basic techniques you can use to create the ADO.NET objects you need as you develop database applications. First, you can use the components in the Data tab of the Toolbox to create ADO.NET objects by dragging and dropping them onto a form. Notice that the names of most of the components in the Data tab are prefixed with either OleDb or Sql. As youll learn in the next figure, these prefixes identify the data provider that these components are associated with. Before I go on, you should realize that when you drag one of the data adapter components onto a form starts the Data Adapter Configuration Wizard. This wizard gathers information about the data you want to retrieve and then generates code to create the required ADO.NET objects. Youll learn how to use the Data Adapter Configuration Wizard in the next chapter. The Visual Basic project shown in this figure contains four ADO.NET objects: two data adapters named daVendors and daStates, a connection named conPayables, and a dataset named DsPayables1. Because these objects dont have a visual interface like the controls that you add to a form, they dont appear on the form itself. Instead, they appear in the Component Designer tray below the form. Then, when you select one of these objects, its properties appear in the Properties window and you can work with them from there. The second technique for creating ADO.NET objects is to write the code yourself. The code shown in this figure, for example, creates three objects: a connection named conPayables, a data adapter named daVendors, and a dataset named dsPayables. It also uses the Fill method of the data adapter to retrieve data from the database identified by the connection and load it into the dataset. (Dont worry if you dont understand all of this code. Youll learn more about coding these types of statements throughout this book.) Although creating ADO.NET objects through code is more time-consuming than using the components and wizards, it can result in more compact and efficient code. In

Page 51

ASP.NET MATERIAL
addition, because the components and wizards have limitations, there are times when youll need to write your own code. For now, you should realize that whether you create ADO.NET objects using the components in the Toolbox or using code, you need to be familiar with object-oriented programming techniques such as constructors and overloaded methods. For example, when you use the Fill method of a data adapter to retrieve data from a database and store it in a dataset, youll need to know which of the eight overloaded methods to use. And when you create ADO.NET objects like connections and data adapters through code, youll need to know which of the overloaded constructors to use. If youre not familiar with these basic object-oriented programming techniques, we recommend that you review chapters 6 and 15 of our book, Murachs Beginning Visual Basic .NET. ADO.NET objects created using components in the Toolbox:

Figure 2 Two ways to create ADO.NET objects ADO.NET objects created using code: Dim sConnectionString As String = "data source=DOUG\VSdotNET;"& _ "initial catalog=Payables;integrated security=SSPI;"& _ "persist security info=False;workstation id=DOUG;packet size=4096" Dim conPayables As New SqlConnection(sConnectionString) Dim sVendorSelect = "Select * From Vendors" Dim daVendors As New SqlDataAdapter(sVendorSelect, conPayables)

Page 52

ASP.NET MATERIAL
Dim dsPayables As New DataSet() daVendors.Fill(dsPayables, "Vendors") Description

You can use the ADO.NET components in the Data tab of the Toolbox to add ADO.NET objects to a form. Then, you can set the properties of the objects using the Properties window. If you add a data adapter from the Toolbox, the Data Adapter Configuration Wizard is started. This wizard helps you create the data adapter and the related connection and command objects. See chapter 3 for details. To create ADO.NET objects in code, you use Dim statements that identify the class that each object is created from. This method requires more coding than using the components but is more flexible.

ADO.NETdataproviders: To access a database, you use an ADO.NET data provider. In the topics that follow, youll learn more about the classes that make up a data provider. First, youll learn about the two data providers that come with the .NET Framework. Then, youll learn what each of the core data provider classes does.

The SQL Server and OLE DB data providers:


All .NET data providers must include core classes for creating the four types of objects listed in the first table in figure 2-3. Youve already learned the basic functions of the connection, command, and data adapter objects. In addition to these, you can use a data reader object to access the data in a database in a read-only, forward-only manner. The second table in this figure lists the two data providers that come with the .NET Framework. The SQL Server data provider is designed to provide efficient access to a Microsoft SQL Server database. The OLE DB data provider is a generic data provider that can access any database that supports the industry standard OLE DB interface, such as Oracle or MySQL. Although you can use the OLE DB data provider to access a SQL Server database, you shouldnt do that unless you plan on migrating the data to another database since the SQL Server data provider is optimized for accessing SQL Server data. In addition to the .NET data providers, you should also know that several database vendors have developed .NET data providers that are optimized for use with their databases. For example, .NET data providers are available for the popular MySQL database as well as for Oracle and SQL Anywhere. Before you develop an application

Page 53

ASP.NET MATERIAL
using the OLE DB provider, then, you should check with your database vendor to see if a specialized .NET data provider is available. The third table in this figure lists the names of the classes you use to create objects using the SQL Server and OLE DB providers. Notice that like the components you saw in the Toolbox in figure 2-2, all of the SQL Server classes are prefixed with Sql and all of the OLE DB classes are prefixed with OleDb. That way, its easy to tell which data provider youre using in your applications. When you develop a Visual Basic application that uses ADO.NET, you may want to add an Imports statement for the namespace that contains the data provider classes at the beginning of each source file that uses those classes. These namespaces are listed in the second table in this figure. If you include an Imports statement, you can then use the data provider classes without having to qualify them with the name of the namespace. The code shown in this figure illustrates how this works. Now that youre familiar with the core classes of the two .NET data providers, the next two topics will describe the classes of the SQL Server data provider in more detail. You should realize, though, that the information presented in these topics applies to the classes of the OLE DB data provider as well. In later chapters, youll learn some of the differences between these classes. Figure 3. The .NET data providers .NET data provider core objects

Data providers included with the .NET framework

Class names for the SQL Server and OLE DB data providers

Page 54

ASP.NET MATERIAL
Code that uses qualification to identify the data provider namespace Dim conPayables As New SqlClient.SqlConnection () Code that uses an Imports statement to identify the data provider namespace Imports System.Data.SqlClient . . Dim conPayables As New SqlConnection () Description

In addition to the core classes shown above, classes are provided for other functions such as passing parameters to commands or working with transactions. To use a .NET data provider in a program, you should add an Imports statement for the appropriate namespace at the beginning of the source file. Otherwise, youll have to qualify each class you refer to with the SqlClient or OleDb namespace since these namespaces arent included as references by default. Other .NET data providers are available to provide efficient access to nonMicrosoft databases such as Oracle, MySQL, and SQL Anywhere.

The SqlConnection class:


Before you can access the data in a database , you have to create a connection object that defines the connection to the database. To do that, you use the SqlConnection class presented in figure 4. The most important property of the SqlConnection class is ConnectionString. A connection string is a text string that provides the information necessary to establish a connection to a database. That means it includes information such as the name of the database you want to access and the database server that contains it. It can also contain authentication information such as a user-id and password. Youll learn more about coding connection strings in chapter 6. The two methods of the SqlConnection class shown in this figure let you open and close the connection. In general, you should leave a connection open only while data is being retrieved or updated. Thats why when you use a data adapter, the connection is opened and closed for you. In that case, you dont need to use the Open and Close methods.

Page 55

ASP.NET MATERIAL
TheSqlCommandclass:
To execute a SQL statement against a SQL Server database, you create a SqlCommand object that contains the statement. Figure 2-4 presents the SqlCommand class you use to create this object. Notice that the Connection property of this class associates the command with a SqlConnection object, and the CommandText property contains the SQL statement to be executed. The CommandType property indicates how the command object should interpret the value of the CommandText property. Instead of specifying a SQL statement for the CommandText property, for example, you can specify the name of a stored procedure, which consists of one or more SQL statements that have been compiled and stored with the database (see chapter 8 for details). Or you can specify the name of a table. If you specify a SQL statement, you set the value of the CommandType property to CommandType.Text. If you specify the name of a stored procedure, you set it to CommandType.StoredProcedure. And if you specify the name of a table, you set it to CommandType.TableDirect. Then, a Select * statement will be executed on the table. Earlier in this chapter, you learned that you can use a data adapter to execute command objects. In addition, you can execute a command object directly using one of the three Execute methods shown in this figure. If the command contains a Select statement, for example, you can execute it using either ExecuteReader or ExecuteScalar. If you use ExecuteReader, the results are returned as a DataReader object. If you use ExecuteScalar, only the value in the first column and row of the query results is returned. Youre most likely to use this method with a Select statement that returns a single summary value. If the command contains an Insert, Update, or Delete statement, youll use the ExecuteNonQuery method to execute it. This method returns an integer value that indicates the number of rows that were affected by the command. For example, if the command deletes a single row, the ExecuteNonQuery method returns 1. Figure-4. The SqlConnection and SqlCommand classes Common properties and methods of the SqlConnection class

Page 56

ASP.NET MATERIAL
Common properties and methods of the SqlCommand class

Description

Each command object is associated with a connection object through the commands Connection property. When a command is executed, the information in the ConnectionString property of the connection object is used to connect to the database. When you use a data adapter to work with a database, the connection is opened and closed automatically. If thats not what you want, you can use the Open and Close methods of the connection object to open and close the connection. You can use the three Execute methods of a command object to execute the SQL statement it contains. You can also execute the SQL statement in a command object using methods of the data adapter. See figure 2-5 for more information.

Microsoft's ADO.NET heralded the introduction of a disconnected mode of data access, enabling data exchange even across process boundaries efficiently. This is in sharp contrast to the earlier data access technologies with only connected data access mode of operation. It should be noted that ADO.NET supports both connected and disconnected mode of data access. The introduction of ADO.NET has come as a boon to the development community with excellent features such as, seamless support for XML and support for connection pooling, to name a few. This article introduces the reader to newly added features to ADO.NET 2.0 and discusses how they can improve the performance, scalability, and maintainability of applications.

Page 57

ASP.NET MATERIAL

Why ADO.NET 2.0?


With a view to mitigate the performance drawbacks of the earlier version of ADO.NET and add more flexibility, Microsoft has introduced more new features in ADO.NET 2.0 features that have profound differences from ADO.NET 1.1, its earlier counterpart. The performance of DataSets with high volumes of data has posed performance problems in the earlier version of ADO.NET. With ADO.NET 2.0 however, the indexing engine of the DataTable has been completely re-written to facilitate much faster processing of data. According to MSDN, "The indexing engine for the DataTable has been completely rewritten in ADO.NET 2.0 and scales much better for large datasets. This results in faster basic inserts, updates, and deletes, and therefore faster Fill and Merge operations". There have been numerous enhancements to the DataSet and the DataTable classes too.

ADO.NET 1.1 vs. ADO.Net 2.0


The salient features of ADO.NET 2.0 are, but are not restricted to:

Enhancements to the DataSet and Datatable classes Optimized DataSet Serialization Conversion of a DataReader to a DataSet or a DataTable and vice versa Data Paging Batch Updates Reduction in database roundtrips Asynchronous Data Access Common Provider Model Bulk Copy

The following sections discuss each of these features in detail.

Enhancements to the DataSet and the DataTable classes:


In ADO.NET 2.0, the DataTable supports two methods Load and Save. Note that the DataSet class supports both these methods from the earlier version of ADO.NET. While the Load method can load data from XML into the DataTable instance, the Save method can persist the DataTable instance to a persistence storage media. Further, unlike in ADO.NET 1.1, the DataTable class now supports serialization. It should be noted that in ADO.NET 1.1, only the DataSet class supported serialization. Moreover, the DataTable class in ADO.NET 2.0 contains a method called CreateTableReader that returns a

Page 58

ASP.NET MATERIAL
DataTableReader instance that can be used not only to read forward only data but also in a disconnected mode of operation. Further, the DataTable class in ADO.NET 2.0 is serializable, unlike in ADO.NET 1.1 where one had to store the DataTable instance inside a DataSet instance to make it serializable.

Optimized DataSet Serialization:


The DataSet object in ADO.NET is an in-memory representation of disconnected, cached set of data and provides a consistent relational programming model regardless of the data source. When we require sending a DataSet class instance across process boundaries, the DataSet needs to be serialized. But, what is Serialization? Serialization is the process of converting an in-memory object into a serial stream of bytes. Serialization and DeSerialization is mostly used to transport objects or to persist the state of the objects to a persistent storage media (e.g. to a file or database). Unfortunately, the DataSet class in the earlier version of ADO.NET used to serialize data as XML even if the BinarySerializer was specified. This resulted in slower serialization and an overhead of large sized serialized data. In ADO.NET 2.0 however, DataSet serialization has been improved to a large extent and you can now use the RemotingFormat property of the DataSet class to specify that the data is to be stored directly in binary format. Hence, the DataSet class ADO.NET 2.0, unlike ADO.NET 1.1, supports both XML and Binary Serialization formats. This is shown in the code example below. BinaryFormatter binaryFormatter = new BinaryFormatter (); FileStream fileStream = new FileStream ("c:\\emp.dat", FileMode.CreateNew); DataSet empDataSet = GetEmployeeDataSet (); //This is a custom method that creates, populates and then returns a DataSet instance. empDataSet.RemotingFormat = SerializationFormat.Binary; //Serialize the employee Data Set instance as binary. In order to serialize the //same instance as XML, specify SerializationFormat.XML binaryFormatter.Serialize (fileStream, empDataSet); fileStream.Close();

Page 59

ASP.NET MATERIAL
Conversion of a DataReader to DataSet or DataTable and vice-versa:
ADO.NET 2.0 allows loading a DataReader object into a DataSet or a DataTable and vice versa. Both the DataSet and the DataTable classes in ADO.NET 2.0 contain the Load method that can be used to load a DataReader instance into a DataSet or a DataTable. The following piece of code shows how a DataTable can be loaded in a DataReader instance. String connectionString = ....; //Some connection string SqlConnection sqlConnection = new SqlConnection(connectionString); sqlConnection.Open(); SqlCommand sqlCommand = new SqlCommand("Select * from Employee", sqlConnection); SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection); DataTable dataTable = new DataTable("Employee"); dataTable.Load(sqlDataReader); The GetDataReader method of both the DataSet and the DataTable classes can be used to retrieve a DataReader instance from either a DataSet or a DataTable. If ithe DataSet instance on which the method is called contains multiple DataTable instances, the resultant DataReader would also contain multiple resultsets.

Data Paging:
Data Paging is a very powerful feature in ADO.NET. It can be recollected that in the earlier version of ADO.NET we needed to make use of stored procedures for incorporating Data Paging functionality in our applications. Now, with ADO.NET 2.0, it is much simplified with the introduction of the ExecutePageReader method in the SqlDataReader class. The following code snippet illustrates how this feature can be achieved. String connectionString = ....; //some connection string SqlConnection sqlConnection = new SqlConnection (connectionString);

Page 60

ASP.NET MATERIAL
sqlConnection.Open (); SqlCommand sqlCommand = new SqlCommand ("Select * from Employee", sqlConnection); SqlDataReader sqlDataReader = sqlCommand.ExecutePageReader (CommandBehavior.CloseConnection, 1, 25);

Batch Updates Reducing Database Roundtrips:


Database round trips degrade the performance of applications to a large extent due to increased network traffic. The Batch update of ADO.NET 2.0 promises to improve the performance of applications to a large extent by reducing the number of round trips to the database. In the earlier version of ADO.NET, if we made any changes to the DataSet and then saved the DataSet using the Update method of the DataAdapter class, it made round trips to the database for each modified row in the DataSet. This was a major performance hindrance. But, how does it know which row or rows have been changed? When we make changes to a DataRow, its RowState changes to reflect the change. Now, for every row that has been changed (depending on whether the RowState property has been changed or not), the DataAdapter communicates with the database in such a type of operation. This is a terrible performance drawback with large volumes of data. In ADO.NET 2.0 however, there is a property known as UpdateBatchSize that can be used to specify a group or batch of rows for a particular hit to the database. It provides the number of rows to be updated in a batch. In other words, the UpdateBatchSize property of the DataAdapter class actually determines the number of changed rows changed rows that send to the database server in a single operation.

Asynchronous Data Access: In the earlier version of ADO.NET, the ExecuteReader, ExecuteScalar and the
ExecuteNonQuery methods used to block the current executing thread. However, ADO.NET 2.0 supports asynchronous data access mode.In ADO.NET 2.0, these methods come with Begin and End methods that support asynchronous execution.

The Common Provider Model:


In the earlier version of ADO.NET, if we wanted to implement a provider independent Data Access Layer, we had to implement the Factory Design Pattern where a class would have been responsible for returning the specific type of Command,Data Reader,

Page 61

ASP.NET MATERIAL
DataAdapter or Connection. In ADO.NET 2.0 we can create provider-independent data access code even without referencing the provider-specific classes using the System.Data.Common namespace that exposes a number of factory classes. The DbProviderFactory class contains two methods called the GetFactoryClasses method and the Getfactory method. While the former is responsible for retrieving all the providers supported, the later can be used to retrieve the specific provider. Refer to the code snippet below that demonstrates how we can make use of this class to create a sql connection seamlessly. DbProviderFactory dbProviderFactory = DbProviderFactories.GetFactory("System.Data.SqlClient"); DbConnection dbConnection = dbProviderFactory.CreateConnection();

Bulk Copy Feature:


In the earlier version of ADO.NET, copying a large volume of data from a source data store to a destination table in SQL database had performance drawbacks due to the repeated database accesses that were required. The SqlBulkCopy feature in ADO.NET 2.0 enables us to copy a large volume of data between a source data store and a destination data table. This class can be used to specify the source and the target data sources for this copy operation. The following code snippet illustrates how this feature can be implemented. SqlConnection connectionObjSource = new SqlConnection(Conn_str); connectionObjSource.Open(); SqlConnection connectionObjTarget = new SqlConnection(Conn_str1); connectionObjTarget.Open(); SqlCommand sqlCommand = new SqlCommand("Select * from Employee", connectionObjSource); SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection); DataTable dt = new DataTable("Employee"); SqlBulkCopy sqlBulkcopy = new SqlBulkCopy(connectionObjTarget); bulkcopy.DestinationTableName = "Employees";

Page 62

ASP.NET MATERIAL
bulkcopy.WriteToServer(sqlDataReader).

Data Reader:
DataReader object is a simply used to read data from the result sets and because of this feature we call this object as forward only or read only cursor. It requires a live connection with the data source. Threw looping you can efficiently access all or a part of data from the result set. Note you cannot directly initialize a DataReader object. Execute reader method of the command object is used to obtain a valid DataReader object. After using DataReader you need to close the connection otherwise it is stayed alive and it is explicitly closed. To close a connection we find two ways you can adopt the either way. First method to close a connection is by using Command Behavior.CloseConnection enumeration by calling the Execute method of the command object. This approach will only work when you are reading data from file using loop. When loop ends connection will be closed automatically. If you are not reading data from file then simply use close method of the connection object. To know more about the DataReader object consider an application that fetch the data from the result set and display it in a GridView control. To start with an application, add following code in web form source: <div> Select Query Parameter: <br /> <asp:RadioButton ID="rbQParam1" runat="server" GroupName="QParam" Text="By ID" Width="69px" /> <asp:RadioButton ID="rbQParam2" runat="server" GroupName="QParam" Text="By Name" Width="91px" /><br /> <br />Enter Query Parameter :<br /> <asp:TextBox ID="txtQuery" runat="server" /> <asp:Button ID="cmdGo" runat="server" Text="Go" /> <br /><br /> Your Result :<br /><asp:GridView ID="GridView1" runat="server" /> </div> Now in code behind first import two namespace System.Data and System.Data.SqlClient. These namespaces help you in communicating with Sql Database objects. After this create three global objects:

Page 63

ASP.NET MATERIAL
Dim DBConn As New SqlConnection("Server=localhost;Password=YourPWD;Persist Security Info=False;User ID=YourID;Initial Catalog=Northwind;Data Source=YourDataSource") Dim DBCmd As New SqlCommand Dim DR As SqlDataReader First object defines connection, second object is used for defining command and third one is used for data reader. Now on Page_Load event open Database connection: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load DBConn.Open() End Sub On Page_Unload event add close this connection and set its object to nothing. Here you also dispose the command object and set this object to nothing: Protected Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Unload DBConn.Close() DBConn = Nothing DBCmd.Dispose() DBCmd = Nothing End Sub Finally on the cmdGo_Click event add the following code: Protected Sub cmdGo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdGo.Click If rbQParam1.Checked = True Then DBCmd = New SqlCommand("SELECT * FROM Customers WHERE CustomerID = @CustomerID", DBConn) DBCmd.Parameters.Add("@CustomerID", SqlDbType.NChar, 5).Value = txtQuery.Text DR = DBCmd.ExecuteReader() Me.GridView1.DataSource = DR Me.GridView1.DataBind() DR.Close()

Page 64

ASP.NET MATERIAL
DR = Nothing Else DBCmd = New SqlCommand("SELECT * FROM Customers WHERE ContactName = @ContactName", DBConn) DBCmd.Parameters.Add("@ContactName", SqlDbType.NVarChar, 30).Value = txtQuery.Text DR = DBCmd.ExecuteReader() Me.GridView1.DataSource = DR Me.GridView1.DataBind() DR.Close() DR = Nothing End If End Sub.

Drawbacks of Record set :

ADO uses Recordsets and cursors to access and modify data. Because of its inherent design, Recordset can impact performance on the server side by tying up valuable resources. In addition, COM marshalling - an expensive data conversion process - is neededtotransmitaRecordset. ADO.NET addresses three important needs that ADO doesn't address: 1. Providing a comprehensive disconnected data-access model, which is crucial to the Web environment 2. Providing tight integration with XML, and 3. Providing seamless integration with the .NET Framework. From an ADO.NET implementation perspective, the Recordset object in ADO is eliminated in the .NET architecture. In its place, ADO.NET has several dedicated objects led by the DataSet object and including the DataAdapter, and DataReader objects to perform specific tasks. In addition, ADO.NET DataSets operate in disconnected state whereas the ADO RecordSet objects operated in a fully connected state. A recordset looks like a single table. If a recordset is to contain data from multiple database tables, it must use a JOIN query, which assembles the data from the various database tables into a single result table. In contrast, a dataset is a collection of one or more tables. The tables within a dataset are called data tables; specifically, they are DataTable objects. If a dataset contains data from multiple database tables, it will

Page 65

ASP.NET MATERIAL
typically contain multiple DataTable objects. That is, each DataTable object typically corresponds to a single database table or view. In this way, a dataset can mimic the structureoftheunderlyingdatabase. In ADO you scan sequentially through the rows of the recordset using the ADO MoveNext method. In ADO.NET, rows are represented as collections, so you can loop through a table as you would through any collection, or access particular rows via ordinal or cursor is a database element that controls record navigation, the ability to update data, and the visibility of changes made to the database by other users. ADO.NET does not have an inherent cursor object, but instead includes data classes that provide the functionality of a traditional cursor. There is one significant difference between disconnected processing in ADO and ADO.NET. In ADO you communicate with the database by making calls to an OLE DB provider. In ADO.NET you communicate with the database through a data adapter (an OleDbDataAdapter, SqlDataAdapter, OdbcDataAdapter, or OracleDataAdapter object), which makes calls to an OLE DB provider or the APIs provided by the underlying data source.

Dataset:

Datasets store a copy of data from the database tables. However, Datasets can not directly retrieve data from Databases. DataAdapters are used to link Databases with DataSets. If we see diagrammatically, DataSets < ----- DataAdapters < ----- DataProviders < ----- Databases DataSets and DataAdapters are used to display and manipulate data from databases.

Reading Data into a Dataset:


To read data into Dataset, you need to:

Create a database connection and then a dataset object. Create a DataAdapter object and refer it to the DB connection already created. Note that every DataAdapter has to refer to a connection object. For example, SqlDataAdapter refers to SqlDataConnection. The Fill method of DataAdapter has to be called to populate the Dataset object.

We elaborate the above mentioned steps by giving examples of how each step can be performed: 1) As we said, our first task is to create a connection to database. We would explore later that there is no need of opening and closing database connection explicitly while

Page 66

ASP.NET MATERIAL
you deal with DataAdapter objects. All you have to do is, create a connection to database using the code like this: SqlConnection con = new SqlConnection ("data source=localhost; uid= sa; pwd= abc; database=Northwind"); We would use Northwind database by using OleDbConnection. The Code would Look like: OleDbConnection con= new OleDbConnection ("Provider =Microsoft.JET.OLEDB.4.0;" + "Data Source=C:\\Program Files\\Microsoft Office\\Office\\Samples\\Northwind.mdb"); 2) Now, create a Dataset object which would be used for storing and manipulating data. You would be writing something like DataSet myDataSet = new DataSet ("Northwind"); Since the name of source database is Northwind, we have passed the same name in the constructor. 3) The DataSet has been created but as we said before, this DataSet object can not directly interact with Database. We need to create a DataAdapter object which would refer to the connection already created. The following line would declare a DataAdapter object: OleDbAdapter myDataAdapter = new OleDbAdapter (CommandObject, con); The above line demonstrates one of many constructors of OleDbAdapter class. This constructor takes a command object and a database connection object. The purpose of command object is to retrieve suitable data needed for populating DataSet. As we know SQL commands directly interacting with database tables, a similar command can be assigned to CommandObject. OleDbCommand CommandObject = new OleDbCommand ("Select * from employee"); Whatever data you need for your Dataset should be retrieved by using suitable command here. The second argument of OleDbAdapter constructor is connection object con.

Page 67

ASP.NET MATERIAL
Data Grid: Introduction:
This article will be very useful to all users who are working with ASP.NET 2.0 GridView control. Here, I will explain how to work with the GridView control in ASP.NET 2.0, which is very easier to use than the DataGrid control in ASP.NET 1.1. I will also explain the differences between the GridView and the DataGrid controls. We will also look into how to work with a template column having a DataGrid inside it.

Background:
The basic idea behind this article is to see how much the ASP.NET 2.0's GridView control is easier to work than the DataGrid control in ASP.NET 1.1. I have previously worked with the DataGrid control, and I know how difficult it is to work with it in the same project in which I am using the GridView control. Working with the ASP.NET 2.0 GridView control is very easy as it is very user friendly. Though I had faced a lot of difficulties in using it, I can still say it is far better than the DataGrid control. The GridView control gives you Edit, Update, Delete, Sorting, Selection, and Paging functionality built-in.

Using the code:


Here in this project, I have used an ObjectDataSource control for binding the GridView to the data source. This is one of the best features available in VS.NET 2005. It is very easy to work with it. The main difference between a DataGrid and a GridView control is that the DataGrid control has centralized event handling which means any event raised by a control inside the DataGrids template column will be handled by the ItemCommand event of the DataGrid. But this functionality is some what different in the GridView control. It directly calls the handler of the control. I mean to say that in the GridView control, if you add a template column having a GridView inside it and then if you select the Column Sorting command, it will not call any event of the master grid, but will directly call the sorting handler of the child grid. It is up to the user to take advantage of this feature. So let me explain the code now. Here, I have a master table which is bind to the master grid using MasterDataSouce and a child table which is bound to a GridView inside a template column of the master grid. To bind the child grid to the ChildDataSource, we have to use the RowDataBound event which is called every time when a row from the

Page 68

ASP.NET MATERIAL
database is bound to the GridViews row. Here, the basic idea behind caching is that when a cell value is required, you should get it and show it. So what happens behind the screen is:

RowDataBound event of the master grid:


Collapse
Protected Sub grdMaster_RowDataBound(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _ Handles grdMaster.RowDataBound Dim objListItem As DataControlRowState objListItem = e.Row.RowState Dim intMAsterID1 As Integer If e.Row.RowType = DataControlRowType.DataRow Then Dim grd As GridView If objListItem = 5 Then grd = CType(e.Row.FindControl("grdChildGridEdit"), GridView) MasterTableID = Convert.ToInt32(CType(e.Row.DataItem, _ DataRowView).Row.ItemArray(0).ToString()) intMAsterID1 = MasterTableID ElseIf objListItem = DataControlRowState.Normal Or _ objListItem = DataControlRowState.Alternate Then grd = CType(e.Row.FindControl("grdChildGridNormal"), GridView) intMAsterID1 = Convert.ToInt32(CType(e.Row.DataItem, _ DataRowView).Row.ItemArray(0).ToString()) Dim lnkButtton As LinkButton lnkButtton = CType(e.Row.FindControl("Edit"), LinkButton) If lnkButtton IsNot Nothing Then lnkButtton.CommandName = "Edit Master" lnkButtton.CommandArgument = intMAsterID1.ToString End If ElseIf objListItem = DataControlRowState.Edit Then grd = CType(e.Row.FindControl("grdChildGridEdit"), GridView) MasterTableID = Convert.ToInt32(CType(e.Row.DataItem, _ DataRowView).Row.ItemArray(0).ToString()) intMAsterID1 = MasterTableID End If If grd IsNot Nothing Then grd.DataSourceID = "" grd.DataSource = ChildDataSource ChildDataSource.SelectParameters(_ "MasterTableID").DefaultValue = intMAsterID1 ChildDataSource.Select() grd.DataBind() End If End If End Sub

Page 69

ASP.NET MATERIAL
Here, what I am doing is when the master table's rows are bound with the GridView's row, I find the ChildGrid control and then bind that control with the ChildDataSource for that MasterID. The above code will be used when the user hits on the Master Grid Edit button. So, in the template column, the child grid with the edit and the delete options will get visible. Now, the biggest problem with this child grid is that each and every event handler have to be written manually because the grid will lose its binding when any command gets fired. And another thing is that unlike the DataGrid, the child grids handler will get called when any command of the child grid gets fired like Edit, Delete, Sorting, or Paging. In the DataGrid, the inner control's event will be first handled by the grid's ItemCommand event irrespective of whether that control is a DataGrid, Button, or ListBox. But here it will not call the RowCommand event of the master grid, but will directly call the RowCommand event of the child grid. So, the event flow is like this: 1. When the user presses the Edit option in the master grid, it will call the RowCommand event of the master grid with the command name "Edit". 2. Now, it will call the RowDataBound of the master grid here. You will find whether the RowState of the particular row is "Edit", and then you will find the child grid with the Edit and Delete commands in the EditTemplate of the template column. And then you will bind the grid to ChildDataSource. 3. Now, the master grid will look like below:

Page 70

ASP.NET MATERIAL
4. When you press the Edit option of the child grid, it will invoke the RowCommand of the child grid just like a DataGrid calls the ItemCommand of the master grid. And it will not call the RowDataBound of the master grid so your child edit grid for that particular row will not bind to the datasource. So your grid will disappear. Now, in the RowCommand of the child grid, you have to rebind the grid with the data source. Collapse
grdchildgrid = CType(sender, GridView) If e.CommandArgument IsNot Nothing Then If IsNumeric(e.CommandArgument) Then intRowId = Convert.ToInt32(e.CommandArgument) End If End If If e.CommandName.Equals("Edit") Then grdchildgrid.DataSourceID = "" grdchildgrid.DataSource = ChildDataSource ChildDataSource.SelectParameters(_ "MasterTableID").DefaultValue = MasterTableID ChildDataSource.Select() End If If e.CommandName.Equals("Update") Then UpdateChildRecord() grdchildgrid.DataSourceID = "" grdchildgrid.DataSource = ChildDataSource ChildDataSource.SelectParameters(_ "MasterTableID").DefaultValue = MasterTableID ChildDataSource.Select() End If If e.CommandName.Equals("Delete") Then DeleteChildRecord() grdchildgrid.DataSourceID = "" grdchildgrid.DataSource = ChildDataSource ChildDataSource.SelectParameters(_ "MasterTableID").DefaultValue = MasterTableID ChildDataSource.Select() End If If e.CommandName.Equals("Cancel") Then grdchildgrid.DataSourceID = "" grdchildgrid.DataSource = ChildDataSource ChildDataSource.SelectParameters(_ "MasterTableID").DefaultValue = MasterTableID ChildDataSource.Select() End If If e.CommandName.Equals("Page") Then grdchildgrid.EditIndex = -1 grdchildgrid.DataSourceID = "" grdchildgrid.DataSource = ChildDataSource ChildDataSource.SelectParameters(_

Page 71

ASP.NET MATERIAL
"MasterTableID").DefaultValue = MasterTableID ChildDataSource.Select() End If If e.CommandName.Equals("Sort") Then grdchildgrid.EditIndex = -1 Dim dt As DataView grdchildgrid.DataSourceID = "" ChildDataSource.SelectParameters(_ "MasterTableID").DefaultValue = MasterTableID dt = CType(ChildDataSource.Select(), DataView) If ViewState.Item("SortDirection") IsNot Nothing Then If CType(ViewState.Item("SortDirection"), _ SortDirection) = SortDirection.Ascending Then dt.Sort = e.CommandArgument & " ASC" ViewState.Item("SortDirection") = _ SortDirection.Descending Else dt.Sort = e.CommandArgument & " DESC" ViewState.Item("SortDirection") = _ SortDirection.Ascending End If End If grdchildgrid.DataSource = dt grdchildgrid.DataBind() End If

Here, you will find that you have to handle every command manually, for the child grid, because you are continuously changing the binding of the child grid. And another thing I have found is that if you do not write the handlers for the Edit, Delete, Update, Sort, and Page commands, it will give an error because when you press the Edit command of the child grid, it will search for the RowEditing handler of the child grid even if you are doing all the activity in the RowCommand event.

Page 72

ASP.NET MATERIAL
The grid will look like this:

5. Here, one thing that is important is that in the RowCommand event of the child grid, you will get the old values in the grid, from the viewstate of the grid. But the child grid will not be bound to any data source if you don't bind it to in the RowCommand event. 6. When you press UpdateCommand, it will call the RowCommand with the CommandArgument as "Update". And after that, it will call the RowUpdating event of the child grid. But there will be no values in either e.NewValues or e.OldValues. So you will have to do the update in the RowCommand event.

Data Source Controls Overview:

ASP.NET includes data source controls that allow you to work with different types of data sources such as a database, an XML file, or a middle-tier business object. Data source controls connect to and retrieve data from a data source and make it available for other controls to bind to, without requiring code. They can also support modifying data. This topic provides information about the different types of data source controls in ASP.NET. The data source control model is extensible, so you can also create your own data source controls that interact with different data sources or that provide additional functionality for an existing data source.

Page 73

ASP.NET MATERIAL
Data Source Control Comparison: The .NET Framework includes data source controls to support different data-binding scenarios. The following table describes the built-in data source controls. More detail about each type of data source control is provided later in this topic. Data control source Description

Enables you to use Language-Integrated Query (LINQ) in an ASP.NET Web page through declarative markup in order to retrieve LinqDataSource and modify data from a data object. Supports automatic generation of select, update, inserts, and delete commands. The control also supports sorting, filtering, and paging. Enables you to bind to data that is based on the Entity Data Model (EDM). Supports automatic generation of update, insert, delete, and EntityDataSource select commands. The control also supports sorting, filtering and paging. Enables you to work with a business object or other class and create Web applications that rely on middle-tier objects to manage data. ObjectDataSource Supports advanced sorting and paging scenarios unavailable with the other data source controls. Enables you to work with Microsoft SQL Server, OLE DB, ODBC, or Oracle databases. When used with SQL Server, supports advanced SqlDataSource caching capabilities. The control also supports sorting, filtering, and paging when data is returned as a DataSet object. Enables you to work with a Microsoft Access database. Supports AccessDataSource sorting, filtering, and paging when data is returned as a DataSet object. Enables you to work with an XML file, especially for hierarchical ASP.NET server controls such as the TreeView or Menu control. Supports filtering capabilities using XPath expressions and enables XmlDataSource you to apply an XSLT transformation to the data. The XmlDataSource allows you to update data by saving the entire XML document with changes. SiteMapDataSource Used with ASP.NET site navigation.

LinqDataSource Control:

Page 74

ASP.NET MATERIAL
The LinqDataSource control enables you to use LINQ in an ASP.NET page to retrieve data from a database table or an in-memory data collection. You can use declarative markup to write all the conditions that are required in order retrieve, filter, order, and group the data. When you retrieve data from a SQL database table, you can also configure a LinqDataSource control to handle update, insert, and delete operations. You can do this writing SQL commands to perform these tasks. By using the LinqDataSource control, you can reduce the amount of code that is required for data operations, compared to performing the same operations in other data source controls. SqlDataSource Control: The SqlDataSource control retrieves and modifies data using SQL commands. The SqlDataSource control works with Microsoft SQL Server, OLE DB, ODBC, and Oracle databases. The SqlDataSource control can return results as a DataReader or a DataSet object. It supports sorting, filtering, and caching when the results are returned as a DataSet. When you are working with Microsoft SQL Server, the control has the added benefit that cache results can be invalidated when the database changes, using a SqlCacheDependency object. EntityDataSource Control: The EntityDataSource control supports data binding scenarios based on the Entity Data Model (EDM). This data specification represents data as sets of entities and relationships. The Entity Framework uses the EDM in object-relational mapping and in other scenarios such as WCF Data Services. The EntityDataSource control supports Entity-SQL (eSQL) as the query language, and it supports the query specification that is exposed by the ObjectQuery<T> class. ObjectDataSource Control: The ObjectDataSource control works with a business object or other class in Web applications that rely on middle-tier business objects to manage data. The control is designed to interact with an object that implements one or more methods to retrieve or modify data. When data-bound controls interact with the ObjectDataSource control to retrieve or modify data, the ObjectDataSource control passes values from the bound control to the source object as parameters in method calls. The source object's data-retrieval methods must return a DataSet, DataTable, or DataView object, or an object that implements the IEnumerable interface. If the data is returned as a Dataset, Data Table, or Data View object, the ObjectDataSource control can cache and filter the data. You can also implement advanced paging scenarios if the source

Page 75

ASP.NET MATERIAL
object accepts page size and record index information from the ObjectDataSource control. XmlDataSource Control: The XmlDataSource control reads and writes XML data so that you can work with it using controls such as the Tree View and Menu controls. The XmlDataSource control can read either an XML file or string of XML. If the control is working with an XML file, it can write modified XML back to the source file. If a schema is available that describes the data, the XmlDataSource control can use the schema to expose data using typed members. You can apply an XSLT transformation to the XML data, which allows you to restructure the raw data from the XML file into a format better suited to the control you want to bind to the XML data. You can also apply XPath expressions to the XML data, which allows you to filter the XML data to return only certain nodes in the XML tree, to look for nodes that have specific values in them, and so on. Using an XPath expression disables the ability to insert new data. AccessDataSource Control: The AccessDataSource control is a specialized version of the SqlDataSource control, designed to work specifically with Microsoft Access .mdb files. As with the SqlDataSource control, you use SQL statements to define how the control fetches and retrieves data. SiteMapDataSource Control: The SiteMapDataSource control works with ASP.NET site maps and provides site navigation data. It is most commonly used with the Menu control. The SiteMapDataSource control is also useful when you want to customize site navigation using site map data with Web server controls that are not specifically designed for navigation, such as the Tree View or Dropdown List controls.

Access Data Source:

Page 76

ASP.NET MATERIAL
Web applications commonly access data sources for storage and retrieval of dynamic data. You can write code to access data using classes from the System.Data namespace (commonly referred to as ADO.NET) and from the System.Xml namespace. This approach was common in previous versions of ASP.NET. However, ASP.NET also enables you to perform data binding declaratively. This requires no code at all for the most common data scenarios, including:

Selecting and displaying data. Sorting, paging, and caching data. Updating, inserting, and deleting data. Filtering data using run-time parameters. Creating master-detail scenarios using parameters.

ASP.NET includes several types of server controls that participate in the declarative data binding model, including data source controls, data-bound controls, and the query extender control. These controls manage the underlying tasks that are required by the stateless Web model in order to display and update data in ASP.NET Web pages. The controls let you add data-binding behavior to a page without having to understand details of the page request life cycle.

Data Source Controls: Data source controls are ASP.NET controls that manage the tasks of connecting to a data source and reading and writing data. Data source controls do not render any user interface, but instead act as an intermediary between a particular data store (such as a database, business object, or XML file) and other controls on the ASP.NET Web page. Data source controls enable rich capabilities for retrieving and modifying data, including querying, sorting, paging, filtering, updating, deleting, and inserting. Data source controls derive from ContextDataSource, which is the base class that provides the context type that data source controls use. This base class enables you to create data source controls that support data models such as Entity Framework and WCF Data Services.

ASP.NET includes the following data source controls:

Page 77

ASP.NET MATERIAL
Data source control AccessDataSource Enables you to use Language-Integrated Query (LINQ) in an ASP.NET Web page through declarative markup in order to retrieve LinqDataSource and modify data from a data object. Supports automatic generation of select, update, insert, and delete commands. The control also supports sorting, filtering, and paging. Enables you to work with a business object or other class and create ObjectDataSource Web applications that rely on middle-tier objects to manage data. SiteMapDataSource Used with ASP.NET site navigation. Enables you to work with ADO.NET managed data providers, which SqlDataSource provide access to Microsoft SQL Server, OLE DB, ODBC, or Oracle databases. Enables you to bind to data that is based on the Entity Data Model (EDM). Supports automatic generation of update, insert, delete, and EntityDataSource select commands. The control also supports sorting, filtering and paging.. Enables you to work with an XML file, which is especially useful for XmlDataSource hierarchical ASP.NET server controls such as the TreeView or Menu control.. Data-source controls can also be extended to support additional data access storage providers. Description Enables you to work with a Microsoft Access database.

Grid View:

The ASP.NET GridView control is the successor to the v1.x DataGrid, adding the ability to take advantage of specific capabilities of ASP.NET data source controls. Whereas the v1.x DataGrid required a page developer to write custom code to handle simple operations such as paging, sorting, editing or deleting data, the GridView control can automatically handle these operations provided its bound data source control supports these capabilities. The GridView also offers some functionality improvements over the DataGrid, such as the ability to define multiple primary key fields, and some UI customization improvements, such as new field types and templating options. It also exposes a new model for page developers to handle or cancel events. GridView-SqlDataSource:

Page 78

ASP.NET MATERIAL
The GridView control reflected against the fields of the data records returned by SqlDataSource in order to dynamically generate the columns of the grid. You can also specify explicit column fields to display by adding DataControlField objects to the GridView's Columns collection. This allows you to specify exactly which columns to display and their relative order. The following example demonstrates a collection of BoundField and CheckBoxField objects in the GridView Columns collection. Other field types that can be assigned to this collection are ImageField, HyperLinkField, CommandField, ButtonField, and TemplateField. GridView Sorting: One of the key advantages of the GridView control over other data-bound controls is its ability to automatically take advantage of data source capabilities. Instead of relying on page code to manually sort or page data, the GridView control can perform these operations automatically as long as the data source is configured to support these operations. The following example shows a GridView control with sorting enabled. GridView Paging: You can also enable paging UI in the GridView by setting the AllowPaging property to true. The GridView can automatically page over any return value from a data source that supports the ICollection interface. The DataView returned by SqlDataSource when in DataSet mode supports this interface, so GridView can page over the result. When in DataReader mode, the GridView cannot page over the data returned by SqlDataSource. The following example demonstrates the GridView paging UI against a SqlDataSource in DataSet mode. GridView Paging and Sorting Callbacks: GridView also supports a special mode for paging and sorting that takes advantage of client-side callbacks to the server to obtain data for the new page or newly sorted data. To enable this feature, set the EnableSortingAndPagingCallbacks property to true. Notice that when a page or sort operation is performed, the page does not need to postback in order to retrieve new values (although a client script callback to the server is made). This feature is not supported when the GridView contains templated fields. Showing a Select button in a CommandField is also not supported when this feature is enabled.

GridView Updating: Just like sorting and paging, the GridView control can also automatically render UI for modifying data through Update and Delete operations, provided the associated data

Page 79

ASP.NET MATERIAL
source is configured to support these capabilities. The SqlDataSource control supports Update operations when its UpdateCommand property is set and Delete operations when its DeleteCommand property is set to a valid update or delete command or stored procedure. The UpdateCommand or DeleteCommand should contain parameter placeholders for each value that will be passed by the GridView control. To enable the UI in the GridView for Updates or Deletes, you can either set the AutoGenerateEditButton and AutoGenerateDeleteButton properties to true, or you can add a CommandField to the GridView control and enable its ShowEditButton and ShowDeleteButton properties. The GridView supports editing or deleting one row at a time. For editing, the user places the row in edit mode by clicking the Edit button, and then confirms the Update by clicking the Update button while the row is in edit mode. The user can also click the Cancel button to abort the edit operation and return to readonly mode. The following example shows the a GridView and SqlDataSource configured for updating data rows. An important property that plays a special role in Update and Delete operations is the DataKeyNames property. This property is typically set to the names of fields from the data source that is part of a primary key used to match a given row in the data source. Multiple keys are comma-separated when specifying this property declaratively, although it is common to only have one primary key field. The values of fields specified by the DataKeyNames property are round-tripped in viewstate for the sake of retaining original values to pass to an Update or Delete operation, even if that field is not rendered as one of the columns in the GridView control. When the GridView invokes the data source Update or Delete operation, it passes the values of these fields to the data source in a special Keys dictionary, separate from the Values dictionary that contains new values entered by the user while the row is in edit mode (for update operations). The contents of the Values dictionary are obtained from the input controls rendered for the row in edit mode. To exclude a value from this dictionary, set the ReadOnly property to true on the corresponding BoundField in the Column collection. If you are using the GridView designer in Visual Studio, the ReadOnly property is set to true for primary key fields by default.

Details View:
It is a data-bound user interface control that renders a single record at a time from its associated data source, optionally providing paging buttons to navigate between records. It is similar to the Form View of an Access database, and is typically used for updating and/or inserting new records. It is often used in a master-details scenario where the selected record of the master control (GridView, for example) determines the DetailsView display record.

Page 80

ASP.NET MATERIAL
DetailsView Editing: DetailsView supports editing just like GridView, and you can enable the UI the same way using the AutoGenerateEditButton or CommandField.ShowEditButton properties. Of course, the data source associated to the DetailsView must also be configured to support the Update operation (in this case, by specifying an UpdateCommand on SqlDataSource). The following example demonstrates a DetailsView configured to support editing records in a master-details scenario. Master-Details (Separate Pages): Normally data-bound controls automatically re-bind to their data source whenever the data source changes (for example after an update). However, in the preceding example, the DetailsView is bound to a different data source than the GridView, so when the Update operation is invoked, only the DetailsView receives a change event from its data source. To force the GridView to also re-bind when the DetailsView performs an update, you can call DataBind () explicitly on GridView in the DetailsView ItemUpdated event. This example also handles events to disable editing when a GridView sorting or paging operation occurs or when a new filter value is selected in the DropDownList control. This next example demonstrates a master-details scenario using GridView and DetailsView in separate pages. Unlike the previous examples that showed the GridView and DetailsView bound to the same type of record (an author), this example shows different types of records for the master and details controls (authors and books), associated by a foreign key relationship in the underlying database. Because an author record may have more than one associated book, the DetailsView has been configured to support paging over the book records in the details page. The DetailsView also supports paging records using client-side callbacks through its EnablePagingCallbacks property (not shown in this example). Master-Details Insert (Separate Pages): Like the GridView control, the DetailsView control supports Updating and Deleting data through its data source. However, DetailsView also supports Inserting data, whereas GridView does not. You can easily pair a DetailsView with GridView to enable inserting records to be displayed in the GridView control. You can place the DetailsView on a separate page to perform an Insert or Update operation. The following example shows a DetailsView configured on a separate page for Insert and Updates. Notice that the DefaultMode property is set in this example to Insert or Edit so that the DetailsView renders in this mode initially instead of read-only

Page 81

ASP.NET MATERIAL
mode. After an Insert or Update operation is performed, DetailsView always reverts to the DefaultMode (which is ReadOnly, by default).

ASP.NET TRACING

Page 82

ASP.NET MATERIAL

Page Level:
One way to get lots of debugging information is to use Tracing. We can enable Tracing at the Page Level and Application Level. We can view the view state information and the events chain when a page is executing, among other things. Let's see, how to enable Tracing at the Page level. 1) Start a new ASP.NET Web site with visual studio 2010 or an earlier version 2) Go to the default.aspx page in the "Source View" and in the Page directive add this Trace="true" The whole directive should like this <%@ Page Title="Home Page" Trace="true" Language="C#" MasterPageFil e="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> 3) Run your application and see the tracing information in the Default.aspx page Have a look at the picture below to see the various settings for enabling tracing at the page level. You can also set TraceMode to SortedByTime or SortByCategory.

Page 83

ASP.NET MATERIAL

Page 84

ASP.NET MATERIAL
4) You can also use the Trace object in your code. Have a look at the code below protected void Page_Load(object sender, EventArgs e) { Trace.Warn("this is my message"); Trace.Write("this is another message"); } Run your application and see the messages printed in the screen. The Trace. Warn method outputs the message on the screen in red. If you want to enable tracing at the application level, type the following in the web.config page <trace enabled="true"/> Then run again your application. After the root of the application , in my case (http://localhost:13983/trace), type trace.axd The whole URL should look like this. http://localhost:13983/trace/trace.axd In that page you can view trace details for all pages of the application.

Application Level :

ASP.NET automatically binds application events to event-handler methods in the Global.asax file using a naming convention of Application_event, such as Application_BeginRequest and Application_Error. This code example handles the application-level Error event and writes error information to the system event log. The Error event is raised whenever an application error or unhandled page error occurs.

To create an Asp.NET application-level event handler:


1. If youre Web site does not already have a Global.asax file, create one in the root of the site. 2. Create an event-handler method whose name follows the pattern Application_event. For example, to handle an application Error event, create a

Page 85

ASP.NET MATERIAL
handler named Application_Error that takes an Object parameter and an EventArgs parameter.

Example:
The following code example shows a handler in the Global.asax file for the Error event. The handler in the example is called whenever an unhandled exception occurs anywhere in the application. If an exception is caught in a try/catch block or by a page object's Error event, the application does not raise the Error error. void Application_Error(Object sender, EventArgs e) { if(!System.Diagnostics.EventLog.SourceExists ("ASPNETApplication")) { System.Diagnostics.EventLog.CreateEventSource ("ASPNETApplication", "Application"); } System.Diagnostics.EventLog.WriteEntry ("ASPNETApplication", Server.GetLastError().Message); } The code writes an entry to the system event log. It checks first to determine whether the event log entry named ASPNETApplication exists; if not, the code creates it. The code gets the error message associated with the error by calling the GetLastError method, and then writes the error message to the log.

Security:
This code example requires that the application have permission to access the system event log. For more information about using the system event log.

Page 86

ASP.NET MATERIAL

STATEMANAGEMENT
Page Submission:
One of the ways in which a Microsoft Office InfoPath form can implement a data submission process is to submit the form's data to an Active Server Page (ASP or ASPX) that is hosted on a Web server such as Microsoft Internet Information Services (IIS). The data submission process is enabled through the Submitting Forms dialog box, which is opened by clicking Submitting Forms on the Tools menu while in design mode. There are two approaches to enabling data submission with an ASP page: one is to specify the Uniform Resource Locator (URL) to the ASP page in the URL box that is displayed by clicking Submit through HTTP in the Submit list. The other is to perform the submission programmatically with script by clicking Submit using custom script in the Submit list and then adding custom script in the Microsoft Script Editor (MSE). In either case, the form's data is sent to the ASP page using HTTP, and the ASP page performs some processing of the data that was submitted. In the Data Submission developer sample form, submission to an ASP page is implemented using custom script, which is contained in the OnSubmitRequest event handler that is created from the Submitting Forms dialog box. The Data submission developer sample form performs three steps during the ASP data submission process, including determining the submission method, sending the data to the ASP page, and processing the data with the ASP page. Determining the submission method: The first step that the Data Submission developer sample form takes in its implementation of a custom data submission process is to determine the submission method to use. The submission method is determined by the contents of the config.xml file that is included in the form files for the Data Submission form template. Using the elements contained in config.xml, you can specify whether the sample form uses an ASP page or an XML Web service for its data submission method. There are three elements in the Config.xml file: submitUrl This element specifies the URL to use for the submission process. This is the URL either for the ASP page or for the XML Web service.

Page 87

ASP.NET MATERIAL

SubmitMethod: This element specifies the submission method. The possible values are ASP and SOAP. ServerErrorDumpFile: This element specifies the location and file name of the error dump file that will be created if the Web server returns an error. The error dump file is formatted as an HTML page.

To specify the data submission method, simply modify the elements of the config.xml file using the examples contained in the comments of the file. The default Web server name used in the file is localhost, but this should be changed to match your own server name if the server is not running locally. For more information about configuring the Web server. Note: To modify the config.xml file, you'll need to extract the sample form's component files to a folder location on your hard disk. The file cannot be modified when the Data Submission developer sample form is open because it is write-protected. Sending the data to the ASP page: When you click Test Submit on the File menu while filling out the Data Submission developer sample form, the script in the OnSubmitRequest event handler checks the submission method specified in config.xml, and if it is ASP, calls the AspPost custom function. This custom function takes two parameters:

objXmlHttp This parameter contains a reference to the Microsoft XML Core Services XMLHTTP object created in the OnSubmitRequest event handler. strUrl This parameter contains the URL specified by the submitUrl element in config.xml.

Using the specified parameters, the AspPost function attempts to send the form's underlying XML document to the ASP page using the following code: function AspPost(objXmlHttp, strUrl) { // post xml document to strUrl objXmlHttp.open("POST", strUrl, false); try { objXmlHttp.send(XDocument.DOM.xml); } catch(ex) { XDocument.UI.Alert("Could not post (ASP) document to " + strUrl + "\r\n" + ex.number + " - " + ex.description);

Page 88

ASP.NET MATERIAL
return false; } } The code first uses the open method of the XMLHTTP object to open the ASP page specified by the strUrl parameter; then it uses the send method to post the form's underlying XML document to the ASP page. The form's underlying XML document is obtained using the DOM property of the InfoPath object model's XDocument object, which returns a reference to an XML Document Object Model (DOM) containing the data of the form. Because the entire contents of the form's underlying XML document is to be sent to the ASP page, the xml property of the XML DOM is used. If the AspPost function is unable to send the data to the ASP page, the Alert method of the InfoPath UI object displays an error message. Note: In addition to the preceding code, the AspPost function also contains script for checking the response returned by the ASP page. If the returned response indicates that an error has occurred, that error is displayed. Processing the data with the ASP page: After the form's data is submitted to the ASP page, the ASP page takes over the processing of that data. It first checks the value of the blnSubmitSuccess element of the submitted XML document, and if that value is False, returns an error message and discontinues processing of the XML document. If the value is True, the ASP page uses the FileSystemObject object to save the XML document to a virtual directory on the Web server with the default file name SubmittedDocument.xml; then a successful response message is returned. The following is the part of the ASP code that is used to save the XML document to the virtual directory on the Web server: // Save the submitted XML document to disk. var objFso = Server.CreateObject("Scripting.FileSystemObject"); var strFileName = Server.MapPath(".") + "\\"+ "SubmittedDoc.xml"; if (objFso.FileExists(strFileName)) { objFso.DeleteFile(strFileName); } // Insert the <submitMethod> element in the XML document. var objSubmitMethodNode = objXmlDoc.selectSingleNode("//submitMethod");

Page 89

ASP.NET MATERIAL
if (!objSubmitMethodNode) { // If the <submitMethod> element was not present in the XML document, // then create it and add it as the last child. objSubmitMethodNode = objXmlDoc.createElement("submitMethod"); objXmlDoc.documentElement.insertBefore(objSubmitMethodNode, null); } objSubmitMethodNode.text = "ASP" // Insert the <dteSubmitDate> element in the XML document. var objSubmitDateNode = objXmlDoc.selectSingleNode("//dteSubmitDate"); if (!objSubmitDateNode) { // If the <dteSubmitDate> element is not present // in the XML document, create it. objSubmitDateNode = objXmlDoc.createElement("dteSubmitDate"); objXmlDoc.documentElement.insertBefore( objSubmitDateNode, objSubmitMethodNode); } var dteNow = new Date(); objSubmitDateNode.text = formatDate(dteNow); objXmlDoc.save(strFileName); // Return submission success. objNewEl.text = "true"; objCurEl.appendChild(objNewEl); objReturnedXmlDoc.save(Response); Response.Status = "200 OK"; Response.End(); In addition to simply persisting the submitted XML document to a virtual directory on the Web server, the ASP page also inserts two XML elements into the saved document:

dteSubmitDate: This element contains the date and time that the XML document was submitted to the ASP page. submitMethod: This element contains the type of submission method used, which is ASP in the case of the ASP method.

If you open the SubmittedDocument.xml file using InfoPath, both of the added XML elements will be displayed in the form.

Page 90

ASP.NET MATERIAL

Cookies:
A cookie is a small bit of text that accompanies requests and pages as they go between the Web server and browser. The cookie contains information the Web application can read whenever the user visits the site. This topic contains the following:

Scenarios Background Code Examples Class Reference Additional Resources What's New

Scenarios:
Cookies provide a means in Web applications to store user-specific information. For example, when a user visits your site, you can use cookies to store user preferences or other information. When the user visits your Web site another time, the application can retrieve the information it stored earlier. A cookie is a small bit of text that accompanies requests and pages as they go between the Web server and browser. The cookie contains information the Web application can read whenever the user visits the site. For example, if a user requests a page from your site and your application sends not just a page, but also a cookie containing the date and time, when the user's browser gets the page, the browser also gets the cookie, which it stores in a folder on the user's hard disk. Later, if user requests a page from your site again, when the user enters the URL the browser looks on the local hard disk for a cookie associated with the URL. If the cookie exists, the browser sends the cookie to your site along with the page request. Your application can then determine the date and time that the user last visited the site. You might use the information to display a message to the user or check an expiration date. Cookies are associated with a Web site, not with a specific page, so the browser and server will exchange cookie information no matter what page the user requests from your site. As the user visits different sites, each site might send a cookie to the user's browser as well; the browser stores all the cookies separately.

Page 91

ASP.NET MATERIAL
Cookies help Web sites store information about visitors. More generally, cookies are one way of maintaining continuity in a Web applicationthat is, of performing state management. Except for the brief time when they are actually exchanging information, the browser and Web server are disconnected. Each request a user makes to a Web server is treated independently of any other request. Many times, however, it's useful for the Web server to recognize users when they request a page. For example, the Web server on a shopping site keeps track of individual shoppers so the site can manage shopping carts and other user-specific information. A cookie therefore acts as a kind of calling card, presenting pertinent identification that helps an application know how to proceed. Cookies are used for many purposes; all relating to helping the Web site remember users. For example, a site conducting a poll might use a cookie simply as a Boolean value to indicate whether a user's browser has already participated in voting so that the user cannot vote twice. A site that asks a user to log on might use a cookie to record that the user already logged on so that the user does not have to keep entering credentials.

Cookie Limitations:
Most browsers support cookies of up to 4096 bytes. Because of this small limit, cookies are best used to store small amounts of data, or better yet, an identifier such as a user ID. The user ID can then be used to identify the user and read user information from a database or other data store. Browsers also impose limitations on how many cookies your site can store on the user's computer. Most browsers allow only 20 cookies per site; if you try to store more, the oldest cookies are discarded. Some browsers also put an absolute limit, usually 300, on the number of cookies they will accept from all sites combined. A cookie limitation that you might encounter is that users can set their browser to refuse cookies. If you define a P3P privacy policy and place it in the root of your Web site, more browsers will accept cookies from your site. However, you might have to avoid cookies altogether and use a different mechanism to store user-specific information. A common method for storing user information is session state, but session state depends on cookies, as explained later in the section "Cookies and Session State." Although cookies can be very useful in your application, the application should not depend on being able to store cookies. Do not use cookies to support critical features. If your application must rely on cookies, you can test to see whether the browser will accept cookies. See the "Checking Whether a Browser Accepts Cookies" section later in this topic.

Writing Cookies:
The browser is responsible for managing cookies on a user system. Cookies are sent to the browser via the HttpResponse object that exposes a collection called Cookies. You can access the HttpResponse object as the Response property of your Page class. Any cookies that you want to send to the browser must be added to this collection. When

Page 92

ASP.NET MATERIAL
creating a cookie, you specify a Name and Value. Each cookie must have a unique name so that it can be identified later when reading it from the browser. Because cookies are stored by name, naming two cookies the same will cause one to be overwritten. You can also set a cookie's date and time expiration. Expired cookies are deleted by the browser when a user visits the site that wrote the cookies. The expiration of a cookie should be set for as long as your application considers the cookie value to be valid. For a cookie to effectively never expire, you can set the expiration date to be 50 years from now. If you do not set the cookie's expiration, the cookie is created but it is not stored on the user's hard disk. Instead, the cookie is maintained as part of the user's session information. When the user closes the browser, the cookie is discarded. A non-persistent cookie like this is useful for information that needs to be stored for only a short time or that for security reasons should not be written to disk on the client computer. For example, non-persistent cookies are useful if the user is working on a public computer, where you do not want to write the cookie to disk. You can add cookies to the Cookies collection in a number of ways. The following example shows two methods to write cookies:
Response.Cookies ["userName"].Value = "patrick"; Response.Cookies ["userName"].Expires = DateTime.Now.AddDays (1); HttpCookie aCookie = new HttpCookie ("lastVisit"); aCookie.Value = DateTime.Now.ToString (); aCookie.Expires = DateTime.Now.AddDays (1); Response.Cookies.Add (aCookie);

The example adds two cookies to the Cookies collection, one named userName and the other named lastVisit. For the first cookie, the values of the Cookies collection are set directly. You can add values to the collection this way because Cookies derives from a specialized collection of type NameObjectCollectionBase. For the second cookie, the code creates an instance of an object of type HttpCookie, sets its properties, and then adds it to the Cookies collection via the Add method. When you instantiate an HttpCookie object, you must pass the cookie name as part of the constructor. Both examples accomplish the same task, writing a cookie to the browser. In both methods, the expiration value must be of type DateTime. However, the lastVisited value is also a date-time value. Because all cookie values are stored as strings, the date-time value has to be converted to a String .

Page 93

ASP.NET MATERIAL
Cookies with More Than One Value:
You can store one value in a cookie, such as user name and last visit. You can also store multiple name-value pairs in a single cookie. The name-value pairs are referred to as subkeys.. For example, instead of creating two separate cookies named userName and lastVisit, you can create a single cookie named userInfo that has the subkeys userName and lastVisit. You might use subkeys for several reasons. First, it is convenient to put related or similar information into a single cookie. In addition, because all the information is in a single cookie, cookie attributes such as expiration apply to all the information. A cookie with subkeys also helps you limit the size of cookie files. As noted earlier in the "Cookie Limitations" section, cookies are usually limited to 4096 bytes and you can't store more than 20 cookies per site. By using a single cookie with subkeys, you use fewer of those 20 cookies that your site is allotted. In addition, a single cookie takes up about 50 characters for overhead, plus the length of the value that you store in it, all of which counts toward the 4096-byte limit. If you store five subkeys instead of five separate cookies, you save the overhead of the separate cookies and can save around 200 bytes. To create a cookie with subkeys, you can use a variation of the syntax for writing a single cookie. The following example shows two ways to write the same cookie, each with two subkeys:
Response.Cookies ["userInfo"] ["userName"] = "patrick"; Response.Cookies ["userInfo"] ["lastVisit"] = DateTime.Now.ToString (); Response.Cookies ["userInfo"].Expires = DateTime.Now.AddDays (1); HttpCookie aCookie = new HttpCookie ("userInfo"); aCookie.Values ["userName"] = "patrick"; aCookie.Values ["lastVisit"] = DateTime.Now.ToString (); aCookie.Expires = DateTime.Now.AddDays (1); Response.Cookies.Add (aCookie);

Controlling Cookie Scope:


By default, all cookies for a site are stored together on the client, and all cookies are sent to the server with any request to that site. In other words, every page in a site gets all of the cookies for that site. However, you can set the scope of cookies in two ways:

Limit the scope of cookies to a folder on the server, which allows you to limit cookies to an application on the site. Set scope to a domain, which allows you to specify which subdomains in a domain can access a cookie.

Page 94

ASP.NET MATERIAL
Limiting Cookies to a Folder or Application:
To limit cookies to a folder on the server, set the cookie's Path property, as in the following example:
HttpCookie appCookie = new HttpCookie ("AppCookie"); appCookie.Value = "written + DateTime.Now.ToString (); appCookie.Expires = DateTime.Now.AddDays (1); appCookie.Path = "/Application1"; Response.Cookies.Add (appCookie);

The path can either be a physical path under the site root or a virtual root. The effect will be that the cookie is available only to pages in the Application1 folder or virtual root. For example, if your site is called www.contoso.com, the cookie created in the previous example will be available to pages with the path http://www.contoso.com/Application1/ and to any pages beneath that folder. However, the cookie will not be available to pages in other applications. Limiting Cookie Domain Scope By default, cookies are associated with a specific domain. For example, if your site is www.contoso.com, the cookies you write are sent to the server when users request any page from that site. (This might not include cookies with a specific path value.) If your site has subdomainsfor example, contoso.com, sales.contoso.com, and support.contoso.comthen you can associate cookies with a specific subdomain. To do so, set the cookie's Domain property, as in this example:
Response.Cookies ["domain"].Value = DateTime.Now.ToString (); Response.Cookies ["domain"].Expires = DateTime.Now.AddDays (1); Response.Cookies ["domain"].Domain = "support.contoso.com";

When the domain is set in this way, the cookie will be available only to pages in the specified subdomain. You can also use the Domain property to create a cookie that can be shared among multiple subdomains, as shown in the following example:
Response.Cookies ["domain"].Value = DateTime.Now.ToString (); Response.Cookies ["domain"].Expires = DateTime.Now.AddDays (1); Response.Cookies ["domain"].Domain = "contoso.com";

The cookie will then be available to the primary domain as well as to sales.contoso.com and support.contoso.com domains.

Page 95

ASP.NET MATERIAL
Reading Cookies:
When a browser makes a request to the server, it sends the cookies for that server along with the request. In your ASP.NET applications, you can read the cookies using the HttpRequest object, which is available as the Request property of your Page class. The structure of the HttpRequest object is essentially the same as that of the HttpResponse object, so you can read cookies out of the HttpRequest object much the same way you wrote cookies into the HttpResponse object. The following code example shows two ways to get the value of a cookie named username and display its value in a Label control.
If (Request.Cookies ["userName"]! = null) Label1.Text = Server.HtmlEncode ["userName"].Value); If (Request.Cookies ["userName"]! = null) { HttpCookie aCookie = Request.Cookies ["userName"]; Label1.Text = Server.HtmlEncode (aCookie.Value); } (Request.Cookies

Before trying to get the value of a cookie, you should make sure that the cookie exists; if the cookie does not exist, you will get a NullReferenceException exception. Notice also that the HtmlEncode method was called to encode the contents of a cookie before displaying it in the page. This makes certain that a malicious user has not added executable script into the cookie. Reading the value of a subkey in a cookie is likewise similar to setting it. The following code example shows one way to get the value of a subkey:
If (Request.Cookies ["userInfo"]! = null) { Label1.Text = Server.HtmlEncode (Request.Cookies ["userInfo"] ["userName"]); Label2.Text = Server.HtmlEncode (Request.Cookies ["userInfo"] ["lastVisit"]);

In the preceding example, the code reads the value of the subkey lastVisit, which was set earlier to the string representation of a DateTime value. Cookies store values as strings, so if you want to use the lastVisit value as a date, you have to convert it to the appropriate type, as in this example:
DateTime dt; dt = DateTime.Parse(Request.Cookies["userInfo"]["lastVisit"]);

Page 96

ASP.NET MATERIAL
The subkeys in a cookie are typed as a collection of type NameValueCollection. Therefore, another way to get an individual subkey is to get the subkeys collection and then extract the subkey value by name, as shown in the following example:
If (Request.Cookies ["userInfo"]! = null) { System.Collections.Specialized.NameValueCollection UserInfoCookieCollection; UserInfoCookieCollection = Request.Cookies ["userInfo"].Values; Label1.Text = Server.HtmlEncode (UserInfoCookieCollection ["userName"]); Label2.Text = Server.HtmlEncode (UserInfoCookieCollection ["lastVisit"]); }

Changing a Cookie's Expiration Date:


The browser is responsible for managing cookies, and the cookie's expiration time and date help the browser manage its store of cookies. Therefore, although you can read the name and value of a cookie, you cannot read the cookie's expiration date and time. When the browser sends cookie information to the server, the browser does not include the expiration information. (The cookie's Expires property always returns a date-time value of zero.) If you are concerned about the expiration date of a cookie, you must reset it, which is covered in the "Modifying and Deleting Cookies" section. Reading Cookie Collections You might occasionally need to read through all the cookies available to the page. To read the names and values of all the cookies available to the page, you can loop through the Cookies collection using code such as the following.
System.Text.StringBuilder output = new System.Text.StringBuilder (); HttpCookie aCookie; For (int i=0; i<Request.Cookies.Count; i++) { ACookie = Request.Cookies[i]; output.Append ("Cookie name = " + Server.HtmlEncode (aCookie.Name) + "<br />"); output.Append ("Cookie value = " + Server.HtmlEncode (aCookie.Value) + "<br /><br />"); } Label1.Text = output.ToString ();

A limitation of the preceding example is that if the cookie has subkeys, the display shows the subkeys as a single name/value string. You can read a cookie's HasKeys property to determine whether the cookie has subkeys. If so, you can read the subkey collection to get individual subkey names and values. You can read subkey values from the Values

Page 97

ASP.NET MATERIAL
collection directly by index value. The corresponding subkey names are available in the AllKeys member of the Values collection, which returns an array of strings. You can also use the Keys member of the Values collection. However, the AllKeys property is cached the first time it is accessed. In contrast, the Keys property builds an array each time it is accessed. For this reason, the AllKeys property is much faster on subsequent accesses within the context of the same page request. The following example shows a modification of the preceding example. It uses the HasKeys property to test for subkeys, and if subkeys are detected, the example gets subkeys from the Values collection:
For (int i=0; i<Request.Cookies.Count; i++) { ACookie = Request.Cookies[i]; output.Append ("Name = " + aCookie.Name + "<br />"); If (aCookie.HasKeys) { For (int j=0; j<aCookie.Values.Count; j++) { SubkeyName = Server.HtmlEncode (aCookie.Values.AllKeys[j]); SubkeyValue = Server.HtmlEncode (aCookie.Values[j]); output.Append ("Subkey name = " + subkeyName + "<br />"); output.Append ("Subkey value = " + subkeyValue + "<br /><br />"); } } Else { output.Append ("Value = " + Server.HtmlEncode (aCookie.Value) + "<br /><br />"); } } Label1.Text = output.ToString ();

Alternatively, you can extract the subkeys as a NameValueCollection object as shown in the following example:
System.Text.StringBuilder output = new System.Text.StringBuilder (); HttpCookie aCookie; String subkeyName; String subkeyValue; For (int i = 0; i < Request.Cookies.Count; i++) { ACookie = Request.Cookies[i]; output.Append ("Name = " + aCookie.Name + "<br />"); If (aCookie.HasKeys) {

Page 98

ASP.NET MATERIAL
= System.Collections.Specialized.NameValueCollection CookieValues aCookie.Values; String [] CookieValueNames = CookieValues.AllKeys; For (int j = 0; j < CookieValues.Count; j++) { SubkeyName = Server.HtmlEncode (CookieValueNames[j]); SubkeyValue = Server.HtmlEncode (CookieValues[j]); output.Append ("Subkey name = " + subkeyName + "<br />"); output.Append ("Subkey value = " + subkeyValue + "<br /><br />"); } } else {

} } Label1.Text = output.ToString ();

output.Append ("Value = " + Server.HtmlEncode (aCookie.Value) + "<br /><br />");

Modifying and Deleting Cookies:


You cannot directly modify a cookie. Instead, changing a cookie consists of creating a new cookie with new values and then sending the cookie to the browser to overwrite the old version on the client. The following code example shows how you can change the value of a cookie that stores a count of the user's visits to the site:
If (Request.Cookies ["counter"] == null) Counter = 0; Else { Counter = int.Parse (Request.Cookies ["counter"].Value); } Counter++; Response.Cookies ["counter"].Value = counter.ToString (); Response.Cookies ["counter"].Expires = DateTime.Now.AddDays (1);

Deleting Cookies:
Deleting a cookiephysically removing it from the user's hard diskis a variation on modifying it. You cannot directly remove a cookie because the cookie is on the user's computer. However, you can have the browser delete the cookie for you. The technique is to create a new cookie with the same name as the cookie to be deleted, but to set the cookie's expiration to a date earlier than today. When the browser checks the cookie's expiration, the browser will discard the now-outdated cookie. The following code example shows one way to delete all the cookies available to the application:

Page 99

ASP.NET MATERIAL
HttpCookie aCookie; String cookieName; Int limit = Request.Cookies.Count; For (int i=0; i<limit; i++) { CookieName = Request.Cookies[i].Name; ACookie = new HttpCookie (cookieName); aCookie.Expires = DateTime.Now.AddDays (-1); Response.Cookies.Add (aCookie); }

Modifying or Deleting Subkeys:


Modifying an individual subkey is the same as creating it, as shown in the following example:
Response.Cookies ["userInfo"]["lastVisit"] = DateTime.Now.ToString(); Response.Cookies ["userInfo"].Expires = DateTime.Now.AddDays (1);

To delete an individual subkey, you manipulate the cookie's Values collection, which holds the subkeys. You first recreate the cookie by getting it from the Cookies object. You can then call the Remove method of the Values collection, passing to the Remove method the name of the subkey to delete. You then add the cookie to the Cookies collection so it will be sent in its modified form back to the browser. The following code example shows how to delete a subkey. In the sample, the name of the subkey to remove is specified in a variable.
String subkeyName; SubkeyName = "userName"; HttpCookie aCookie = Request.Cookies ["userInfo"]; aCookie.Values.Remove (subkeyName); aCookie.Expires = DateTime.Now.AddDays (1); Response.Cookies.Add (aCookie);

Cookies and Security:


The security issues with cookies are similar to those of getting data from the client. In your application, cookies are another form of user input and are therefore subject to examining and spoofing. A user can as a minimum see the data that you store in a cookie, since the cookie is available on the user's own computer. The user can also change the cookie before the browser sends it to you. You should never store sensitive data in a cookie, such as user names, passwords, credit card numbers, and so on. Do not put anything in a cookie that should not be in the hands of a user or of someone who might somehow steal the cookie.

Page 100

ASP.NET MATERIAL
Similarly, be suspicious of information you get out of a cookie. Do not assume that the data is the same as when you wrote it out; use the same safeguards in working with cookie values that you would with data that a user has typed into a Web page. The examples earlier in this topic showed HTML-encoding the contents of a cookie before displaying the value in a page, as you would before displaying any information you get from users. Cookies are sent between browser and server as plain text, and anyone who can intercept your Web traffic can read the cookie. You can set a cookie property that causes the cookie to be transmitted only if the connection uses the Secure Sockets Layer (SSL). SSL does not protect the cookie from being read or manipulated while it is on the user's computer, but it does prevent the cookie from being read while in transit because the cookie is encrypted.

Determining Whether a Browser Accepts Cookies:


Users can set their browser to refuse cookies. No error is raised if a cookie cannot be written. The browser likewise does not send any information to the server about its current cookie settings. One way to determine whether cookies are accepted is by trying to write a cookie and then trying to read it back again. If you cannot read the cookie you wrote, you assume that cookies are turned off in the browser. The following code example shows how you might test whether cookies are accepted. The sample consists of two pages. The first page writes out a cookie, and then redirects the browser to the second page. The second page tries to read the cookie. It in turn redirects the browser back to the first page, adding to the URL a query string variable with the results of the test. The code for the first page (AcceptsCookies.aspx) looks like the following example:
Protected void Page_Load (object sender, EventArgs e) { If (! Page.IsPostBack) { If (Request.QueryString ["AcceptsCookies"] == null) { Response.Cookies ["TestCookie"].Value = "ok"; Response.Cookies ["TestCookie"].Expires = DateTime.Now.AddMinutes (1); Response.Redirect ("TestForCookies.aspx? Redirect=" + Server.UrlEncode (Request.Url.ToString ())); } Else {

Page 101

ASP.NET MATERIAL
Label1.Text = "Accept cookies = " + Server.UrlEncode ( Request.QueryString ["AcceptsCookies"]);

} } }

The page first tests to see if this is a postback, and if not, the page looks for the query string variable name AcceptsCookies that contains the test results. If there is no query string variable, the test has not been completed, so the code writes out a cookie named TestCookie. After writing out the cookie, the sample calls Redirect to transfer to the test page TestForCookies.aspx. Appended to the URL of the test page is a query string variable named redirect containing the URL of the current page; this will allow you to redirect back to this page after performing the test. The test page can consist entirely of code; it does not need to contain controls. The following example illustrates the test page (TestForCookies.aspx).
Protected void Page_Load (object sender, EventArgs e) { String redirect = Request.QueryString ["redirect"]; String acceptsCookies; If (Request.Cookies ["TestCookie"] ==null) AcceptsCookies = "no"; Else { AcceptsCookies = "yes"; // Delete test cookie. Response.Cookies ["TestCookie"].Expires = DateTime.Now.AddDays (-1); } Response.Redirect (redirect + "? AcceptsCookies=" + acceptsCookies, True); }

After reading the redirect query string variable, the code tries to read the cookie. For housekeeping purposes, if the cookie exists, it is immediately deleted. When the test is finished, the code constructs a new URL from the URL passed to it in the redirect query string variable. The new URL also includes a query string variable containing test results. The final step is to use the new URL to redirect the browser to the original page. An improvement in the example would be to keep the cookie test results in a persistent store such as a database so that the test does not have to be repeated each time the user views the original page. (Storing the test results in session state by default requires cookies.)

Page 102

ASP.NET MATERIAL
Cookies and Session State:
When a user navigates to your site, the server establishes a unique session for that user that lasts for the duration of the user's visit. For each session, ASP.NET maintains session state information where applications can store user-specific information. For more information. ASP.NET must track a session ID for each user so that it can map the user to session state information on the server. By default, ASP.NET uses a non-persistent cookie to store the session state. However, if a user has disabled cookies on the browser, session state information cannot be stored in a cookie. ASP.NET offers an alternative in the form of cookieless sessions. You can configure your application to store session IDs not in a cookie, but in the URLs of pages in your site. If your application relies on session state, you might consider configuring it to use cookieless sessions. However, under some limited circumstances, if the user shares the URL with someone elseperhaps to send the URL to a colleague while the user's session is still activethen both users can end up sharing the same session, with unpredictable results.

Session State:
Use ASP.NET session state to store and retrieve values for a user. This topic contains:

Background Code Examples Class Reference

ASP.NET session state enables you to store and retrieve values for a user as the user navigates ASP.NET pages in a Web application. HTTP is a stateless protocol. This means that a Web server treats each HTTP request for a page as an independent request. The server retains no knowledge of variable values that were used during previous requests. ASP.NET session state identifies requests from the same browser during a limited time window as a session, and provides a way to persist variable values for the duration of that session. By default, ASP.NET session state is enabled for all ASP.NET applications. Alternatives to session state include the following:

Application state, which stores variables that can be accessed by all users of an ASP.NET application.

Page 103

ASP.NET MATERIAL

Profile properties, which persists user values in a data store without expiring them. ASP.NET caching, which stores values in memory that is available to all ASP.NET applications. View state, which persists values in a page. Cookies. The query string and fields on an HTML form that are available from an HTTP request.

Session Variables:
Session variables are stored in a SessionStateItemCollection object that is exposed through the HttpContext.Session property. In an ASP.NET page, the current session variables are exposed through the Session property of the Page object. The collection of session variables is indexed by the name of the variable or by an integer index. Session variables are created by referring to the session variable by name. You do not have to declare a session variable or explicitly add it to the collection. The following example shows how to create session variables in an ASP.NET page for the first and last name of a user, and set them to values retrieved from TextBox controls.
Session ["FirstName"] = FirstNameTextBox.Text; Session ["LastName"] = LastNameTextBox.Text;

Session variables can be any valid .NET Framework type. The following example stores an ArrayList object in a session variable named StockPicks. The value returned by the StockPicks session variable must be cast to the appropriate type when you retrieve it from the SessionStateItemCollection.
// When retrieving an object from session state, cast it to // the appropriate type. ArrayList stockPicks = (ArrayList) Session ["StockPicks"]; // Write the modified stock picks list back to session state. Session ["StockPicks"] = stockPicks;

Session Identifiers:
Sessions are identified by a unique identifier that can be read by using the SessionID property. When session state is enabled for an ASP.NET application, each request for a page in the application is examined for a SessionID value sent from the browser. If no SessionID value is supplied, ASP.NET starts a new session and the SessionID value for that session is sent to the browser with the response.

Page 104

ASP.NET MATERIAL
By default, SessionID values are stored in a cookie. However, you can also configure the application to store SessionID values in the URL for a "cookieless" session. A session is considered active as long as requests continue to be made with the same SessionID value. If the time between requests for a particular session exceeds the specified time-out value in minutes, the session is considered expired. Requests made with an expired SessionID value result in a new session.

Cookieless SessionIDs:
By default, the SessionID value is stored in a non-expiring session cookie in the browser. However, you can specify that session identifiers should not be stored in a cookie by setting the cookieless attribute to true in the sessionState section of the Web.config file. The following example shows a Web.config file that configures an ASP.NET application to use cookieless session identifiers.
<Configuration> <system.web> <sessionState cookieless="true" RegenerateExpiredSessionId="true" /> </system.web> </configuration>

ASP.NET maintains cookieless session state by automatically inserting a unique session ID into the page's URL. For example, the following URL has been modified by ASP.NET to include the unique session ID lit3py55t21z5v55vlm25s55: When ASP.NET sends a page to the browser, it modifies any links in the page that use an application-relative path by embedding a session ID value in the links. (Links with absolute paths are not modified.) Session state is maintained as long as the user clicks links that have been modified in this manner. However, if the client rewrites a URL that is supplied by the application, ASP.NET may not be able to resolve the session ID and associate the request with an existing session. In that case, a new session is started for the request. The session ID is embedded in the URL after the slash that follows the application name and before any remaining file or virtual directory identifier. This enables ASP.NET to resolve the application name before involving the SessionStateModule in the request.

Page 105

ASP.NET MATERIAL
Regenerating Expired Session Identifiers:
By default, the session ID values that are used in cookieless sessions are recycled. That is, if a request is made with a session ID that has expired, a new session is started by using the SessionID value that is supplied with the request. This can result in a session unintentionally being shared when a link that contains a cookieless SessionID value is used by multiple browsers. (This can occur if the link is passed through a search engine, through an e-mail message, or through another program.) You can reduce the chance of session data being shared by configuring the application not to recycle session identifiers. To do this, set the regenerateExpiredSessionId attribute of the sessionState configuration element to true. This generates a new session ID when a cookieless session request is made with an expired session ID. Custom Session Identifiers You can implement a custom class to supply and validate SessionID values. To do so, create a class that inherits the SessionIDManager class and override the CreateSessionID and Validate methods with your own implementations. For an example, see the example provided for the CreateSessionID method. You can replace the SessionIDManager class by creating a class that implements the ISessionIDManager interface. For example, you might have a Web application that associates a unique identifier with non-ASP.NET pages (such as HTML pages or images) by using an ISAPI filter. You can implement a custom SessionIDManager class to use this unique identifier with ASP.NET session state. If your custom class supports cookieless session identifiers, you must implement a solution for sending and retrieving session identifiers in the URL.

Session Modes:
ASP.NET session state supports several storage options for session variables. Each option is identified as a session-state Mode type. The default behavior is to store session variables in the memory space of the ASP.NET worker process. However, you can also specify that session state should be stored in a separate process, in a SQL Server database, or in a custom data source. If you do not want session state enabled for your application, you can set the session mode to Off.

Session Events:
ASP.NET provides two events that help you manage user sessions. The Session_OnStart event is raised when a new session starts, and the Session_OnEnd event is raised when a session is abandoned or expires. Session events are specified in the Global.asax file for an ASP.NET application.

Page 106

ASP.NET MATERIAL
The Session_OnEnd event is not supported if the session Mode property is set to a value other than InProc, which is the default mode. For more information, see Session-State Events.

Configuring Session State:


Session state is configured by using the sessionState element of the system.web configuration section. You can also configure session state by using the EnableSessionState value in the @ Page directive. The sessionState element enables you to specify the following options:

The mode in which the session will store data. The way in which session identifier values are sent between the client and the server. The session Timeout value. Supporting values that are based on the session Mode setting.

The following example shows a sessionState element that configures an application for SQLServer session mode. It sets the Timeout value to 30 minutes, and specifies that session identifiers are stored in the URL. Copy
<sessionState mode="SQLServer" Cookieless="true RegenerateExpiredSessionId="true Timeout="30" SqlConnectionString="Data Security=SSPI;" StateNetworkTimeout="30"/>

Source=MySqlServer;

Integrated

You can disable session state for an application by setting the session-state mode to Off. If you want to disable session state for only a particular page of an application, you can set the EnableSessionState value in the @ Page directive to false. The EnableSessionState value can also be set to ReadOnly to provide read-only access to session variables.

Concurrent Requests and Session State:


Access to ASP.NET session state is exclusive per session, which means that if two different users make concurrent requests, access to each separate session is granted concurrently. However, if two concurrent requests are made for the same session (by using the same SessionID value), the first request gets exclusive access to the session information. The second request executes only after the first request is finished. (The second session can also get access if the exclusive lock on the information is freed

Page 107

ASP.NET MATERIAL
because the first request exceeds the lock time-out.) If the EnableSessionState value in the @ Page directive is set to ReadOnly, a request for the read-only session information does not result in an exclusive lock on the session data. However, read-only requests for session data might still have to wait for a lock set by a read-write request for session data to clear.

Session Tracking Architecture Introduction:


This article explains how to implement session tracking using two of the simplest & oldest methods available to programmers. I feel that in order to understand the beauty of new technologies that exist today it is often necessary to understand what used to be done before that technology came into being. The techniques presented in this article do not use the new technologies present to implement session tracking, but use some old, tried and tested ways which are extremely popular even today. After reading this article you would be able to implement session tracking using any language, since you would understand the concepts of session tracking rather than some language dependent implementation of session tracking. Various languages provide higher level API for implementing session tracking. There is a detailed session tracking API available in Java which enables many programmers to get session tracking implemented quickly and easily. But that is not what this article talks about. It focuses on understanding the basic techniques so that you can use it with any language. To understand this article you need to know 3 things. 1. Familiarity with any server side technology such as JSP, ASP, Java servlets, etc. 2 .You need to know HTML very well. 3. You need to know how to access the contents of a HTML Form from within a programming language such as JSP, ASP, etc.

Application Objects in ASP .NET


ADO.NET and XML: ADO.NET and XML are the core technologies that help you design an effective caching subsystem. ADO.NET provides a namespace of data-oriented classes through

Page 108

ASP.NET MATERIAL
which you can build a rough but functional in-memory DBMS. XML is the input and output language of this subsystem, but it's much more than the language used to serialize and desterilize living instances of ADO.NET objects. If you have XML documents formatted like datahierarchical documents with equally sized subtreesyou can synchronize them to ADO.NET objects and use both XML-related technologies and relational approaches to walk through the collection of data rows. Although ADO.NET and XML are tightly integrated, only one ADO.NET object has the ability to publicly manipulate XML for reading and writing. This object is called the DataSet. ASP.NET apps often end up handling DataSet objects. DataSet objects are returned by data adapter classes, which are one of the two ADO.NET command classes that get in touch with remote data sources. DataSets can also be created from local dataany valid stream objects can be read into and populate a DataSet object. The DataSet has a powerful, feature-rich programming interface and works as an inmemory cache of disconnected data. It is structured as a collection of tables and relationships. This makes it suitable when you have to work with related tables of data. Using DataSets, all of your tables are stored in a single container. This container knows how to serialize its content to XML and how to restore it to its original state. Devising an XML-based Caching System: The majority of ASP.NET applications could take advantage of the Cache object for all of their caching needs. The Cache object is new to ASP.NET and provides unique and powerful features. It is a global, thread-safe object that does not store information on a per-session basis. In addition, the Cache is designed to ensure it does not tax the server's memory whatsoever. If memory pressure does become an issue, the Cache will automatically purge less recently used items based on a priority defined by the developer. Like Application, though, the Cache object does not share its state across the machines of a Web farm. I'll have more to say about the Cache object later. Aside from Web farms, there are a few tough scenarios you might want to consider as alternatives to Cache. Even when you have large DataSets to store on a per-session basis, storing and reloading them from memory will be faster than any other approach. However, with many users connected at the same time, each storing large blocks of data, you might want to consider helping the Cache object to do its job better. An app-specific layered caching system built around the Cache object is an option. In this case, sensitive data will go into the Cache efficiently managed by ASP.NET. The rest of them could be cached in a slower but memory-free storagefor example, session-specific XML files. Saving intermediate data to disk is a caching alternative that significantly reduces the demands on the Web server. To be effective, though, it should involve minimum overheadjust the time necessary to serialize and deserialize data. Custom schemas and proprietary data formats are unfit for this technique because the extra steps required introduce a delay. In .NET, you can use the DataSet object to fetch data and to persist it to disk. The DataSet object natively provides methods to save to XML and to load from it. These procedures, along with the internal representation of the DataSet, have been

Page 109

ASP.NET MATERIAL
carefully optimized. They let you save and restore XML files in an amount of time that grows linearly (rather than geometrically) with the size of the data to process. So instead of storing persistent data sets to Session, you can save them on the server on a per-user basis with temporary XML files. To recognize the XML file of a certain session, use the Session IDan ASCII sequence of letters and digits that uniquely identifies a connected user. To avoid the proliferation of such files, you kill them when the session ends. Saving DataSet objects to XML does not affect the structure of the app, as it will continue to work with the DataSet object in mind. The writing and reading is performed by a couple of ad hoc methods provided by the DataSet object with a little help from .NET stream objects. A Layered Caching System: If you want to use a cache mechanism to store data across multiple requests of the same page, your code will probably look like Figure 1. When the page first loads, you fetch all the data needed using the private member DataFromSourceToMemory. This function reads the rows from the data source and stores them into the cache, whatever it is. Then requests for the page will result in a call to DeserializeDataSource to fetch data. This call will try to load the DataSet from the cache and will resort to other physical access to the underlying DBMS if an exception is thrown. This can happen if the file is deleted from its location for any reason. Figure 2 shows the app's global.asax file. In the OnEnd event, the code deletes the XML file whose name matches the current session ID. The global.asax file resides in the root directory of an ASP.NET application. When you run an ASP.NET application, you must use a virtual directory. If you test an ASP.NET page outside a virtual directory, you won't capture any session or application event in your global.asax file. Also, while Session_OnStart is always raised, the Session_OnEnd event is not guaranteed to fire in an out-of-process scenario. Each active ASP.NET session is tracked using a 120-bit string that is composed of URL-legal ASCII characters. Session ID values are generated so uniqueness and randomness are guaranteed. This avoids collisions and makes it harder to guess the session ID of an existing session. The following code shows how to use session ID to persist to and reload data from disk, serializing a DataSet to an XML file. void SerializeDataSource(DataSet ds) { String strFile; strFile = Server.MapPath(Session.SessionID + ".xml"); XmlTextWriter xtw = new XmlTextWriter(strFile, null); ds.WriteXml(xtw); xtw.Close(); } That code is equivalent to storing the DataSet in a Session slot. Session["MyDataSet"] = ds;

Page 110

ASP.NET MATERIAL
Of course, the functionality of the previous two approaches is actually radically different. To read back previously saved data, you can use this code: DataSet DeserializeDataSource() { String strFile; strFile = Server.MapPath(Session.SessionID + ".xml"); // Read the content of the file into a DataSet XmlTextReader xtr = new XmlTextReader(strFile); DataSet ds = new DataSet(); ds.ReadXml(xtr); xtr.Close(); return ds; } This function locates an XML file whose name matches the ID of the current session and loads it into a newly created DataSet object. If you have a caching system based on the Session object, you should use this routine to replace any code that looks like this: DataSet ds = (DataSet) Session ["MyDataSet"]; Figure 3 shows some of the elements that could form the ASP.NET caching pyramid, but the design is not set in stone. The number and the type of layers are completely up to you, and are application-specific. In several Web applications, only one level is used: the DBMS tables level. If scalability is important, and your data is mostly disconnected, a layered caching system is almost a must.

Figure 3 Caching: Also different from layer to layer is the time needed to retrieve data. Session, in most cases, is an in-process and in-memory object. Nothing could be faster. Keeping Session lean is critical because it is duplicated for each connected user. For quick access to data that can be shared between users, nothing is better than Cache or Application. Cache is faster and provides for automatic decay and prioritization. Relatively large amounts of frequently used static data can be effectively stored in any of these containers.

Page 111

ASP.NET MATERIAL
Disk files serve as an emergency copy of data. Use them when you don't need or can't afford to keep all the data in memory, but when going to the database is too costly. Finally, DBMS views are just like virtual tables that represent the data from one or more tables in an alternative way. Views are normally used for read-only data. Views can also be used as a security mechanism to restrict the data that a certain user can access. For example, some data can be available to users for query and/or update purposes, while the rest of the table remains invisible. And table views can constitute an intermediate storage for preprocessed or post-processed data. Therefore, accessing a view has the same effect for the application, but doesn't cause preprocessing delays or place any locks on the physical table. XML Server-side Data Islands: Caching is particularly useful when you have a large amount of data to load. However, when the amount of data is really huge, any techniqueeither on the client or the servercan hardly be optimal. When you have one million records to fetch, you're out of luck. In such situations, you can reduce the impact of the data bulk by using a layered architecture for caching by bringing the concept of client-side data islands to the server. An XML data island is a block of XML that is embedded in HTML and can be retrieved through the page's DOM. They're good at storing read-only information on the client. Used on the server, an XML data island becomes a persistent bulk of information that you can store in memory, or (for scalability) on disk. But, how do you read it back? Typically, in .NET you would use DataSet XML facilities to read and write. For lots of data (say, one million records), caching this way is not effective if you don't need all records in memory. Keeping all the records in a single file makes it heavier for the system. What about splitting records into different XML files that are organized like those in Figure 4? This expands the level of XML disk files shown in Figure 3.

Figure 4 Dividing RecordsforPerformance: You can build up an extensible tree of XML files, each representing a page of database records. Each time you need a block of non-cached records, you fetch them from the database and add them to a new or existing XML data island. You would use a special naming convention to distinguish files on a per-session basis, for example, by appending a progressive index to the session ID. An index file can help you locate the right data island where a piece of data is cached. For really huge bulks of data, this

Page 112

ASP.NET MATERIAL
minimizes the processing on all tiers. However, with one million records to manage there is no perfect tool or approach. Automatic Cache Bubble-up: Once you have a layered caching system, how you move data from one tier to the next is up to you. However, ASP.NET provides a facility that can involve both a disk file and a Cache object. The Cache object works like an application-wide repository for data and objects. Cache looks quite different from the plain old Application object. For one thing, it is thread-safe and does not require locks on the repository prior to reading or writing. Some of the items stored in the Cache can be bound to the timestamp of one or more files or directories as well as an array of other cached items. When any of these resources change, the cached object becomes obsolete and is removed from the cache. By using a proper try/catch block you can catch the empty item and refresh the cache. String strFile; strFile = Server.MapPath(Session.SessionID + ".xml"); CacheDependency fd = new CacheDependency(strFile); DataSet ds = DeserializedDataSource(); Cache.Insert("MyDataSet", ds, fd); To help the scavenging routines of the Cache object, you can assign some of your cache items with a priority and even a decay factor that lowers the priority of the keys that have limited use. When working with the Cache object, you should never assume that an item is there when you need it. Always be ready to handle an exception due to null or invalid values. If your application needs to be notified of an item's removal, then register for the cache's OnRemove event by creating an instance of the CacheItemRemovedCallback delegate and passing it to the Cache's Insert or Add method. CacheItemRemovedCallback onRemove = new CacheItemRemovedCallback(DoSomething); The signature of the event handler looks like this: void DoSomething(String key, Object value, CacheItemRemovedReason reason) From DataSet to XML: When stored in memory, the DataSet is represented through a custom binary structure like any .NET class. Each and every data row is bound with two arrays: one for the current value and one for the original value. The DataSet is not kept in memory as XML, but XML is used for output when the DataSet is remoted through app domains and networks or serialized to disk. The XML representation of a DataSet object is based on diffgramsa subset of the SQL Server 2000 updategrams. It is an optimized XML schema that describes changes the object has undergone since it was created. If the DataSetor any contained DataTable and DataRow objecthas no changes pending, then the XML representation is a description of the child tables. If there are changes pending, then the remoted and serialized XML representation of the DataSet is

Page 113

ASP.NET MATERIAL
the diffgram. The structure of a diffgram is shown in Figure 5. It is based on two nodes, <before> and <after>. A <before> node describes the original state of the record, while <after> exposes the contents of the modified record. An empty <before> node means the record has been added and an empty <after> node means the node has been deleted. The method that returns the current XML format is GetXml, which returns a string. WriteXml saves the content to a stream while ReadXml rebuilds a living instance of the DataSet object. If you want to save a DataSet to XML, use WriteXml directly (instead of getting the text through GetXml) then save using file classes. When using WriteXml and ReadXml, you can control how data is written and read. You can choose between the diffgram and the basic format and decide if the schema information should be saved or not. Working with Paged Data Sources: There is a subtler reason that makes caching vital in ASP.NET. ASP.NET relies heavily on postback events, so when posted back to the server for update, any page must rebuild a consistent state. Each control saves a portion of its internal state to the page's view state bag. This information travels back and forth as part of the HTML. ASP.NET can restore this information when the postback event is processed on the Web server at risk. You repeatedly download all the datasay, hundreds of recordsjust to display the few that fit into the single grid page. If data is cached, you significantly reduce this overhead. This said, custom paging is probably the optimal approach for improving the overall performance of pagination. To enable custom pagination, you must set both the AllowPaging and AllowCustomPaging properties to True. You can do that declaratively or programmatically. Next, you arrange your code for pagination as usual and define a proper event handler for PageIndexChanged. The difference between custom and default pagination for a DataGrid control is that when custom paging is enabled, the control assumes that all the elements currently stored in its Items collectionthe content of the object bound to the DataSource propertyare part of the current page. It does not even attempt to extract a subset of records based on the page index and the page size. With custom paging, the programmer is responsible for providing the right content when a new page is requested. Once again, caching improves performance and scalability. The caching architecture is mostly application-specific, but I consider caching and custom pagination vital for a data-driven application. Data Readers: To gain scalability I'd always consider caching. However, there might be circumstances (such as highly volatile tables) in which project requirements lead you to consider alternative approaches. If you opt for getting data each time you need it, then you should use the DataReader classes instead of DataSets. A DataReader class is filled and returned by command classes like SqlCommand and OleDbCommand. DataReaders act like read-only, firehose cursors. They work connected, and to be lightweight they never cache a single byte of data. DataReader classes are extremely lean and are ideal for reading small portions of data frequently. Starting with Beta 2, a DataReader object can

Page 114

ASP.NET MATERIAL
be assigned to the DataSource property of a DataGrid, or to any data-bound control. By combining DataReaders with the grid's custom pagination, and both with an appropriate query command that loads only the necessary portions of records for a given page, you can obtain a good mix that enhances scalability and performance. illustrates some C# ASP.NET code that uses custom pagination and data readers. As mentioned earlier, a DataReader works while connected, and while the reader is open, the attached connection results in busy. It's clear that this is the price to pay for getting up-to-date rows and to keep the Web server's memory free. To avoid the overturn of the expected results, the connection must be released as soon as possible. This can happen only if you code it explicitly. The procedure that performs data access ends as follows: conn.Open(); dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); return dr; You open the connection, execute the command, and return an open DataReader object. When the grid is going to move to a new page, the code looks like this: grid.DataSource = CreateDataSource(grid.CurrentPageIndex); grid.DataBind(); dr.Close(); Once the grid has been refreshed (DataBind does that), explicitly closing the reader is key, not only to preserve scalability, but also to prevent the application's collapse. Under normal conditions, closing the DataReader does not guarantee that the connection will be closed. So do that explicitly through the connection's Close or the Dispose method. You could synchronize reader and connection by assigning the reader a particular command behavior, like so: dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); In this way, the reader enables an internal flag that automatically leads to closing the associated connection when the reader itself gets closed. SQL Statements: The standards of the SQL language do not provide special support for pagination. Records can be retrieved only by condition and according to the values of their fields, not based on absolute or relative positions. Retrieving records by positionfor example, the second group of 20 records in an sorted tablecan be simulated in various ways. For instance, you could use an existing or custom field that contains a regular series of values (such as 1-2-3-4) and guarantee its content to stay consistent across deletions and updates. Alternatively, you could use a stored procedure made of a sequence of SELECT statements that, through sorting and temporary tables, reduces the number of records returned from a particular subset. This is outlined in this pseudo SQL: first n records are, in reverse order, what you need SELECT INTO tmp TOP page*size field_names FROM table ORDER BY field_name DESC only the first "size" records are, in reverse order,

Page 115

ASP.NET MATERIAL
copied in a temp table SELECT INTO tmp1 TOP size field_names FROM tmp the records are reversed and returned SELECT field_names FROM tmp1 ORDER BY field_name DESC More efficient SQL can be written if you omit the requirement of performing random access to a given page. If you allow only moving to the next or previous page, and assume to know the last and the first key of the current page, then the SQL code is simpler and faster. Conclusion: Caching was already a key technique in ASP, but it's even more important in ASP.NETnot just because ASP.NET provides better infrastructural support for it, but because of the architecture of the Web Forms model. A lot of natural postback events, along with a programming style that transmits a false sense of total statefulness, could lead you to bad design choices like repeatedly reloading the whole DataSet just to show a refreshed page. To make design even trickier, many examples apply programming styles that are only safe in applications whose ultimate goal is not directly concerned with paginationorcaching.

Global.asax:
The Global.asax file, also known as the ASP.NET application file, is an optional file that contains code for responding to application-level and session-level events raised by ASP.NET or by HTTP modules. The Global.asax file resides in the root directory of an ASP.NET application. At run time, Global.asax is parsed and compiled into a dynamically generated .NET Framework class derived from the HttpApplication base class. ASP.NET is configured so that any direct URL request for the Global.asax file is automatically rejected; external users cannot download or view the code in it.The Global.asax file is optional. You create it only if you want to handle application or session events. In This Section: Application Directives Tags that define optional application-specific settings used by the ASP.NET parser when processing the Global.asax file. Code Declaration Blocks

Page 116

ASP.NET MATERIAL
Tags that define sections of server-side code that can be embedded in the Global.asax file. Code Render Blocks Tags that define inline code or expressions that can be embedded within the declarative sections of the Global.asax file. Server-Side Object Tag Syntax Elements that create application and session variables using a declarative syntax. Server-Side Include Directive Syntax Tags with a syntax for specifying server-side includes of text files within ASP.NET application files.

Page 117

ASP.NET MATERIAL

XML
XML:
Please note that the descriptions given below are simplified and only meant to give an impression of XML. They leave out a lot of the standards and are (for reasons of readability) a little inaccurate. If you want more detailed and accurate information you should go on to read the appendices below. Also note that these standards are not finalized yet, so that they may change before they're officially accepted. As a first introduction, however, this document should be useful.

XML itself:
There already exists a standard for defining markup languages like HTML, which is called SGML. HTML is actually defined in SGML. SGML could have been used as this new standard, and browsers could have been extended with SGML parsers. However, SGML is quite complex to implement and contains a lot of features that are very rarely used. Its support for different character sets is also a bit weak, which is something that can cause problems on the web where people use many different kinds of computers and languages. It's also difficult to interpret an SGML document without having the definition of the markup language (the DTD) available. Because of this, the XWG decided to develop a simplified version of SGML, which they called XML. (As they like to say, XML is more like SGML light, than HTML++.) The main point of XML is that you, by defining your own markup language, can encode the information of your documents much more precisely than is possible with HTML. This means that programs processing these documents can "understand" them much better and therefore process the information in ways that are impossible with HTML (or ordinary text processor documents). Imagine that you marked up recipes (for, say, soups and sea food dishes etc) according to a DTD tailored for recipes where you entered the amounts of each ingredient and alternatives for some ingredients. You could then easily make a program that, given a list of the contents of your fridge, would go through the entire list of recipes and make a list of the dishes you could make with them. Given nutritional information about the ingredients (x calories per ounce of this, y calories per once of that etc) the program could sort the suggestions by the amount of calories in each dish. Or by how long they'd take to prepare, or the price (given price information for the ingredients), or... The possibilites are almost endless, because the information is encoded in a way that the computer can "understand".

Page 118

ASP.NET MATERIAL
Defining your own markup language with XML is actually surprisingly simple. If you wanted to make a markup language for FAQs you might want it to be used like this: (note that this example is really too simple to be very useful)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE FAQ SYSTEM "FAQ.DTD"> <FAQ> <INFO> <SUBJECT> XML </SUBJECT> <AUTHOR> Lars Marius Garshol</AUTHOR> <EMAIL> larsga@ifi.uio.no </EMAIL> <VERSION> 1.0 </VERSION> <DATE> 20.jun.97 </DATE> </INFO> <PART NO="1"> <Q NO="1"> <QTEXT>What is XML?</QTEXT> <A>SGML light.</A> </Q> <Q NO="2"> <QTEXT>What can I use it for?</QTEXT> <A>Anything.</A> </Q> </PART> </FAQ>

In XML, the markup language shown above (let's call it FAQML) had a DTD like this:
<!ELEMENT FAQ <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT INFO SUBJECT AUTHOR EMAIL VERSION DATE (INFO, PART+)> (SUBJECT, AUTHOR, EMAIL?, VERSION?, DATE?)> (#PCDATA)> (#PCDATA)> (#PCDATA)> (#PCDATA)> (#PCDATA)> (Q+)> (QTEXT, A)> (#PCDATA)> (#PCDATA)> NO CDATA #IMPLIED TITLE CDATA #IMPLIED> NO CDATA #IMPLIED>

<!ELEMENT PART <!ELEMENT Q <!ELEMENT QTEXT <!ELEMENT A <!ATTLIST PART <!ATTLIST Q

Page 119

ASP.NET MATERIAL
is used to define elements like this: <!ELEMENT NAME CONTENTS>. NAME gives the name of the element, and CONTENTS describes which elements that are allowed where inside the element we've defined. A,B means that you must have an A first, followed by a B. ? after an element means that it can be skipped, + means that it must be included one or more times and * means that it can be skipped or included one or more times. #PCDATA means ordinary text without markup (more or less).
<!ELEMENT>

An important difference between XML and SMGL is that elements in XML which do not have any contents (like IMG and BR of HTML) are written like this in XML: <IMG SRC="pamela.gif"/>. Note the slash before the final >. This means that a program can read the document without knowing the DTD (which is where it says that IMG does not have any contents) and still know that IMG does not have an end tag and that what comes after IMG is not inside the element. defines the attributes of an element. In the DTD given above it's used to give PART and Q an attribute called NO, which contains ordinary text and which can be skipped. As you can see, PART has two attributes, and the last one is called TITLE, contains text and can be skipped.
<!ATTLIST>

Linking in XML:
HyTime is a standard for adding linking attributes and elements to SGML DTDs. It is far more advanced than what's possible with HTML and contains a lot of stuff not useful on the web. The XWG is therefore currently making a similar standard for XML which borrows a lot from HyTime (and similar standards) and simplifies it. To make it possible to use this linking standard in any DTD (regardless of which elements the DTD has) there aren't defined any particular elements for linking. Instead, linking elements use special attributes that identify them as linking elements. All elements that have an attribute called XML-LINK will be considered linking. The value of XML-LINK specifies what kind of link the element specifies. XML links can be between two or more resources, and resources can be either files (and not necessarily XML or HTML files) or elements in files. Links can be specified with the ACTUATE-attribute to be followed either (if the value is USER) when the user explicitly requests this (for instance by clicking) or (value AUTO) automatically (ie: when the system reads the linking element). What happens when you follow the link is specified with SHOW, which can take the following values: EMBED This means that the resource the link points to is to be inserted into the document the link comes from. This will happen either during the displaying of the

Page 120

ASP.NET MATERIAL
document or during processing of the document. This can be useful for including text from other files (with ACTUATE=AUTO) or to include a picture in a page. It can also be used to insert footnotes into the text and ACTUATE will then specify if the user has to click on the footnotes to include them or whether all footnotes will be inserted automatically. REPLACE This means that the resource the link points to is to replace the linking element. If you have two different versions of a paragraph you can link them in such a way that one can see the other version in the same context by following the link. NEW In this case, following the link will not affect the resource the link came from. Instead, the linked resource will be processed/displayed in a new context. Ordinary HTML links are of type NEW, as the new page is displayed in place of the previous one. XML is even more advanced than this. Links can be between more than one resource, they can be specified outside the actual documents themselves and the linked-to element inside a resource can be specified in very powerful ways. The element can be identified with an ID-attribute, position in the element structure and one can even specify that the link goes to things like "fourth LI inside the first UL inside BODY". In FAQML this could have been used both for specifying links to relevant information outside the FAQ as well as specifying internal relationships between different answers. It could also have been used for footnotes etc.

XML and layout:


There is actually already an SGML standard for this as well, and it's called DSSSL, and isn't very simple, either. The XWG has therefore decided to make a simplified version of DSSSL as well and call it XSL. So far, not much has been done about this. One proposal (see references) has been submitted, but it hasn't been accepted yet, and it's uncertain if it will be. So, I'm going to describe DSSSL instead of XSL, at least until the future shape of XSL becomes clearer. DSSSL is actually a full programming language, based on Scheme (a LISP dialect), and is very powerful. It can be used both as a stylesheet specifying fonts and positioning for the different elements and as a transformational language that can be used to transform documents from one DTD to another. The most common use of DSSSL is to convert SGML documents to other formats better suited for presentation, like PDF (also known as Acrobat), PostScript, LaTeX, HTML or RTF. What the XWG is planning is to use XSL to specify how XML documents are to be displayed on screen.

Page 121

ASP.NET MATERIAL
Below I try to show how we could make a stylesheet for FAQML, but without explaining very much of what really happens. I've split the DSSSL file into several parts in order to be able to comment it as it's written, but it is meant to be a single file. DSSSL consists of several different parts, and the most basic one is the expression language which is quite simply a subset of Scheme. This means that DSSSL-stylesheets are really one large Scheme expression that is calculated by the DSSSL engine, with a file as the result of the calculation. Another important part (which is built on the expression language) is the style language, which I've used almost exclusively in this example. A third part is the query language, which can be used to find any element you want in your document. I've used it in this example to find the number of a FAQ question from inside the QTEXT element. This was necessary because NO is an attribute of the surrounding Q element, and not QTEXT itself. All formatting in DSSSL is done with so-called flow objects. In the code below you'll se a lot of (element X (make Y-expressions which indicate that when element X shows up the DSSSL engine is to create a flow object of type Y. Then style rules for Y and then the contents of Y are specified. There's much more to DSSSL than this, but the rest is considered to be outside the scope of this document.
<!doctype style-sheet Sheet//EN"> PUBLIC "-//James Clark//DTD DSSSL Style

;--- DSSSL stylesheet for FAQML ;---Constants (define *font-size* (define *font* 12pt) "Times New Roman")

The first line tells the SGML parser that this document follows the DTD for DSSSL. (Yes, DSSSL is an SGML application.) The next two lines are comments (after ; the rest of the line is ignored). Then I define two constants that I use below in the styles themselves. This is done to make it easy to change the font size of the entire document without having to adjust sizes for all kinds of headers etc. Instead, I just change the value of *font-size*.
;---Element styles (element FAQ (make simple-page-sequence font-family-name: *font* font-size: *font-size* input-whitespace-treatment: 'collapse line-spacing: (* *font-size* 1.2)

Page 122

ASP.NET MATERIAL
(process-children)))

This part creates a flow object for the FAQ element, ie: the whole document. The flow object is "simple-page-sequence", which I assume is meant for small articles. I then specify what font to use, font size, that whitespace is to be considered insignificant (like in HTML) and then I give the line height. The line height is set to be 1.2 times the font size.
(element INFO (make paragraph quadding: space-after: (process-children)))

'center (* *font-size* 1.5)

This indicates that the element INFO (from start-tag to end-tag) is to be laid out as a paragraph that is centered and has a blank space as high as 1.5 lines after it. After creating the paragraph flow object the DSSSL engine is to go on to process the child elements of INFO.
(element SUBJECT (make paragraph font-size: line-spacing: space-after: (process-children)))

(* *font-size* 2) (* *font-size* 2) (* *font-size* 2)

The subject element gets its own paragraph and is displayed in double font size. AUTHOR and EMAIL are simpler versions of this, so I skip them. (You can find them in the complete DSSSL file linked to below.)
(element VERSION (make paragraph (make sequence (literal "Version: ")) (process-children)))

The VERSION element is given its own paragraph, which contains sequence flow objects. I insert one containing the text "Version: " before the actual contents of VERSION are processed. This means that the text "Version: " will be inserted in front of the actual version number. DATE is similar, so I skip that.
(element PART (make paragraph font-size:

(* *font-size* 1.5)

Page 123

ASP.NET MATERIAL
line-spacing: (* *font-size* 2) (make sequence (literal (attribute-string "NO" (current-node))) (literal ". ") (literal (attribute-string "TITLE" (current-node))) ) (process-children)))

I wanted PART to have a large font size and contain both number and title. We've already seen how to do this with sequence, but the problem of getting hold of the number and title is new. They are only given as attributes, and thus will be ignored by (processchildren). The function attribute-string gives us what we want. (Attribute-string "NO" (current-node)) returns the value of the attribute NO in the current element. The rest of this style sheet is so simple that I'll just skip it without comments. In case anyone's interested, they can find the entire DSSSL file here, together with the results in RTF and PostScript formats. The RTF file is produced by Jade (see reference 12) and the Postscript file is produced from this. Note that the RTF and Postscript files are from the Norwegian version. This should make no difference, though.

Creation of XML Document

There are two ways to create an XML document. One way is to create an XmlDocument with no parameters. The other way is to create an XmlDocument and pass it an XmlNameTable as a parameter. The following example shows how to create a new, empty XmlDocument using no parameters.
XmlDocument doc = new XmlDocument();

Once a document is created, you can load it with data from a string, stream, URL, text reader, or an XmlReader derived class using the Load method. There is also another load method, the LoadXML method, which reads XML from a string. For more information on the various Load methods, see Reading an XML Document into the DOM. There is a class called the XmlNameTable. This class is a table of atomized string objects. This table provides an efficient means for the XML parser to use the same string object for all repeated element and attribute names in an XML document. An XmlNameTable is automatically created when a document is created as shown above and is loaded with attribute and element names when the document is loaded. If you already have a document with a name table, and those names would be useful in another

Page 124

ASP.NET MATERIAL
document, you can create a new document using the Load method that takes an XmlNameTable as a parameter. When the document is created with this method, it uses the existing XmlNameTable with all the attributes and elements already loaded into it from the other document. It can be used for efficiently comparing element and attribute names. For more information on the XmlNameTable.

XML Parsers:

This article lists the version numbers of Microsoft XML Core Services or the Microsoft XML parser (MSXML). Different versions of MSXML are included with various Microsoft products, such as Microsoft Windows, Microsoft Internet Explorer, Microsoft Office, and Microsoft SQL Server. MSXML is also updated when you install software updates for various Microsoft products. Microsoft provides several different XML parsers. The System.xml parser and the System.XML.XmlReader XML parser are included with the Microsoft .NET Framework 2.0. The MSXML parser is included in the Msxml.dll file, the Msxml2.dll file, the Msxml3.dll file, the Msxml4.dll file, the Msxml5.dll file, the Msxml6.dll file, and one or more resource files. Notice that Windows HTTP Services (Winhttp*.dll) is also included withsomeversionsofmsxml. The Microsoft XML parser is a Component Object Model (COM) implementation of the W3C DOM model. Two versions are associated with each parser: the release version of the MSXML parser and the actual file version of the DLL that contains the parser. The release version of the MSXML parser (for example, versions 2.5, 2.6, 3.0, 4.0, 5.0, and 6.0) identifies the milestone of development.

MSXML versions 1.x and 2.x are no longer supported by Microsoft. MSXML 3.0 is supported by Microsoft only if you are running Service Pack 5 (SP5) or a later service pack. MSXML 4.0 is supported by Microsoft only if you are running Service Pack 2 (SP2). MSXML 5.0 and MSXML 6.0 are supported by Microsoft. This table includes the version of MSXML that is included in security updates that were released on October 10, 2006 (MS06-061), on November 14, 2006 (MS06-071), and on August 14, 2007 (MS07-042). For more information about the security updates, click the following article numbers to view the articles in the Microsoft Knowledge Base:

Page 125

ASP.NET MATERIAL

After you install the security update that is described in Microsoft security bulletin MS06-061, you cannot use MSXML 2.6 in Internet Explorer. This behavior is by design. The security update packages set the "kill bit" for MSXML 2.6. The "kill bit" prevents MSXML 2.6 from running in Internet Explorer. 32-bit versions of MSXML (Wmsxml*.dll.) on 64-bit versions of Windows use the same MSXML and file version numbers that are listed in this table. If MSXML 4.0 is installed on a computer that is running Microsoft Windows 98 or Windows Millennium Edition, the Msxml4a.dll file is installed. If the parser is installed on a computer that is running Windows NT, Windows 2000, or Windows XP, the WinHTT5.dll file is installed.

DOM VS SAX Parsers

DOM parsers and SAX parsers work in different ways:

A DOM parser creates a tree structure in memory from the input document and then waits for requests from client. But a SAX parser does not create any internal structure. Instead, it takes the occurrences of components of a input document as events, and tells the client what it reads as it reads through the input document. A DOM parser always serves the client application with the entire document no matter how much is actually needed by the client. But a SAX parser serves the client application always only with pieces of the document at any given time. With DOM parser, method calls in client application have to be explicit and forms a kind of chain. But with SAX, some certain methods (usually overriden by the cient) will be invoked automatically (implicitly) in a way which is called "callback" when some certain events occur. These methods do not have to be called explicitly by the client, though we could call them explicitly.

In the following cases, using SAX parser is advantageous than using DOM parser.

The input document is too big for available memory (actually in this case SAX is your only choice) You can process the document in small contiguous chunks of input. You do not need the entire document before you can do useful work You just want to use the parser to extract the information of interest, and all your computation will be completely based on the data structures created by yourself. Actually in most of our applications, we create data structures of our own which are usually not as complicated as the DOM tree. From this sense, I think, the chance of using a DOM parser is less than that of using a SAX parser.

Page 126

ASP.NET MATERIAL
In the following cases, using DOM parser is advantageous than using SAX parser.

Your application needs to access widely separately parts of the document at the same time. Your application may probably use a internal data structure which is almost as complicated as the document itself. Your application has to modify the document repeatedly. Your application has to store the document for a significant amount of time through many method calls.

Using Dom Parser and Using Sax Parser: Example: Assume that an instructor has an XML document containing all the personal information of the students as well as the points his students made in his class, and he is now assigning final grades for the students using an application. What he wants to produce is a list with the SSN and the grades. Also we assume that in his application, the instructor use no data structure such as arrays to store the student personal information. If the instructor decides to give A's to those who earned the class average or above, and give B's to the others, then he'd better to use a DOM parser in his application. The reason is that he has no way to know how much is the class average before the entire document gets processed. What he probably need to do in his application, is first to look through all the students' points and compute the average, and then look through the document again and assign the final grade to each student by comparing the points he earned to the class average. If, however, the instructor adopts such a grading policy that the students who got 90 points or more, are assigned A's and the others are assigned B's, then probably he'd better use a SAX parser. The reason is, to assign each student a final grade, he do not need to wait for the entire document to be processed. He could immediately assign a grade to a student once the SAX parser reads the grade of this student. In the above analysis, we assumed that the instructor created no data structure of his own. What if he creates his own data structure, such as an array of strings to store the SSN and an array of integers to sto re the points ? In this case, I think SAX is a better choice, before this could save both memory and time as well, yet get the job done. Well, one more consideration on this example. What if what the instructor wants to do is not to print a list, but to save the original document back with the grade of each student updated ? In this case, a DOM parser should be a better choice no matter what grading policy he is adopting. He does not need to create any data structure of his own. What he

Page 127

ASP.NET MATERIAL
needs to do is to first modify the DOM tree (i.e., set value to the 'grade' node) and then save the whole modified tree. If he choose to use a SAX parser instead of a DOM parser, then in this case he has to create a data structure which is almost as complicated as a DOM tree before he could get the job done.

Developing Client App for XML: Introduction:


XML technology is in its high tide and companies are enthusiastic to leverage its power and flexibility. Presentation tier technology based on XML is also gaining momentum in this wave. Database vendors have been providing implicit support for XML in their DB products for quite some time. IBM offers XML support with DB2 Express-C software that is free in all aspects: free for development, production, and even distribution. OpenLaszlo has come up with an XML-based scripting framework that is worth notice due to its visual appeal, flexibility, and efficiency. The foundation block is XML and they form a buddy pair unlike any other. In this article, we shall develop an addressbook application end-to-end using OpenLaszlo, DB2 and Java. The functionality is simple but should be able to demonstrate the integration of technologies discussed above. This is a sequel to Introducing OpenLaszlo, which provided a quick-start on setting up a development environment with Ant and IDE4Laszlo. We will build on this application using the development environment discussed therein.

Download the Required Software:


The following software is required in addition to the development environment to try out the address book application: 1. Download and install DB2 Express-C. This is free for download, development, and production. You can learn more about IBM XML database there too. 2. Download the source code for the entire application.

Install Software:
Install DB2 Express-C by following the instructions in the installation program.

Create the Database adbookdb:


1. Since this is an XML database, the structure of the table is very simple with just two columns (see Figure 1).

Page 128

ASP.NET MATERIAL

Figure 1. The structure of the adbookdb. 2. Go to Windows Start >> Programs >> IBM DB2 >> and DB2 Command Editor. Alternatively, you can right-click the DB icon in the windows notification area and start(DB2) or launch Command Editor (see Figure 2).

Figure 2. The DB2 Community Edition quick launch 3. Run the scripts in the following listing to set up the database.

Listing 1.
CREATE DATABASE ADBOOKDB USING CODESET UTF-8 TERRITORY US~ CONNECT TO ADBOOKDB user db2admin using 'db2admin'~ CREATE SCHEMA DB2ADMIN AUTHORIZATION DB2ADMIN~ CREATE TABLE DB2ADMIN.ADDRESSBOOK (EMAILID NULL PRIMARY KEY, CONTACTINFO XML) ~ CHARACTER (50) NOT

The above file contains scripts that will insert 10 records into the database. A person's email ID is the primary key from which the subsequent XML string is inserted into the database. The entire contact information of the person goes as elements of a single XML string. The code below is an example of the insert script: note that to give a one-to-one correspondence to the XML and the primary key, the email ID is maintained as an attribute to the <person> element.
insert into db2admin.addressbook ('grace.thomas@yahoo.com',' <person email="grace.thomas@yahoo.com"> <firstname>Grace</firstname> <lastname>Thomas</lastname> <phone>9947267690</phone> values

Page 129

ASP.NET MATERIAL
<housename>Grace Villa</housename> <street>III Cross</street> <city>Pattom</city> </person>')~

4. To ensure that data is properly inserted, run the following command from the DB2 Command Editor. DB2 provides excellent views of the XML column in two formats: tree view and source view (see Figures 3 and 4). SELECT * FROM DB2ADMIN.ADDRESSBOOK~

Figure 3. Tree view of the XML field in DB2 XML document viewer.

Page 130

ASP.NET MATERIAL

Application Flow:
The addressbook application is no different from any other application offering the functionality. In fact, it will have only limited features, including: 1. Adding contact information to the addressbook database 2. Listing the contacts already in the database 3. Updating information. All other functionality that could be added to is left to the imagination of the reader. The addressbook application substitutes a simple JSP in place of a full-fledged application. This is possible since DB2 Express-C database supports XQuery functions that can return data in well-formed XML structures. In a production scenario, this JSP

Page 131

ASP.NET MATERIAL
would be replaced by an application framework to implement transaction handling and business logic. The application code could be built up using any technology since the presentation layer attains the theoretical 100 percent separation from the application layer and data transfer is achieved using XML. With OpenLaszlo, presentation needs to be handled differently from the conventional web application since there is no page transition. The data is sent to the web application to be persisted and at the same time the user interface is updated to reflect the changes. However, this poses two challenges: 1. If the data update is reflected in the GUI in parallel to the application call persisting data, how do we ensure that the data is properly added to the persistence mechanism? What if there is a validation error or an exception that needs to be communicated to the user? One way to solve this would be to refresh the data at the client as soon as a change is made to the database. In this case, the information that is already present at the client will be downloaded once again, which would be inefficient. 2. Refreshing the entire set of records by fetching it once again could also be a cause for poor response time. We would also miss out on the power of Ajax, which has the power to execute activities asynchronously. Ultimately, we are left with but one choice: update the client GUI immediately on a confirmation from the application layer. Only the set of changed data would be updated. All the other information is present in the component cache. This way, it would simulate a desktop application in its quick response time. OpenLaszlo's data caching mechanism and the OpenLaszlo API facilitates this function (see Figure 5).

Page 132

ASP.NET MATERIAL

Figure 5. Flow of the Addressbook application.

Running the Application:


1. Extract the addressbook.zip that comes with this article and copy the files to their locations (see Figure 6).

Page 133

ASP.NET MATERIAL

Figure 6. Addressbook application workspace in Eclipse. 2. Copy the db2jcc.jar and db2jcc_license_cu.jar to the web-inf/lib folder of your web application. These JARs are required for the application to connect to the database. Look in the SQLLIB\java directory under your DB2 installation directory for these JAR files. 3. Deploy the OpenLaszlo and the Java web application by executing the Ant target deploy-all. This will deploy the OpenLaszlo application to the LPServer and the .war to the default Tomcat 5.0 server. 4. Start DB2. 5. Start the OpenLaszlo Presentation Server. 6. Enter the URL http://localhost:8080/lps-3.2/laszlotutorial/addressbook.lzx in the browser and hit enter. Figure 7 is a screen shot of the main page.

Page 134

ASP.NET MATERIAL

Figure 7. Addressbook application.

Application Functionality
The navigation of the application is intuitive. 1. Clicking the Add New Contact will lead to a screen to add a person's contact information. The email ID is the only mandatory field. All other information can be updated by returning to the screen anytime (see Figure 8).

Page 135

ASP.NET MATERIAL

Figure 8. Adding new contact screen. 2. Clicking the List all contacts will list all contacts in the database with basic information in a scrollable table (see Figure 9).

Page 136

ASP.NET MATERIAL

Figure 9. Listing all the contacts in the database. 3. Double-clicking the email ID of a person will pop-up the update screen with information currently available in the database (see Figure 10).

Page 137

ASP.NET MATERIAL

Figure 10. View or update an existing contact. 4. Pressing the Update button from this screen will result in an application call to update the record in the database. Exceptions in the web application layer or any errors in validation can be communicated to the client through a custom XML in the HttpResponse. If you list the contacts in the database with the database stopped, you will get the screen in Figure 11. This could be easily customized to send informative messages to the user.

Page 138

ASP.NET MATERIAL

Figure 11. Displaying exceptions to the user. The following are the .lzx classes that are used in the application: 1. addressbook.lzx: Declares the canvas on which the entire user interface is built. 2. contactdetails.lzx: This class generates the screen to show the detailed information of a contact. From here, the user can also update information on a contact. 3. newcontact.lzx<: This is the aggregation of the screen information for a new contact. 4. datasets.lzx: This class only serves to group the datasets into one file. The file is included in the addressbook.lzx and helps to avoid clutter. 5. xmlfetcher.jsp: This JSP file represents the application layer in the current setup. In a production scenario, this would be replaced by a framework that would include the business logic and necessary framework to handle transactions, validations etc. 6. ringingphone.gif: A small graphic to add some spice to the application. The structure of the GUI is just three views that are hidden initially but made visible when selecting the relevant option. This view is always visible.

Page 139

ASP.NET MATERIAL

XML Schema:

An XML Schema describes the structure of an XML document. In this tutorial you will learn how to create XML Schemas, why XML Schemas are more powerful than DTDs, and how to use XML Schema in your application. XML Schema is an XML-based alternative to DTD. An XML schema describes the structure of an XML document. The XML Schema language is also referred to as XML Schema Definition (XSD).

What You Should Already Know:


Before you continue you should have a basic understanding of the following:

HTML / XHTML XML and XML Namespaces A basic understanding of DTD

What is an XML Schema?


The purpose of an XML Schema is to define the legal building blocks of an XML document, just like a DTD. An XML Schema:

defines elements that can appear in a document defines attributes that can appear in a document defines which elements are child elements defines the order of child elements defines the number of child elements defines whether an element is empty or can include text defines data types for elements and attributes defines default and fixed values for elements and attributes

XML Schemas are the Successors of DTDs:


We think that very soon XML Schemas will be used in most Web applications as a replacement for DTDs. Here are some reasons:

Page 140

ASP.NET MATERIAL

XML Schemas are extensible to future additions. XML Schemas are richer and more powerful than DTDs. XML Schemas are written in XML. XML Schemas support data types. XML Schemas support namespaces.

XML Schema Example:


<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="note"> <xs:complexType> <xs:sequence> <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading" type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>

Dataset Serialization and Deserialization

This article provides a roadmap to learn and to master serialization and deserialization of XML with the .NET Framework (System.Xml namespace). Roadmap articles provide links to useful information, including online documentation, Microsoft Knowledge Base articles, and Microsoft white papers, to help you learn about a Microsoft product or technology. Microsoft Knowledge Base How To articles and walkthroughs provide step-by-step instructions to complete specific tasks. Quick Start sample files are ready-made programs that illustrate a technique.

Page 141

ASP.NET MATERIAL
Overview:
Serialization is the process of converting an object into a form that can be easily transported. For example, you can serialize an object and transport it over the Internet by using HTTP between a client and a server. On the other end, deserialization reconstructs theobjectfromthestream. The .NET Framework features two serializing technologies:

Binary serialization preserves type fidelity, which is useful for preserving the state of an object between different invocations of an application. For example, you can share an object between different applications by serializing it to the clipboard. For example, you can serialize an object to a stream, to a disk, to memory, or over the network. Remoting uses serialization to pass objects "by value" from one computer or application domain to another. XML serialization serializes only the public fields and property values of an object into an XML stream. XML serialization does not include type information. For example, if you have a Book object that exists in the Library namespace, there is no guarantee that it will be deserialized into an object of the same type.

It is important to understand the difference between these two technologies. XML serialization does not convert methods, indexers, private fields, or read-only properties (except read-only collections). To serialize all of the public and private fields and properties of an object, use the BinaryFormatter instead of XML serialization.

XML Serialization Architecture:


The System.Xml.Serialization namespace contains the classes that are used to serialize objects into XML format documents or streams. The central class in the namespace is the XmlSerializer class. To use this class, use the constructor of the XmlSerializer to create an instance of the class by using the Type of the object to serialize. After an XmlSerializer is created, create an instance of the object to serialize. You must also create an object to write the file to a document or stream, such as a Stream, a TextWriter, or an XmlWriter. You can then call the Serialize method to convert the object to an XML document. To deserialize an object from an XML document, create a suitable object to read the document or stream (again a Stream, a TextWriter, or an XmlWriter). Invoke the Deserialize method while casting the resulting object to the Type of the original object that was serialized.

Page 142

ASP.NET MATERIAL
To control the serialization more, the System.Xml.Serialization namespace provides several Attribute classes that can be applied to members of a class. For example, if a class contains a member that will be serialized as an XML element, you can apply the XmlElementAttribute attribute to the member. When applying the attribute, you can specify details such as the actual XML element name by using the ElementName property.

DataSet Serialization in ADO.NET 2.0


When you upgrade to ADO.NET 2.0, your problems will be solved. In ADO.NET 2.0, the DataSet class provides a new serialization option specifically designed to optimize remoting serialization. As a result, remoting a DataSet uses less memory and bandwidth. The end-to-end latency is greatly improved illustrates. In ADO.NET 2.0, the DataSet and DataTable come with a new property named RemotingFormat defined to be of type SerializationFormat. By default, the new property is set to SerializationFormat.Xml to preserve backward compatibility. The property affects the behavior of the GetObjectData members on the ISerializable interface and ultimately is a way to control the serialization of the DataSet. The following code snippet represents the pseudocode of the method in ADO.NET 2.0: void GetObjectData(SerializationInfo info, StreamingContext context) { SerializationFormat fmt = RemotingFormat; SerializeDataSet(info, context, fmt); } SerializeDataSet is a helper function that fills the SerializationInfo memory buffer with data that represents the DataSet. If the format parameter is SerializationFormat.Binary, the function goes through every object in the DataSet and copies its contents into a serializable structuremostly ArrayLists and Hashtables. the pseudocode. If you compare that to the code in the aforementioned Knowledge Base article 829740, you'll find many similarities. Note, though, that the code is based on Beta 1 and might change in the future. What shouldn't change, though, is the idea behind the binary serialization. To serialize a DataSet in a true binary fashion, here's what you do: DataSet ds = GetData(); ds.RemotingFormat = SerializationFormat.Binary; BinaryFormatter bin = new BinaryFormatter(); bin.Serialize(stream, ds); Aside from the new RemotingFormat property, there's nothing new in this code. The impact of this new feature on existing code is very minimal.

Page 143

ASP.NET MATERIAL
Pseudocode for DataSet's Binary Serialization private void SerializeDataSet( SerializationInfo info, StreamingContext context, SerializationFormat remotingFormat) { info.AddValue("DataSet.RemotingVersion", new Version(2, 0)); if (remotingFormat != SerializationFormat.Xml) { int i; info.AddValue("DataSet.RemotingFormat", remotingFormat); SerializeDataSetProperties(info, context); info.AddValue("DataSet.Tables.Count", this.Tables.Count); for (i=0; i< Tables.Count; i++) Tables[i].SerializeConstraints(info, context, i, true); SerializeRelations(info, context); for (i=0; i< Tables.Count; i++) Tables[i].SerializeExpressionColumns(info, context, i); for (int=0; i< Tables.Count; i++) Tables[i].SerializeTableData(info, context, i); return; } // 1.x code } SerializationFormat Values Value Description Xml Maintained for backward compatibility, serializes the DataSet object using an XML DiffGram format as in ADO.NET 1.x; this is the default value of the RemotingFormat property Binary Instructs the internal serializer to use a true binary format when serializing the DataSet

Page 144

ASP.NET MATERIAL
It is interesting to measure the performance gain that you get from this new feature. Here's a simple technique you can easily reproduce. Fill a DataSet with the results of a query and persist it to a file on disk. You can wrap the code in in either a Web Form or a Windows Form. Run the sample application and take a look at the size of the files created. Try first with a simple query like this: SELECT lastname, firstname FROM employees Testing Performance of Remoting Format SqlDataAdapter adapter = new SqlDataAdapter(query, connString);DataSet ds = new DataSet(); adapter.Fill(ds); BinaryFormatter bin = new BinaryFormatter(); // Save as XMLusing(StreamWriter writer1 = new StreamWriter(@"c:\xml.dat")) { bin.Serialize(writer1.BaseStream, ds); } // Save as binaryusing(StreamWriter writer2 = new StreamWriter(@"c:\bin.dat")) { ds.RemotingFormat = SerializationFormat.Binary; bin.Serialize(writer2.BaseStream, ds); } If you're familiar with the Northwind database, you know that this query returns only nine records. Quite surprisingly, in this case the XML DiffGram is about half the size of the binary file! Don't worry, there's nothing wrong in the code or in the underlying technology.

Page 145

ASP.NET MATERIAL

CACHING

Importance of Caching:

Caching is a technique widely used in computing to increase performance by keeping frequently accessed or expensive data in memory. In the context of a Web application, caching is used to retain pages or data across HTTP requests and reuse them without the expense of recreating them. ASP.NET has several kinds of caching that can be used by Web applications: Output caching is useful when the contents of an entire page can be cached. On a heavily accessed site, caching frequently accessed pages for even a Output minute at a time can result in substantial throughput gains. While a page is Caching cached by the output cache, subsequent requests for that page are served from the output page without executing the code that created it. Sometimes it is not practical to cache an entire page - perhaps portions of the page must be created or customized for each request. In this case, it is Fragment often worthwhile to identify objects or data that are expensive to construct Caching and are eligible for caching. Once these items are identified, they can be created once and then cached for some period of time. Additionally, fragment caching can be used to cache regions of a page's output. Choosing the time to cache an item can be an interesting decision. For some items, the data might be refreshed at regular intervals or the data is valid for a certain amount of time. In that case, the cache items can be given an expiration policy that causes them to be removed from the cache when they have expired. Code that accesses the cache item simply checks Data Caching for the absence of the item and recreates it, if necessary. The ASP.NET cache supports file and cache key dependencies, allowing developers to make a cache item dependent on an external file or another cache item. This technique can be used to invalidate items when their underlying data source changes. ASP.Net 2.0 includes some new features to help with cache configuration. Cache profiles enable you to configure cache profiles in the configuration Cache system, and then use those profiles on pages. This enables changes to Configuration caching for sets of pages to be made on a global basis. More options for customizing the cache performance have also been added.

Asp3.0 Support Caching:

Page 146

ASP.NET MATERIAL
Server-side caching:
ASP.NET offers a "Cache" object that is shared across the application and can also be used to store various objects. The "Cache" object holds the data only for a specified amount of time and is automatically cleaned after the session time-limit elapses.

Types of caching in Asp.net:

LoadControl and Output Caching: Rare is the ASP.NET application that doesnt employ user controls. Before the advent of Master Pages, developers employed user controls to factor out common content, such as headers and footers. Even in ASP.NET 2.0, user controls provide an effective means for encapsulating content and behavior, and for dividing pages into regions whose ability to be cached can be controlled independently of the page as a wholea special form of output caching known as fragment caching. User controls can be loaded declaratively or imperatively. Imperative loading relies on Page.LoadControl, which instantiates a user control and returns a Control reference. If the user control contains custom type members (for example, public properties), then you can cast that reference and access the custom members from your code. The user control in Figure 1 implements a property named BackColor. The following code loads the user control and assigns a value to BackColor:
protected void Page_Load(object sender, EventArgs e) { // Load the user control and add it to the page Control control = LoadControl("~/MyUserControl.ascx"); PlaceHolder1.Controls.Add(control); // Set its background color ((MyUserControl)control).BackColor = Color.Yellow; }

This code, simple as it is, is a trap waiting to ensnare the unwary developer. Can you identify the flaw? Figure 1 MyUserControl MyUserControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyUserControl.ascx.cs" Inherits="MyUserControl" %> <h1><asp:Label ID="Label1" runat="server" Text="Label" /></h1>

MyUserControl.ascx.cs

Page 147

ASP.NET MATERIAL
using using using using using System; System.Web; System.Web.UI; System.Web.UI.WebControls; System.Drawing;

public partial class MyUserControl : System.Web.UI.UserControl { public Color BackColor { get { return Label1.BackColor; } set { Label1.BackColor = value; } } protected void Page_Load(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToLongTimeString(); } }

If you guessed that the problem is related to output caching, you are correct. These code samples compile and run fine as shown, but try adding the following (perfectly legal) statement to MyUserControl.ascx:
<%@ OutputCache Duration="5" VaryByParam="None" %>

Next time you run the page, youll be greeted by an InvalidCastException (oh joy!) accompanied by the following error message:
"Unable to cast object of type System.Web.UI.PartialCachingControl to type MyUserControl."

So, heres code that works great without an OutputCache directive, but bombs when an OutputCache directive is added. ASP.NET isnt supposed to work this way. Pages (and controls) are supposed to be agnostic towards output caching. So what gives? The problem is that when output caching is enabled for a user control, LoadControl no longer returns a reference to an instance of the control; instead, it returns a reference to an instance of PartialCachingControl that might or might not wrap a control instance, depending on whether the controls output is cached. Consequently, developers who call LoadControl to load a user control dynamically and who also cast the control reference in order to access control-specific methods and properties must take care in how they do it in order for the code to work with or without an OutputCache directive. Figure 2 demonstrates the proper way to load user controls dynamically and cast the returned control references. Heres a synopsis of how it works:

Page 148

ASP.NET MATERIAL

If the ASCX file lacks an OutputCache directive, LoadControl returns a MyUserControl reference. Page_Load casts the reference to MyUserControl and sets the controls BackColor property. If the ASCX file includes an OutputCache directive and the controls output isnt cached, LoadControl returns a reference to a PartialCachingControl whose CachedControl property contains a reference to the underlying MyUserControl. Page_Load casts PartialCachingControl.CachedControl to MyUserControl and sets the controls BackColor property. If the ASCX file includes an OutputCache directive and the controls output is cached, LoadControl returns a reference to a PartialCachingControl whose CachedControl property is null. Seeing this, Page_Load does nothing more. Its powerless to set the controls BackColor property because the controls output is delivered from the output cache. In other words, there is no MyUserControl on which to set a property.

Figure 2 The Proper Way to Load MyUserControl.ascx


protected void Page_Load(object sender, EventArgs e) { // Load the user control Control control = LoadControl("~/MyUserControl.ascx"); PlaceHolder1.Controls.Add(control); // Set its background color (if possible) MyUserControl uc = control as MyUserControl; if (uc == null) { PartialCachingControl pcc = control as PartialCachingControl; if (pcc != null) uc = pcc.CachedControl as MyUserControl; } if (uc != null) uc.BackColor = Color.Yellow; }

The code in Figure 2 will work with or without an OutputCache directive in the .ascx file. Its not pretty, but it averts nasty surprises. Simpler doesnt always equate to more maintainable.

Sessions and Output Caching:


Speaking of output caching, theres a potential issue with ASP.NET 1.1 and ASP.NET 2.0 that affects output-cached pages on servers running on Windows Server 2003 and IIS 6.0. Ive personally seen this manifest itself on production ASP.NET servers twice, and both times it was resolved by turning off output caching. I later learned theres a better solution that doesnt require output caching to be disabled. Heres how I first encountered the problem.

Page 149

ASP.NET MATERIAL
The saga began when a dot-comlets call it Contoso.comthat runs a public ecommerce app on a small ASP.NET Web farm contacted my team and complained that they were experiencing "cross-threading" errors. Every now and then, a customer using the Contoso.com Web site would suddenly lose the data they had entered and instead would see data corresponding to another user. A bit of sleuthing revealed that crossthreading wasnt an accurate description; "cross-session" errors was more like it. It seems that Contoso.com was storing data in session state, and for some reason users were occasionallyand randomlybeing connected to other users sessions. One of my team members wrote a diagnostic tool to log key elements of each HTTP request and response, including cookie headers. Then he installed it on Contoso.coms Web servers and let it run for a few days. The results were remarkable. Roughly once in every 100,000 requests, ASP.NET was correctly assigning a session ID to a brand new session and returning the session ID in a Set-Cookie header. It would then return the same session ID (that is, the same Set-Cookie header) in the very next request, even if that request was already associated with a valid session and was correctly submitting the session ID in a cookie. In effect, ASP.NET was randomly switching users away from their own sessions and connecting them to other sessions. Astonished, we began to look for causes. We first examined Contoso.coms source code and satisfied ourselves that the problem lay elsewhere. Next, just to be sure the problem wasnt related to the fact that the application was hosted on a Web farm, we turned off all the servers but one. The problem persisted, which wasnt surprising since our logs showed that the matching Set-Cookie headers never came from two different servers. It wasnt credible that ASP.NET accidentally generated duplicate session IDs because it uses the .NET Framework RNGCryptoServiceProvider class to generate those IDs, and session IDs are of sufficient length to ensure that the same one will never be generated twice (not in the next trillion years, anyway). Besides, even if RNGCryptoServiceProvider was erroneously generating duplicate random numbers, that wouldnt explain why ASP.NET mysteriously replaced valid session IDs with new (and non-unique) ones. On a hunch, we decided to look at output caching. When OutputCacheModule caches HTTP responses, it must be careful not to cache Set-Cookie headers; otherwise, a cached response containing a new session ID would connect all recipients of the cached response (as well as the user whose request generated the cached response) to the same session. We checked the source code; Contoso.com had output caching enabled in two pages. We turned it off. Lo and behold, the application ran for days without a single cross-session incident. It has run without error for more than two years since. And we saw the exact same scenario play out at a different company with a different application and a different set of Web servers. As at Contoso.com, eliminating output caching made the problem go away. Microsoft has since confirmed that this behavior stems from a problem in OutputCacheModule. (There may be an update available by the time you read this.) When ASP.NET is paired with IIS 6.0 and kernel-mode caching is enabled, OutputCacheModule sometimes fails to strip Set-Cookie headers from the cached

Page 150

ASP.NET MATERIAL
responses it passes to Http.sys. Heres the specific sequence of events that causes the bug to manifest itself: 1. A user who hasnt visited the site recently (and therefore doesnt have a corresponding session) requests a page for which output caching is enabled, but whose output isnt currently available in the cache. 2. The request executes code that accesses the users newly created session, causing a session ID cookie to be returned in a Set-Cookie header in the response. 3. OutputCacheModule provides the output to Http.sys, but fails to strip the SetCookie header from the response. 4. Http.sys returns the cached response in subsequent requests, inadvertently connecting other users to the session. Session state and kernel-mode output caching dont mix. If you use session state in a page that has output caching enabled, and if the application runs on IIS 6.0, then you need to turn off kernel-mode output caching. Youll still get the benefit of output caching, but because kernel-mode output caching is substantially faster than ordinary output caching, the caching wont be as effective. You can turn off kernel-mode output caching for individual pages by including VaryByParam="*" attributes in the pages OutputCache directives, although doing so can cause memory requirements to explode. The safer alternative is to turn off kernel-mode caching for the entire application by including the following element in web.config:
<httpRuntime enableKernelOutputCache="false" />

You can also disable kernel-mode output caching globallythat is, for entire servers with a registry setting. Whenever I hear about inexplicable things happening with sessions, I ask the customer if theyre using output caching in any of their pages. If the answer is yes, and if the host OS is Windows Server 2003, then I advise them to disable kernel-mode output caching. The problem usually goes away. If it doesnt, then the bug is in their code. Be warned! Output Caching:

Output caching is a powerful technique that increases request/response throughput by caching the content generated from dynamic pages. Output caching is enabled by default, but output from any given response is not cached unless explicit action is taken to make the response cacheable. To make a response eligible for output caching, it must have a valid expiration/validation policy and public cache visibility. This can be done using either the low-level OutputCache API or the high-level @ OutputCache directive. When output caching is enabled, an output cache entry is created on the first GET request to the page.

Page 151

ASP.NET MATERIAL
Subsequent GET or HEAD requests are served from the output cache entry until the cached request expires. The output cache also supports variations of cached GET or POST name/value pairs. The output cache respects the expiration and validation policies for pages. If a page is in the output cache and has been marked with an expiration policy that indicates that the page expires 60 minutes from the time it is cached, the page is removed from the output cache after 60 minutes. If another request is received after that time, the page code is executed and the page can be cached again. This type of expiration policy is called absolute expiration - a page is valid until a certain time.

The Output Cache Directive:


The following example demonstrates a simple way to output cache responses using the @ OutputCache directive. The example simply displays the time when the response was generated. To see output caching in action, invoke the page and note the time at which the response was generated. Then refresh the page and note that the time has not changed, indicating that the second response is being served from the output cache. The following directive activates output caching on the response:
<%@ OutputCache Duration="60" VaryByParam="none"%>

This directive simply indicates that the page should be cached for 60 seconds and that the page does not vary by any GET or POST parameters. Requests received while the page is still cached are satisfied from the cache. After 60 seconds, the page is removed from the cache; the next request is handled explicitly and caches the page again. Of course, in the previous example, very little work is saved by output caching. The following example shows the same technique for output caching, but queries a database and displays the results in a grid.

Vary By Parameters:
In this, the application is modified slightly to allow the user to selectively query for authors in various states. This example demonstrates caching requests varying by the name/value pairs in the query string using the VaryByParam attribute of the @ OutputCache directive.
<%@ OutputCache Duration="60" VaryByParam="state" %>

Page 152

ASP.NET MATERIAL
For each state in the data set, there is a link that passes the desired state as part of the query string. The application then constructs the appropriate database query and shows authors belonging only to the selected state. Note that the first time you click the link for a given state, it generates a new timestamp at the bottom of the page. Thereafter, whenever a request for that state is resubmitted within a minute, you get the original timestamp indicating that the request has been cached.

SQL Cache Notification New in 2.0:


In the previous example, the data was cached for 60 seconds, regardless of whether the data has changed in the database. SQL cache invalidation enables you to make the cache entry dependent on the database, so the cache entry will only be cleared when data in the database is changed.

Post-cache Substitution New in 2.0:


In ASP.NET 1.0, pages that were mostly static but contained a small dynamic region, such as username or current time, were frequently forced to either not use caching or partition the page into multiple user controls cached with fragment caching. ASP.NET 2.0 enables these pages to take advantage of output caching, by allowing output cached pages to insert dynamic content on every request. In the example below, the output cached page inserts a dynamic callback to a static method that returns the current date with the Response.WriteSubstitution API. This callback executes on every request, and the result gets inserted into the cached response chain that is served from output cache.

Using the Cache API: Applications that want more control over the HTTP headers
related to caching can use the functionality provided by the System.Web.HttpCachePolicy class. The following example shows the code equivalent to the page directives used in the previous samples. Response.Cache.SetExpires (Now.AddSeconds (60))
Response.Cache.SetCacheability (HttpCacheability.Public)

To make this a sliding expiration policy, where the expiration time out resets each time the page is requested, set the SlidingExpiration property as shown in the following code.
Response.Cache.SetExpires (Now.AddSeconds (60)) Response.Cache.SetCacheability (HttpCacheability.Public) Response.Cache.SetSlidingExpiration (True)

Page 153

ASP.NET MATERIAL
Web user Control & Custom Control:

ASP.NET provides two models of creating Web controls user controls and custom controls. This article assumes basic knowledge of the two models and will not provide detailed information on writing controls. Instead, this article will present the reasons why one should choose one model over the other. User Controls: User controls are authored in the same fashion as a standard Web Form. This makes user controls relatively easy to create, especially when aided by a visual designer such as Visual Studio .NET. Hence, given the same WYSIWYG and declarative environment as an ASP.NET page, user controls can be created with or without a code-behind file, and can handle their own events independent of the parent page. Design-time support for user controls, however, is limited. User controls are represented only by a dull placeholder and properties cannot be set via the Properties window. Also, user controls cannot be added to the Toolbox; sharing of user controls is achieved through placing the necessary user control files in each Web application directory. Custom Controls: Unlike user controls which are authored in the same fashion as a Web Form, custom controls are compiled and distributed in binary format. Control authors must create their own classes which subclass from System.Web.UI.Control either directly or indirectly by subclassing another control. Custom controls are created without the aid of a designer and require the author to overcome a much steeper learning curve. On the other hand, custom controls provide strong designer-time support. Once compiled, custom controls can be added to the Toolbox and be used the same fashion as the other controls that ship with the .NET SDK such as the TextBox and Button controls. Furthermore, custom controls can expose properties which can easily be set by page developers using the Properties window of the visual designer. Finally, custom controls allow authors to extend or modify the functionality provided by existing controls. Performance: With regards to performance, neither has a distinct advantage over the other. Both derive from System.Web.UI.Control and both are compiled into assemblies. Hence, performance is not a factor to consider when choosing between user and custom controls. Conclusion: In conclusion, the single most important factor is how the control will be used will the control be application specific or generic and redistributable? If

Page 154

ASP.NET MATERIAL
the control is application specific and contains a lot of static layout, such as a site header and footer, a user control would make sense. If the control is generic, redistributable, and contains dynamic layout, such as the server controls that ship with the .NET SDK, then a custom control would be more suitable.

Fragment Caching:

This article demonstrates how to implement fragment caching in ASP.NET. Fragment caching does not actually cache a Web Form's code fragments directly; fragment caching refers to the caching of individual user controls (.ascx) within a Web Form. Each user control can have independent cache durations and implementations of how the caching behavior is to be applied. The sample code in this article illustrates how to achieve this functionality. Fragment caching is useful when you need to cache only a subset of a page. Navigation bars, header, and footers are good candidates for fragment caching.

Requirements:

Microsoft Windows 2000 Microsoft Internet Information Server (IIS) Microsoft .NET Framework ASP.NET

Create an ASP.NET Web Application Using C# .NET:


The following steps demonstrate how to create a new ASP.NET Web application named FragmentCache. 1. Open Microsoft Visual Studio .NET 2. On the File menu, point to New, and then click Project. 3. In the New Project dialog box, click Visual C# Projects under Project Types, and then click ASP.NET Web Application under Templates. 4. In the Name box, type FragmentCache. In the Location box, select the appropriate server. If you are using the local server, you can leave the server name as http://localhost.

Create the User Controls:


This section provides the sample code and explanations of each user control that you will use in this article. You can copy and paste the sample code into the associated .ascx file and code-behind page as described.

Page 155

ASP.NET MATERIAL
User Control 1 (FragmentCtrl1.ascx): The following user control, FragmentCtrl1.ascx, is very simple. FragmentCtrl1.ascx writes out the time that the cache entry for the item occurs. As with all of the controls that are created for this article, a basic description is provided for the control to make it easier to distinguish the settings and the associated behaviors at run time in the later sections. 1. In Visual Studio .NET, create a new user control as follows: a. In Solution Explorer, right-click the project node, point to Add, and then click Add Web User Control. b. Name the control FragmentCtrl1.ascx, and then click Open. 2. Make sure that the Design tab is selected. Click and drag a Web Form Label control from the Web Forms section of the toolbox, and drop the Label control onto the page. 3. Click the Label control. In the Properties pane of the Visual Studio .NET integrated development environment (IDE), type CacheEntryTime in the ID property, and leave the Text property blank. 4. Switch to HTML view, and add the following @OutputCache directive to the top of the page:
5. <%@ OutputCache Duration="40" VaryByParam="none"%>

6. Right-click the .ascx file, and then click View Code to display the code-behind page source. 7. Add the following code to the Page_Load event, which sets the CacheEntryTime label's Text property:
8. private void Page_Load(object sender, System.EventArgs e) 9. { 10. CacheEntryTime.Text ="FragmentCtrl1: DateTime.Now.TimeOfDay.ToString(); 11. } " +

User Control 2 (FragmentCtrl2.ascx):


Although you can simply create another version of the first control with a different cache duration to show how multiple user controls can have independent behaviors in the same page, this section makes the second control, FragmentCtrl2.ascx, more interesting. FragmentCtrl2.ascx is used to introduce the VaryByControl attribute. VaryByControl allows different cache entries to be made based on the values for a specified control. This functionality is made much clearer at run time in the next section. 1. In Visual Studio .NET, create a new user control as follows:

Page 156

ASP.NET MATERIAL
a. In Solution Explorer, right-click the project node, point to Add, and then click Add Web User Control. b. Name the control FragmentCtrl2.ascx, and then click Open. Make sure that the Design tab is selected. Click and drag a Web Form Label control from the Web Forms section of the toolbox, and then drop the Label control onto the page. Click the Label control. In the Properties pane, type CacheEntryTime in the ID property, and leave the Text property blank. Position the cursor directly after the Label control, and then press ENTER to move to the next line in the page. Click and drag a Web Form RadioButtonList control from the Web Forms section of the toolbox, and drop it onto the page. The RadioButtonList control should appear by itself on the line after the Label control. Click the RadioButtonList control. In the Properties pane, type MyRadioButtonList in the ID property. In the Properties pane, locate the Items property for the MyRadioButtonList control, click Collection, and then click the ellipsis (...) button that appears next to Collection. In the ListItem Collection Editor window, add ListItem members as follows:

2. 3. 4. 5. 6. 7. 8.

a. Under Members, click Add. b. In the ListItem properties section, set Text and Value to Yes, and set Selected to True. c. Under Members, click Add again. d. In the ListItem properties section, set Text and Value to No, and set Selected to False. e. Under Members, click Add one last time. f. In the ListItem properties section, set Text and Value to Maybe, and set Selected to False. g. Click OK to return to the .ascx file in Design view. Notice that three radio buttons appear that are contained within the RadioButtonList control: Yes, No, and Maybe. 2. Position the cursor directly after the RadioButtonList control, and press ENTER to move to the next line in the page. 3. Click and drag a Web Form Button control from the Web Forms section of the toolbox, and drop it onto the page. The Button control should appear by itself on the line after the RadioButtonList control. 4. Click the Button control. In the Properties pane, type Submit in the Text property. 5. Switch to HTML view, and add the following @OutputCache directive to the top of the page:
6. <%@ OutputCache Duration="60" VaryByControl="MyRadioButtonList"%> VaryByParam="none"

Page 157

ASP.NET MATERIAL
7. Right-click the .ascx file, and then click View Code to display the code-behind page source. 8. Add the following code to the Page_Load event, which sets the CacheEntryTime label's Text property:
9. private void Page_Load(object sender, System.EventArgs e) 10. { 11. CacheEntryTime.Text = "FragmentCtrl2: DateTime.Now.TimeOfDay.ToString(); 12. } " +

Create the Web Form to Contain the User Controls:


You can now create the Web Form (.aspx) to contain the newly developed user control. To create the Web Form, follow these steps: 1. Add a new Web Form named FragmentCaching.aspx to your project in Visual Studio .NET as follows: a. In Solution Explorer, right-click the project node, point to Add, and then click Add Web Form. b. Name the Web Form FragmentCaching.aspx, and then click Open. 2. Make sure that the Design tab is selected. Click and drag a Web Form Label control from the Web Forms section of the toolbox, and drop it onto the page. 3. Click the Label control. In the Properties pane, type Time in the ID property, and leave the Text property blank. 4. Position the cursor directly after the Label control, and press ENTER to move to the next line in the page. 5. Drag FragmentCtrl1.ascx, and drop it onto the Web Form so that it is positioned after the Label control on a line by itself. Position the cursor directly after the control, and press ENTER to move to the next line in the page. 6. Drag FragmentCtrl2.ascx, and drop it onto the Web Form so that it is positioned after FragmentCtrl1.ascx on a line by itself. 7. In HTML view, the Web Form should appear similar to the following code:
8. <%@ Page language ="c#" Codebehind="FragmentCaching.aspx.cs" 9. AutoEventWireup="false" Inherits="FragmentCache.FragmentCaching" %> 10. <%@ Register TagPrefix="uc1" TagName="FragmentCtrl1" Src="FragmentCtrl1.ascx" %> 11. <%@ Register TagPrefix="uc1" TagName="FragmentCtrl2" Src="FragmentCtrl2.ascx" %> 12. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 13. <HTML> 14. <HEAD>

Page 158

ASP.NET MATERIAL
15. <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0"> 16. <meta name="CODE_LANGUAGE" Content="C#"> 17. <meta name="vs_defaultClientScript" content="JavaScript (ECMAScript)"> 18. <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> 19. </HEAD> 20. <body> 21. <form id="FragmentCaching" method="post" runat="server"> 22. <P> 23. WebForm Time: 24. <asp:Label id="Time" runat="server" ForeColor="Blue"></asp:Label> 25. </P> 26. <P> 27. <uc1:FragmentCtrl1 id="FragmentCtrl11" runat="server"> 28. </uc1:FragmentCtrl1> 29. </P> 30. <P> 31. <uc1:FragmentCtrl2 id="FragmentCtrl21" runat="server"> 32. </uc1:FragmentCtrl2> 33. </P> 34. </form> 35. </body> 36. </HTML>

NOTE: Make sure that the controls are placed inside the 37. Right-click the .aspx file, and then click View Code to display the code-behind page source. 38. Add the following code to the Page_Load event, which sets the Time label's Text property:
39. 40. 41. 42. private void Page_Load(object sender, System.EventArgs e) { Time.Text = "WebFormTime: " + DateTime.Now.TimeOfDay.ToString(); }

43. From the File menu, click Save All to save the user controls, the Web Form, and other associated project files. 44. From the Build menu in the Visual Studio .NET integrated development environment (IDE), click Build to build the project.

Run the Sample:


This section demonstrates how to view the code at run time to witness the caching behavior and then briefly describes why the code performs the way that it does.

Page 159

ASP.NET MATERIAL
1. In the Visual Studio .NET IDE Solution Explorer, right-click the FragmentCaching.aspx Web Form, and then click View in Browser to run the code. 2. After the page appears in the browser, right-click the page, and then click Refresh to refresh the page. You can also press the F5 key to refresh the page if you are viewing the page in a browser that is external to the Visual Studio .NET IDE. Notice that the time on the Web Form has been updated, but the user controls still display the time when their associated cache entry was made. 3. In the second control, click Submit. Notice that the control displays an updated time. This is in response to the VaryByControl attribute setting for the user control that references the RadioButtonList control. 4. Click No, and then click Submit again. Notice that the time is updated again in the user control's display. This is because a new cache entry is made for the control based on this No value setting. Repeat this step except with the Maybe option. You see the same behavior. 5. Click Yes, and then click Submit again. Repeat this operation with the No and Maybe options. Notice that these selections for the control are cached and that they display the previous cache entry time. If you continue to click Submit past the @ OutputCache directive's duration setting, the user control's time is updated for each specific value selection for the RadioButtonList control. Data Caching: If you're using typically static data with your ASP.NET applications - such as that from a database server like Microsoft SQL Server - you should take a look at caching your data. Previously, this was not an easy thing to do, but the caching in .NET makes caching your data and objects a trivial task. This tutorial will cover basic caching and scenarios where caching would be good to use. Using the Cache Property: In ASP.NET, every page you write extends the System.Web.UI.Page class, which contains a member called Cache. You use the Cache property as you would any other IEnumerable, which gives you methods and properties to get, set, and enumerate through members. We will be looking at getting and setting items in the cache. In the simplest example, you can retrieve any object from the cache like so:
Object obj = (Object)Cache["key"];

What this does is look in the Cache for an item with the key "key". If such an item exists, the object is returned. While we don't need to cast the returned object to Object, this is

Page 160

ASP.NET MATERIAL
just an example of how you must cast the return to the class type you want returned. If the item is not found, null is returned, so you will need to do some checking:
Object obj = (Object)Cache["key"]; if (obj == null) { // Generate a new object and insert it into the cache } // Use your object

You can also assign object to the cache like the following code example, but using Cache.Inset () is a much better means as you'll see later:
Cache["key"] = obj;

Now let's look at a serious example. In the example below, we will define a function that binds data to a control, such as a ASP.NET DataGrid control. We will look at data binding in a little more depth later. For this example, we will use a System.Data.DataSet object. <%@ Page Language="C#" %> <%@ Import Namespace="System.Data" %>
<script runat="server"> private string _filename = "mydata.xml"; private void Page_Load(Object src, EventArgs args) { DataSet ds = (DataSet)Cache["mydata"]; if (ds == null) { ds.ReadXml(Server.MapPath(_filename)); Cache.Insert("mydata", ds, new CacheDependency(Server.MapPath(_filename)), DateTime.Now.AddHours(12), NoSlidingExpiration); } myDataGrid.DataSource = ds; myDataGrid.DataBind();

We'll break down the above example. The first part we've already discussed, where we get the object from the cache. If the object is null (i.e., doesn't exist in the cache), we need to create the object. The first line after checking if our DataSet object is null loads an XML file called a DiffGram, which is a serialized DataSet object. We'll talk about this

Page 161

ASP.NET MATERIAL
later. Essentially, the DataSet object (hereforth, "ds") is created from serialized XML, which you can event type by hand. We call Server.MapPath() because the file as we know it is virtual. ds.ReadXml needs the absolute path and filename to load it. Server.MapPath() figures out what the absolute path of a virtual filename and returns the absolutepath. The next statement inserts the newly created "ds" into the cache. Again, the statement is:
Cache.Insert("mydata", ds, new CacheDependency(Server.MapPath(_filename)), DateTime.Now.AddHours(12), NoSlidingExpiration);

1. The first parameter is the key used to identify our cache item. 2. The second parameter is the object we want to cache. In this example, we are caching the DataSet object "ds". This can be any object, however, including strings, numbers, controls, etc. 3. The third parameter creates a dependency on an object. If this object changes, the cached object is marked as expired and your application will regenerate next time, returning null as your object reference. In fact, the object is expired. You can also pass null in this parameter to signify that you don't want any dependencies. 4. The fourth parameter is the absolute expiration period your object is valid. Here, we use DateTime.Now (which uses "now's" time) and add 12 hours to it. This means the object will automatically expire in 12 hours. You could also use NoAbsoluteExpiration which means the object will never expire until the dependent object changes. We use an absolute expiration here to make sure we have somewhat recent data in case the CacheDependency doesn't expire the data for some reason. (As if Microsoft software doesn't have bugs!) 5. The fifth and final parameter is a sliding expiration. This means that if the object is access, the absolute expiration time is essentially pushed back to however many minutes, hours, etc. you specify here. This is an object of type TimeSpan. Here, we want our object expired after 12 hours even if the object is accessed before then. After all this, we can finally bind our object to a data-driven control, such as the ASP.NET DataGrid control. While the full use of the control is out of the scope of this tutorial. The DataGrid control is a data-driven control meaning that on the server, the control will use data and will then render the HTML onto the page for the client to see in their browser. We will define a basic DataGrid control customizing only a few parameters:
<body> <asp:DataGrid id="myDataGrid" runat="server"

Page 162

ASP.NET MATERIAL
AutoGenerateColumns="true" ShowHeader="true" AllowPaging="true" PageSize="25" Font-Name="Verdana" Font-Size="10pt"> <HeaderStyle Font-Bold="true"/> </asp:DataGrid> </body>

Above, we define a Web server control of type DataGrid, which is a data-driven control that renders a table on the page. By setting AutoGenerateColumns to true (which is default anyway), we specify that the DataGrid control will automatically generate headers and columns based on your data in the order of the columns in your DataSet. We also setup default paging and a few items styles, while making the Header column text bold. In the example Page_Load() event handler, we did a little data binding like so:
myDataGrid.DataSource = ds; myDataGrid.DataBind();

These two lines associate the DataSource property of the DataGrid with our DataSet object "ds" and then binds the data with DataBind(). If you do not call DataBind(), you will find that nothing is rendered on your page. The DataSource property can point at other types of object, like ArrayList(), DataView() and many others. Consult your .NET SDKDocumentationformoredetails. Scenarios: why would you use this tutorial to build your next data-driven ASP.NET page? There are severalexamples,butIwilldiscussonehere. Lets say that you've developed a page or site that generates a table of contents on ever page. You also have a SQL Server storing this data because the table of contents changes from time to time. Instead of making calls across the network to the SQL Server (even cached data on SQL Server requires a few calls back and forth), you could use the caching. There are two ways primary ways of handling this: 1. Setup a scheduled task on the SQL Server 2000 to output your table as XML to a specified location on your web server. Because SQL Server 2000 can serialize your data to DiffGrams used in DataSet construction, this is an easy way to deliver updates to your DiffGram file described above in our caching example. You could even setup a trigger on your SQL Server to generate a new DiffGram

Page 163

ASP.NET MATERIAL
when the contents of your table change, but that is beyond the scope of this tutorial. 2. Another way is to adapt the example above to create not only a DataSet, but to use classes from System.Data.OleDb or System.Data.SqlClient to get your data from time to time from the server. In this particular case (which we'll do below), creating a cache dependency wouldn't make much since because the SQL Server is no longer updating your DiffGram file, identified by the private member _filename in the example above. You could adapt second method above to something like the following: <%@ Page Language="C#" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server"> // If used frequently, store these strings in your Web.config // and use ConfigurationSettings.AppSettings["key"] to get them out. // If you do this, make sure these are constant strings! private const string connstr = "Data Source=sqlserver1;Initial Catalog=Web"; private const string cmdstr = "SELECT Title,URL FROM TOC"; private void Page_Load(Object src, EventArgs args) { DataSet ds = (DataSet)Cache["mydata"]; if (ds == null) { // Connect to the SQL Server and get our data using a DataAdapter SqlConnection conn = new SQlConnection(connstr); SqlCommand cmd = new SqlCommand(cmdstr, conn); SqlDataAdapter adapter = new SqlDataAdapter(cmd); // Create a new DataTable and fill it DataTable dt = new DataTable("Item"); adapter.Fill(dt); // Now add our DataTable to a DataSet instance and add to cache ds = new DataSet("TOC"); ds.Tables.Add(dt); Cache.Insert("mydata", ds, null, DataTime.Now.AddHours(1), NoSlidingExpiration); } // Bind our data myRepeater.DataSource = ds; myRepeater.DataBind();

Page 164

ASP.NET MATERIAL
Yes, I've chanced our ASP.NET control to a Repeater because a DataGrid wouldn't make a lot of sense. I will describe what you could use in this example for a Repeater control in a minute. Describing the example above, it is really nothing more than what we had before execpt that we have no CacheDependency because we have no files to watch, and we create our DataSet from a DataTable that is filled by a SqlDataAdapter (or OleDbDataAdapter if you prefer). DataSets are good to store in the Cache since they are easy to use, can be used in any data-driven control, and can be serialized at will with one call to ReadXml() or WriteXml(). Finally, our Repeater control would look something like the following:
<body> <asp:Repeater id="myRepeater" runat="server" Visible="true"> <ItemTemplate> <dd><a href="<%# DataBinder.Eval(Container, "Item.URL") %>"><%# DataBinder.Eval(Container, "Item.Title") %></a></dd> </ItemTemplate> </asp:Repeater> </body>

The expressions above evaluate your Container (your DataSet object) and find the "Item.Title" and "Item.URL". "Item" is the name of the data item, which is the the name of the table usually. You may remember that we called our DataTable "Item" above:
DataTable dt = new DataTable("Item");

"Title" and "URL" our names of our fields in the table. See, even your data is appropriatelynamed! Conclusions: That pretty much wraps up the tutorial of how to use caching. There are many other examples and scenarios of how to use Caching and DataSets to cache data, but this tutorial is long enough I think. Please keep in mind that you can cache other objects as well, not just DataSets. I find that caching DataSets where you used infrequently accessed data is especially helpful, however, to decrease loads on your Web server, SQL Server (or other database server), and network.

ASP.NET CONFIGURATION

Machine Config VS WebConfig:

Page 165

ASP.NET MATERIAL
Machine.config: This is automatically installed when you install Visual Studio. Net.This is also called machine level configuration file. Only one Machine.config file exists on a server.This file is at the highest level in the configuration hierarchy. Web.config: This is automatically created when you create an ASP.Net web application project. This is also called application level configuration file. This file inherits setting from the Machine.config Difference between Web.config and Machine.config:

The settings made in the Web.config file are applied to that particular web application only whereas the settings of Machine.config file are applied to the whole asp.net application. Web.config file Setting of asp.net all project Machine.config are setting of server setting and when the web side are implemented time it work all project but Web.config file set all projects Web config will be for that particular aplln whereas the Machine .config will for the whole machine Every ASP.NET application that you has a Web.config file . The settings specified in this will imply only to that application.Whereas Your System will have a Machine.config file in Microsoft.NET\Framework\v1.1.4322\CONFIG Folder which contains specifications and settings at a system level. Web.config file is to override the settings from the Machine.config file. Machine.config file settings are applied to all the webapplications residing on the server while Web.config settings are application specific. Machine. config is configuration file for all the application in the IIS. but Web.config is a configuration file for a application or folder. Machine.config for machine level configuration. but Web.config for a application/folder level configuration.

Custom Error Settings:

Provides information about custom error messages for an ASP.NET application. The customErrors element can be defined at any level in the application file hierarchy. <configuration> Element system.web Element (ASP.NET Settings Schema) <customErrors>
<customErrors defaultRedirect="url" mode="On|Off|RemoteOnly"> <error. . ./> </customErrors>

Page 166

ASP.NET MATERIAL
Attributes and Elements: The following sections describe attributes, child elements, and parent elements.

Attributes
Attribute Optional attribute. Specifies the default URL to direct a browser to, if an error occurs. When this attribute is not specified, a generic error is displayed instead. defaultRedirect The URL can be absolute (for example, www.contoso.com/ErrorPage.htm) or relative. A relative URL, such as /ErrorPage.htm, is relative to the Web.config file that specified the URL for this attribute, not to the Web page in which the error occurred. A URL starting with a tilde (~), such as ~/ErrorPage.htm, indicates that the specified URL is relative to the root path of the application. Required attribute. Specifies whether custom errors are enabled, disabled, or shown only to remote clients. This attribute can be one of the following values. ValueDescription OnSpecifies that custom errors are enabled. If no defaultRedirect attribute is specified, users see a generic error. The custom errors are shown to the remote clients and to the local host. OffSpecifies that custom errors are disabled. The detailed ASP.NET errors are shown to the remote clients and to the local host. RemoteOnlySpecifies that custom errors are shown only to the remote clients, and that ASP.NET errors are shown to the local host. This is the default value. The default is RemoteOnly. Optional attribute. Specifies values for how the URL of the original request is handled when a custom error page is displayed. This attribute can be one of the following values. Description

mode

redirectMode

Page 167

ASP.NET MATERIAL
ValueDescription ResponseRedirectSpecifies that the URL to direct the browser to must be different from the original Web request URL. ResponseRewriteSpecifies that the URL to direct the browser to must be the original Web request URL.

Child Elements:
Element Optional element. error Specifies the custom error page for a given HTTP status code. The error tag can appear multiple times. Each appearance defines one custom error condition. Description

Parent Elements:
Description Specifies the root element in every configuration file that is used by the configuration common language runtime and the .NET Framework applications. Specifies the root element for the ASP.NET configuration settings in a system.web configuration file and contains configuration elements that configure ASP.NET Web applications and control how the applications behave. Example: The following configuration example demonstrates how to specify the error handling pages to use for an ASP.NET application.
<configuration> <system.web> <customErrors defaultRedirect="GenericError.htm" mode="RemoteOnly"> <error statusCode="500" redirect="InternalError.htm"/> </customErrors> </system.web> </configuration>

Element

Session State Setting:

Use ASP.NET session state to store and retrieve values for a user. This topic contains:

Page 168

ASP.NET MATERIAL

Background Code Examples Class Reference

ASP.NET session state enables you to store and retrieve values for a user as the user navigates ASP.NET pages in a Web application. HTTP is a stateless protocol. This means that a Web server treats each HTTP request for a page as an independent request. The server retains no knowledge of variable values that were used during previous requests. ASP.NET session state identifies requests from the same browser during a limited time window as a session, and provides a way to persist variable values for the duration of that session. By default, ASP.NET session state is enabled for all ASP.NET applications. Alternatives to session state include the following:

Application state, which stores variables that can be accessed by all users of an ASP.NET application. Profile properties, which persists user values in a data store without expiring them. ASP.NET caching, which stores values in memory that is available to all ASP.NET applications. View state, which persists values in a page. Cookies. The query string and fields on an HTML form that are available from an HTTP request.

Session Variables:
Session variables are stored in a SessionStateItemCollection object that is exposed through the HttpContext.Session property. In an ASP.NET page, the current session variables are exposed through the Session property of the Page object. The collection of session variables is indexed by the name of the variable or by an integer index. Session variables are created by referring to the session variable by name. You do not have to declare a session variable or explicitly add it to the collection. The following example shows how to create session variables in an ASP.NET page for the first and last name of a user, and set them to values retrieved from TextBox controls.
Session["FirstName"] = FirstNameTextBox.Text; Session["LastName"] = LastNameTextBox.Text;

Session variables can be any valid .NET Framework type. The following example stores an ArrayList object in a session variable named StockPicks. The value returned by the

Page 169

ASP.NET MATERIAL
StockPicks session variable must be cast to the appropriate type when you retrieve it from the SessionStateItemCollection.
// When retrieving an object from session state, cast it to // the appropriate type. ArrayList stockPicks = (ArrayList)Session["StockPicks"]; // Write the modified stock picks list back to session state.

Session["StockPicks"] = stockPicks;

Session Identifiers:
Sessions are identified by a unique identifier that can be read by using the SessionID property. When session state is enabled for an ASP.NET application, each request for a page in the application is examined for a SessionID value sent from the browser. If no SessionID value is supplied, ASP.NET starts a new session and the SessionID value for that session is sent to the browser with the response. By default, SessionID values are stored in a cookie. However, you can also configure the application to store SessionID values in the URL for a "cookieless" session. A session is considered active as long as requests continue to be made with the same SessionID value. If the time between requests for a particular session exceeds the specified time-out value in minutes, the session is considered expired. Requests made with an expired SessionID value result in a new session.

Cookieless SessionIDs:
By default, the SessionID value is stored in a non-expiring session cookie in the browser. However, you can specify that session identifiers should not be stored in a cookie by setting the cookieless attribute to true in the sessionState section of the Web.config file. The following example shows a Web.config file that configures an ASP.NET application to use cookieless session identifiers.
<configuration> <system.web> <sessionState cookieless="true" regenerateExpiredSessionId="true" /> </system.web> </configuration>

Page 170

ASP.NET MATERIAL
ASP.NET maintains cookieless session state by automatically inserting a unique session ID into the page's URL. For example, the following URL has been modified by ASP.NET to include the unique session ID lit3py55t21z5v55vlm25s55: When ASP.NET sends a page to the browser, it modifies any links in the page that use an application-relative path by embedding a session ID value in the links. (Links with absolute paths are not modified.) Session state is maintained as long as the user clicks links that have been modified in this manner. However, if the client rewrites a URL that is supplied by the application, ASP.NET may not be able to resolve the session ID and associate the request with an existing session. In that case, a new session is started for the request. The session ID is embedded in the URL after the slash that follows the application name and before any remaining file or virtual directory identifier. This enables ASP.NET to resolve the application name before involving the SessionStateModule in the request.

Regenerating Expired Session Identifiers:


By default, the session ID values that are used in cookieless sessions are recycled. That is, if a request is made with a session ID that has expired, a new session is started by using the SessionID value that is supplied with the request. This can result in a session unintentionally being shared when a link that contains a cookieless SessionID value is used by multiple browsers. (This can occur if the link is passed through a search engine, through an e-mail message, or through another program.) You can reduce the chance of session data being shared by configuring the application not to recycle session identifiers. To do this, set the regenerateExpiredSessionId attribute of the sessionState configuration element to true. This generates a new session ID when a cookieless session request is made with an expired session ID.

Custom Session Identifiers:


You can implement a custom class to supply and validate SessionID values. To do so, create a class that inherits the SessionIDManager class and override the CreateSessionID and Validate methods with your own implementations. For an example, see the example provided for the CreateSessionID method. You can replace the SessionIDManager class by creating a class that implements the ISessionIDManager interface. For example, you might have a Web application that associates a unique identifier with non-ASP.NET pages (such as HTML pages or images) by using an ISAPI filter. You can implement a custom SessionIDManager class to use this unique identifier with ASP.NET session state. If your custom class supports cookieless session identifiers, you must implement a solution for sending and retrieving session identifiers in the URL.

Page 171

ASP.NET MATERIAL
Session Modes:
ASP.NET session state supports several storage options for session variables. Each option is identified as a session-state Mode type. The default behavior is to store session variables in the memory space of the ASP.NET worker process. However, you can also specify that session state should be stored in a separate process, in a SQL Server database, or in a custom data source. If you do not want session state enabled for your application, you can set the session mode to Off.

Session Events:
ASP.NET provides two events that help you manage user sessions. The Session_OnStart event is raised when a new session starts, and the Session_OnEnd event is raised when a session is abandoned or expires. Session events are specified in the Global.asax file for an ASP.NET application. The Session_OnEnd event is not supported if the session Mode property is set to a value other than InProc, which is the default mode.

Configuring Session State:


Session state is configured by using the sessionState element of the system.web configuration section. You can also configure session state by using the EnableSessionState value in the @ Page directive. The sessionState element enables you to specify the following options:

The mode in which the session will store data. The way in which session identifier values are sent between the client and the server. The session Timeout value. Supporting values that are based on the session Mode setting.

The following example shows a sessionState element that configures an application for SQLServer session mode. It sets the Timeout value to 30 minutes, and specifies that session identifiers are stored in the URL.
<sessionState mode="SQLServer" cookieless="true " regenerateExpiredSessionId="true " timeout="30" sqlConnectionString="Data Security=SSPI;" stateNetworkTimeout="30"/>

Source=MySqlServer;Integrated

Page 172

ASP.NET MATERIAL
You can disable session state for an application by setting the session-state mode to Off. If you want to disable session state for only a particular page of an application, you can set the EnableSessionState value in the @ Page directive to false. The EnableSessionState value can also be set to ReadOnly to provide read-only access to session variables.

Concurrent Requests and Session State:


Access to ASP.NET session state is exclusive per session, which means that if two different users make concurrent requests, access to each separate session is granted concurrently. However, if two concurrent requests are made for the same session (by using the same SessionID value), the first request gets exclusive access to the session information. The second request executes only after the first request is finished. (The second session can also get access if the exclusive lock on the information is freed because the first request exceeds the lock time-out.) If the EnableSessionState value in the @ Page directive is set to ReadOnly, a request for the read-only session information does not result in an exclusive lock on the session data. However, read-only requests for session data might still have to wait for a lock set by a read-write request for session data to clear.

Enhancement in ASP.NET:

Introduction: ASP.NET's model of Web controls, server-side event handlers, and view state work in unison to help blur the lines between the client and the server. In short, a developer designing an ASP.NET web page can think in terms of higher-level abstrations TextBoxes, Buttons, Click events, and so on - and not have to worry about the low-level details of HTML, JavaScript, and how data is shuttled from the web server down to the client's web browser, and back again. However, it is important to be aware of the distinction between the client and the server. . Oftentimes, the overall user experience can be enhanced by intelligently adding clientside script. By associating script with client-side user actions, it is possible to provide a snappier user interface or to enhance the overall experience. For example, when clicking a Delete button on a web form, rather than blindly deleting the record or posting back to a confirmation page, client-side script can be used to display a confirm messagebox, asking the user if they're certain they want to proceed with the delete. Clicking OK would proceed with the postback, while clicking Cancel would short circuit it.

Page 173

ASP.NET MATERIAL

Adding such client-side functionality in ASP.NET version 1.x almost always involved writing code. And for more advanced scenarios, the amount of code - both server-side and client-side - could easily explode. ASP.NET 2.0 has added a number of enhancements that make performing common client-side tasks as easy as setting a property. Setting Focus to a Web Control: All form fields in a web page have the ability to programmatically receive focus in the client's web browser via the using the JavaScript focus() method. For example, if the web page contains a textbox with a client-side id of myTextBox (such as <input type="text" id="myTextBox" />), the following JavaScript will set focus to the textbox:
var tb = document.getElementById('myTextBox'); if (tb != null) tb.focus();

This technique is commonly used to set focus to a particular form field when the page first loads. For example, when visiting Google's homepage, focus is set immediately to the search textbox, allowing visitors to immediately start entering they query without having to first click on the textbox with their mouse. To have a Web control receive focus on page load in ASP.NET 1.x, the page developer needed to inject the above JavaScript into the page. With ASP.NET 2.0, all Web controls have a Focus() method that can be invoked on the server-side. Doing so automatically injects the necessary JavaScript. For example, if we have an ASP.NET page with a TextBox Web control whose ID is SearchQuery, we could use the following Page_Load event handler to set focus to this control on page load:
protected void Page_Load(object sender, EventArgs e) { // Set focus to the SearchQuery TextBox SearchQuery.Focus(); }

Page 174

ASP.NET MATERIAL
Calling the Focus() method automatically injects the following script include into the rendered page:
<script src="/Directory/WebResource.axd? d=JA7BpX_wFudgXazbqxO5Dw2&t=632965002926288600" type="text/javascript"></script>

The WebResource.axd reference is a special path that returns a specific set of JavaScript functions to be used by the client. One of the JavaScript files included is WebForm_AutoFocus(control), which has the following definition:
function WebForm_AutoFocus(focusId) { var targetControl; if (__nonMSDOMBrowser) { targetControl = document.getElementById(focusId); } else { targetControl = document.all[focusId]; } var focused = targetControl; if (targetControl && (!WebForm_CanFocus(targetControl)) ) { focused = WebForm_FindFirstFocusableChild(targetControl); } if (focused) { try { focused.focus(); if (__nonMSDOMBrowser) { focused.scrollIntoView(false); } if (window.__smartNav) { window.__smartNav.ae = focused.id; } } catch (e) { } } }

In addition to adding the above script reference, calling the Focus() method also adds the following call to WebForm_AutoFocus(control) right before the closing </form> element:
WebForm_AutoFocus('SearchQuery');

In short, calling the Focus() method on the server-side automatically injects the appropriate script functions and a call to the WebForm_AutoFocus(control) function, meaning that we do not need to bother with crafting the JavaScript ourselves. The

Page 175

ASP.NET MATERIAL
download available at the end of this article includes a live demo of the Focus() method along with the other techniques examined in this article. Performing a Client-Side Action When a Button, LinkButton, or ImageButton is clicked: When a Button, LinkButton, or ImageButton Web control is clicked, a postback ensues. Sometimes, though, rather than immediately performing a postback we'd first like to perform some client-side task. A common example is in displaying a confirm dialog box that prompts the end user whether they want to perform the action associated with the button being clicked. Regardless of what script you want executed when the button is clicked, you can specify it through the Button, LinkButton, or ImageButton's OnClientClick property. The confirm dialog box can be displayed through the JavaScript confirm(msg) function. confirm(msg) displays a modal dialog box with an OK and Cancel button, displaying the text msg within the messagebox. If the end user clicks OK, confirm(msg) returns true; if Cancel is clicked, it returns false. When submitting a form, if one of the clientside event handlers returns false, the browser stops the form submission. Therefore, an end user can click the Cancel button to stop the postback and thereby prevent the serverside action from occurring. To add a confirmation dialog box to a Button Web control, simply set its OnClientClick property to return confirm('msg');, like so:
<asp:Button ID="ConfirmOnClick" runat="server" OnClientClick="return confirm('You\'re sure you want to do this?');" Text="Launch Airstrike" />

Since the msg value passed into the confirm(msg) function is delimited by apostrophes, if you have any apostrophes in msg they must be escaped using \', like in "You\'re" in the above example. Adding a value for the OnClientClick property results in rendered HTML that includes an onclick attribute, like:
<input type="submit" name="ConfirmOnClick" value="Launch Airstrike" onclick="return confirm('You\'re sure you want to do this?');" id="ConfirmOnClick" />

Adding such confirmation dialog boxes is quite possible in ASP.NET version 1.x, but requires writing code. See Adding Client-Side Message Boxes in Your ASP.NET Web Pages for more information on achieving this functionality with ASP.NET 1.x.

Page 176

ASP.NET MATERIAL
Maintaining Scroll Position on Postback: When working with large web pages where users typically have to scroll down, one annoyance that can occur when a Button, LinkButton, or ImageButton far down on the page is clicked is that, on postback, the browser returns to the top of the page. That is, if a user has to scroll down to click a button that causes a postback, on postback the browser will reload the document and be at the top of the page, meaning that the user has to scroll back down to where the button was clicked from if they want to see or work with the page at that point. This is a common pain when working with an editable GridView that may span many pages - when scrolling down and clicking the Edit button for some row that's not visible from the very top of the page, on postback the user has to scroll back down to the row being edited. A previous 4Guys article authored by Steve Stchur - Maintaining Scroll Position on Postback - examined how to add a bit of JavaScript that would remember the X and Y scroll positions across postbacks and use JavaScript on the postback to "restore" the user's scroll position. I've personally used Steve's technique in a number of my ASP.NET 1.x projects over the past several years. ASP.NET 2.0 makes remembering scroll position on postback even easier, as the ASP.NET 2.0 engine will kindly inject the necessary JavaScript and HTML elements necessary to remember scroll position across postbacks. To turn on this feature in ASP.NET 2.0, simply set the MaintainScrollPositionOnPostback directive to True, either on the page-level or in Web.config if you want it to apply to all pages in the website. To apply it for a single page, just update the <% @Page %gt; directive so that it looks lkike:
<%@ Page Language="..." MaintainScrollPositionOnPostback="true" ... %>

To apply this setting to all pages in the website, add the following markup to the Web.config file (within the <system.web> element):
<pages maintainScrollPositionOnPostBack="true" />

Turning on the MaintainScrollPositionOnPostback feature adds two hidden form fields to the rendered markup to track the X and Y scroll positions across postbacks:
<input type="hidden" name="__SCROLLPOSITIONX" id="__SCROLLPOSITIONX" value="0" /> <input type="hidden" name="__SCROLLPOSITIONY" id="__SCROLLPOSITIONY" value="0" />

Page 177

ASP.NET MATERIAL
Also, script is injected to associate the web form's client-side onsubmit event handler with the WebForm_SaveScrollPositionOnSubmit() function, which saves the current scroll positions in the hidden form fields shown above. On postback, the window's clientside onload event handler is configured to call the WebForm_RestoreScrollPosition() function, which restores the scroll position prior to the postback. Both the WebForm_SaveScrollPositionOnSubmit() and WebForm_RestoreScrollPosition() functions are included in the page via a JavaScript include to WebResource.axd? d=KJ8KmyYEIkBWV17-XIEtOQ2, which defines these functions as such:
function WebForm_GetScrollX() { if (__nonMSDOMBrowser) { return window.pageXOffset; } else { if (document.documentElement && document.documentElement.scrollLeft) { return document.documentElement.scrollLeft; } else if (document.body) { return document.body.scrollLeft; } } return 0; } function WebForm_GetScrollY() { if (__nonMSDOMBrowser) { return window.pageYOffset; } else { if (document.documentElement && document.documentElement.scrollTop) { return document.documentElement.scrollTop; } else if (document.body) { return document.body.scrollTop; } } return 0; } function WebForm_SaveScrollPositionOnSubmit() { theForm.__SCROLLPOSITIONX.value = WebForm_GetScrollX(); theForm.__SCROLLPOSITIONY.value = WebForm_GetScrollY(); if ((typeof(this.oldOnSubmit) != "undefined") && (this.oldOnSubmit ! = null)) { return this.oldOnSubmit(); } return true; }

Page 178

ASP.NET MATERIAL
function WebForm_RestoreScrollPosition() { if (__nonMSDOMBrowser) { window.scrollTo(theForm.elements['__SCROLLPOSITIONX'].value, theForm.elements['__SCROLLPOSITIONY'].value); } else { window.scrollTo(theForm.__SCROLLPOSITIONX.value, theForm.__SCROLLPOSITIONY.value); } if ((typeof(theForm.oldOnLoad) != "undefined") && (theForm.oldOnLoad != null)) { return theForm.oldOnLoad(); } return true; }

Conclusion: In many scenarios, adding client-side functionality can greatly improve the overall user experience of your web application. Such possibilities were available in ASP.NET 1.x, but ASP.NET 2.0 has added a variety of properties and methods to make it easier to perform a plethora of common client-side tasks. In this article we examined how to set the focus of a Web control, how to associate some client-side action when a Button, LinkButton, or ImageButton was clicked, and how to maintain scroll position across postbacks. Live demos of all of these techniques are provided in the download at the end of this article.

In process & Out Process Session State:

In-process Mode:
In-process mode simply means using ASP.NET session state in a similar manner to classic ASP session state. That is, session state is managed in process and if the process is re-cycled, state is lost. Given the new settings that ASP.NET provides, you might wonder why you would ever use this mode. The reasoning is quite simple: performance. The performance of session state, e.g. the time it takes to read from and write to the session state dictionary, will be much faster when the memory read to and from is in process, as cross-process calls add overhead when data is marshaled back and forth or possibly read from SQL Server. In-process mode is the default setting for ASP.NET. When this setting is used, the only other session config.web settings used are cookieless and timeout. If we call SessionState.aspx, set a session state value, and stop and start the ASP.NET process (iisreset), the value set before the process was cycled will be lost.

Page 179

ASP.NET MATERIAL
Out-of-process Mode:
Included with the .NET SDK is a Windows NT service: ASPState. This Windows service is what ASP.NET uses for out-of-process session state management. To use this state manager, you first need to start the service. To start the service, open a command prompt and type:

Figure 1. Starting the Windows NT service ASPState at the command prompt At this point, the Windows NT Service ASPState has started and is available to ASP.NET. Next, we need to configure ASP.NET to take advantage of this service. To do this we need to configure config.web:
<configuration> <sessionstate mode="stateserver" cookieless="false" timeout="20" sqlconnectionstring="data source=127.0.0.1;user id=<user id>;password=<password>" server="127.0.0.1" port="42424" /> </configuration>

We changed only from inproc mode to stateserver mode. This setting tells ASP.NET to look for the ASP state service on the server specified in the server and port settings in this case, the local server. We can now call SessionState.aspx, set a session state value, stop and start the IIS process (iisreset), and continue to have access to the values for our current state.

Cookie less Session:

Are Cookies a Problem?


For several years, cookies were simply considered a technical feature and largely ignored. A few years ago, the worldwide push on Web security focused the spotlight on cookies.

Page 180

ASP.NET MATERIAL
Cookies were alleged to contain dangerous programs capable of stealing valuable information even beyond the physical boundaries of the machine. It goes without saying that cookies are not programs and therefore can't collect any information on their own, let alone any personal information about users. More simply, a cookie is a piece of text that a Web site can park on a user's machine to be retrieved and reused later. The information stored consists of harmless name-value pairs. The point is, cookies are not part of the standard HTTP specification, so they imply a collaboration between browsers and Web sites to work. Not all browsers support cookies and, more importantly, not all users may have cookie support enabled in their own copy of the browser. There are Web site features that are historically so tightly bound to cookies that they make it hard to distinguish which really came first. On the one hand, session state management and user authentication are much easier to code with cookies. On the other hand, if you take a look at your site's statistics regarding browsers used to access pages, you might be surprised to discover that a significant share of users connect with cookies disabled. This poses a point for you as a developer. Summarizing, cookies are not a problem per se but their use undoubtedly gives some server code the ability to store a piece of data on client machines. This prefigures some potential security risks and an overall situation less then ideal. (In some cases and countries, it's even illegal for an application to require cookies to work.)

Enter Cookieless Sessions:


In ASP.NET, the necessary session-to-user link may optionally be established without using cookies. Interestingly enough, you don't have to change anything in your ASP.NET application to enable cookieless sessions, except the following configuration setting.
<sessionState cookieless="true" />

Default settings for ASP.NET session state are defined in the machine.config file and can be overridden in the web.config file in the application's root folder. By ensuring that the above line appears in the root web.config file, you enable cookieless sessions. That's iteasy and effective.

Page 181

ASP.NET MATERIAL
The <sessionState> node can also be used to configure other aspects of the session state management, including the storage medium and the connection strings. However, as far as cookies are concerned, setting the cookieless attribute to true (default is false) is all that you have to do. Note that session settings are application-wide settings. In other words, all the pages in your site will, or will not, use cookies to store session IDs. Where is ASP.NET storing the session ID when cookies are not being used? In this case, the session ID is inserted in a particular position within the URL. The figure below shows a snapshot from a real-world site that uses cookieless sessions.

Figure 1. MapPoint using cookieless sessions Imagine you request a page like http://yourserver/folder/default.aspx. As you can see from the MapPoint screenshot, the slash immediately preceding the resource name is expanded to include parentheses with the session ID stuffed inside, as below. The session ID is embedded in the URL and there's no need to persist it anywhere. Well, not exactly.. Consider the following scenario. You visit a page and get assigned a session ID. Next, you clear the address bar of the same browser instance, go to another application and work. Then, you retype the URL of the previous application and, guess what, retrieve your session values as you get in. If you use cookieless sessions, in your second access to the application you're assigned a different session ID and lose all of your previous state. This is a typical side effect of cookieless sessions. To understand why, let's delve deep into the implementation of cookieless sessions.

Implementation:

Page 182

ASP.NET MATERIAL
The implementation of cookieless sessions results from the efforts of two runtime modulesthe standard Session HTTP module named SessionStateModule and an executable known as aspnet_filter.dll. The latter is a small piece of Win32 code acting as an ISAPI filter. HTTP modules and ISAPI filters realize the same idea, except that HTTP modules are made of managed code and require ASP.NET and CLR to trigger and work. Classic ISAPI filters like aspnet_filter.dll are invoked by Internet Information Services (IIS). Both intercept IIS events fired during the processing of the request. When the first request of a new browser session comes in, the session state module reads about the cookie support in the web.config file. If the cookieless attribute of the <sessionState> section is set to true, the module generates a new session ID, mangles the URL by stuffing the session ID just before the resource name, and redirects the browser to the new URL using the HTTP 302 command. When each request arrives at the IIS gatefar before it is handed over to ASP.NET aspnet_filter.dll is given a chance to look at it. If the URL embeds a session ID in parentheses, then the session ID is extracted and copied into a request header named AspFilterSessionId. The URL is then rewritten to look like the originally requested resource and let go. This time the ASP.NET session state module retrieves the session ID from the request header and proceeds with session-state binding. The cookieless mechanism works great as long as the URL contains information that can be used to obtain the session ID. As you'll see in a moment, this poses some usage restrictions. Let's review the pros and cons of cookieless sessions.

Thumbs Up:
In ASP.NET, session management and forms authentication are the only two system features that use cookies under the hood. With cookieless sessions, you can now deploy stateful applications that work regardless of the user's preferences about cookies. As of ASP.NET 1.x, though, cookies are still required to implement forms authentication. The good news is that in ASP.NET 2.0 forms authentication can optionally work in a cookieless fashion. Another common reason advanced against cookies is security. This is a point that deserves a bit more attention.

Page 183

ASP.NET MATERIAL
Cookies are inert text files and as such can be replaced or poisoned by hackers, should they gain access to a machine. The real threat lies not much in what cookies can install on your client machine, but in what they can upload to the target site. Cookies are not programs and never run like programs; other software that gets installed on your machine, though, can use the built-in browser support for cookies to do bad things remotely. Furthermore, cookies are at risk of theft. Once stolen, a cookie that contains valuable and personal information can disclose its contents to malicious hackers and favor other types of Web attacks. In summary, by using cookies you expose yourself to risks that can be zeroed off otherwise. Really?

Thumbs Down:
Let's look at security from another perspective. Have you ever heard of session hijacking? If not, take a look at the TechNet Magazine article Theft On The Web: Prevent Session Hijacking. In brief, session hijacking occurs when an attacker gains access to the session state of a particular user. Basically, the attacker steals a valid session ID and uses that to get into the system and snoop into the data. One common way to get a valid session ID is stealing a valid session cookie. That said, if you think that cookieless sessions put your application on the safe side, you're deadly wrong. With cookieless sessions, in fact, the session ID shows up right in the address bar! Try the following: 1. Connect to a Web site that uses cookieless sessionsfor example, MapPoint and get a map. At this point, the address is stored in the session state. 2. Grab the URL up to the page name. Don't include the query string but make sure the URL includes the session ID. 3. Save the URL to a file and copy/send the file to another machine. 4. On the second machine, open the file and paste the URL in a new instance of the browser. 5. The same map shows up as long as the session timeout is still valid. With cookieless sessions, stealing session IDs is easier than ever. I believe we all agree that stealing sessions is a reprehensible action from an ethical point of view. But is it injurious as well? That depends on what is actually stored in the session state. Stealing a session ID per se doesn't execute an action out of the code control. But it could disclose private data to unauthorized users and enable the bad guy to execute unauthorized operations. Read Wicked Code: Foiling Session Hijacking Attempts for tips on how to block session hijacking in ASP.NET applications. (And, yes, it doesn't rely on cookieless sessions!)

Page 184

ASP.NET MATERIAL
Using cookieless sessions also raises issues with links. For example, you can't have absolute, fully qualified links in your ASP.NET pages. If you do this, each request that originates from that hyperlink will be considered as part of a new session. Cookieless sessions require that you always use relative URLs, like in ASP.NET postbacks. You can use a fully qualified URL only if you can embed the session ID in it. But how can you do that, since session IDs are generated at run time? The following code breaks the session:
<a runat="server" href="/test/page.aspx">Click</a>

To use absolute URLs, resort to a little trick that uses the ApplyAppPathModifier method on the HttpResponse class:
<a runat="server" href=<% >Click</a> =Response.ApplyAppPathModifier("/test/page.aspx")%>

The ApplyAppPathModifier method takes a string representing a URL and returns an absolute URL that embeds session information. For example, this trick is especially useful in situations in which you need to redirect from a HTTP page to an HTTPS page. Finally, be conscious that every time you type a path to a site from within the same browser you're going to lose your state with cookieless sessions. As a further warning, be aware that cookieless sessions can be problematic with mobile applications if the device can't handle the specially formatted URL.

Summary:
The main reason for cookieless sessions in ASP.NET is that usersfor whatever reasons may have cookies disabled on their browsers. Like it or not, this is a situation you have to face if your application requires session state. Cookieless sessions embed the session ID in the URL and obtain a two-fold result. On the one hand, they provide a way for the Web site to correctly identify the user making the request. On the other hand, though, they make the session ID clearly visible to potential hackers who can easily steal it and represent themselves as you. To implement cookieless sessions you don't have to modify your programming modela simple change in the web.config file does the trickbut refactoring your application to avoid storing valuable information in the session state is strongly recommended too. At

Page 185

ASP.NET MATERIAL
the same time, reducing the lifetime of a session to less than the default 20 minutes can help in keeping your users and your site safe.

ASP.NET SECURITY
ASP.NET Impersonation:
When using impersonation, ASP.NET applications can optionally execute with the identity of the client on whose behalf they are operating. The usual reason for doing this is to avoid dealing with authentication and authorization issues in the ASP.NET application code. Instead, you rely on Microsoft Internet Information Services (IIS) to authenticate the user and either pass an authenticated token to the ASP.NET application or, if unable to authenticate the user, pass an unauthenticated token. In either case, the ASP.NET application impersonates whichever token is received if impersonation is enabled. The ASP.NET application, now impersonating the client, then relies on the

Page 186

ASP.NET MATERIAL
settings in the NTFS directories and files to allow it to gain access, or not. Be sure to format the server file space as NTFS, so that access permissions can be set. Impersonation is disabled by default. For ASP compatibility, the user must explicitly enable impersonation. If impersonation is enabled for a given application, ASP.NET always impersonates the access token that IIS provides to ISAPI extensions. That token can be either an authenticated user token, or the token for the anonymous user (such as IUSR_MACHINENAME). The impersonation occurs regardless of the type of authentication being used in the application. Only application code is impersonated; compilation and configuration are read as the process token. The result of the compilation is put in the "Temporary ASP.NET files" directory. The account that is being impersonated needs to have read/write access to this directory. If an application is on a universal naming convention (UNC) share, ASP.NET will always impersonate the token provided to IIS to access that share unless a configured account is used. If an explicit configured account is provided, ASP.NET will use that account in preference to the IIS UNC token. Applications that do want per-request impersonation can simply be configured to impersonate the user making the request. Impersonation is disabled at the computer level by default and, unless overridden, all the application domains inherit this setting. You can enable impersonation by putting a configuration file in the application root directory. For more information about the ASP.NET configuration system, see ASP.NET Configuration. As is the case with other configuration directives, this directive applies hierarchically. It is respected by nested applications in the hierarchy, unless explicitly overridden. The default value for this setting is as follows.

<impersonation enable="false"/>

A minimal configuration file to enable impersonation for an application might look similar to the following example.
<!-- Web.config file. --> <identity impersonate="true"/>

There is also name support for running an application as a configurable identity. For example:
<identity impersonate="true" userName="contoso\Jane" password="pass"/>

Page 187

ASP.NET MATERIAL
This enables the entire application to run as contoso\Jane, regardless of the identity of the request, as long as the password is correct. This type of impersonation can be delegated to another computer. You can programmatically read the identity of the impersonated user, as shown in the following example.
This language is not supported or no code example is available.

In the preceding example, userName and password are stored in clear text in the configuration file. Although IIS will not transmit .config files in response to a user agent request, configuration files can be read by other means, for instance by an authenticated user with proper credentials on the domain that contains the server. To help increase security, the identity section supports storage of encrypted userName and password attributes in the registry as shown in the following example.
userName="registry:HKLM\Software\AspNetIdentity,Name" password="registry:HKLM\Software\AspNetIdentity,Password"

The portion of the string after the keyword registry and before the comma indicates the name of the registry key that ASP.NET opens. The portion after the comma contains a single string value name from which ASP.NET will read the credentials. The comma is required, and the credentials must be stored in the HKLM hive. If the configuration format is incorrect, ASP.NET will not launch the worker process and the current account creation failure code path will be followed. The credentials must be in REG_BINARY format, containing the output of a call to the Windows API function CryptProtectData. You can create the encrypted credentials and store them in the registry with the ASP.NET Set Registry console application(Aspnet_setreg.exe), which uses CryptProtectData to accomplish the encryption. To download Aspnet_setreg.exe, along with the Visual C++ source code and documentation, visit the Web site www.asp.net and search for "aspnet_setreg". You should configure access to the key storing the encrypted credentials so that access is provided only to Administrators and SYSTEM. Because the key will be read by the ASP.NET process running as SYSTEM, you should set the following permissions: Administrators:F SYSTEM:F CREATOR OWNER:F ProcessAccount:R This provides two lines of defense to protect the data:

Page 188

ASP.NET MATERIAL
The ACL permissions require the identity accessing the data to be an Administrator. 2. An attacker must run code on the server (CryptUnprotectData) to recover the credentials for the account. Authentication & Authorization:
1.

Designing an Authentication and Authorization Strategy:


The following steps identify a process that will help you develop an authentication and authorization strategy for your application: 1. 2. 3. 4. 5. 6. Identify resources Choose an authorization strategy Choose the identities used for resource access Consider identity flow Choose an authentication approach Decide how to flow identity

Identify Resources:
Identify resources that your application needs to expose to clients. Typical resources include:

Web Server resources such as Web pages, Web services, static resources (HTML pages and images). Database resources such as per-user data or application-wide data. Network resources such as remote file system resources and data from directory stores such as Active Directory.

You must also identify the system resources that your application needs to access. This is in contrast to resources that are exposed to clients. Examples of system resources include the registry, event logs and configuration files.

Choose an Authorization Strategy:


The two basic authorization strategies are:

Role based. Access to operations (typically methods) is secured based on the role membership of the caller. Roles are used to partition your application's user base into sets of users that share the same security privileges within the application; for example, Senior Managers, Managers and Employees .Users are mapped to roles

Page 189

ASP.NET MATERIAL
and if the user is authorized to perform the requested operation, the application uses fixed identities with which to access resources. These identities are trusted by the respective resource managers (for example, databases, the file system and so on). Resource based. Individual resources are secured using Windows ACLs. The application impersonates the caller prior to accessing resources, which allows the operating system to perform standard access checks. All resource access is performed using the original caller's security context. This impersonation approach severely impacts application scalability, because it means that connection pooling cannot be used effectively within the application's middle tier.

In the vast majority of .NET Web applications where scalability is essential, a role-based approach to authorization represents the best choice. For certain smaller scale intranet applications that serve per-user content from resources (such as files) that can be secured with Windows ACLs against individual users, a resource-based approach may be appropriate. The recommended and common pattern for role-based authorization is:

Authenticate users within your front-end Web application. Map users to roles. Authorize access to operations (not directly to resources) based on role membership. Access the necessary back-end resources (required to support the requested and authorized operations) by using fixed service identities. The back-end resource managers (for example, databases) trust the application to authorize callers and are willing to grant permissions to the trusted service identity or identities. For example, a database administrator may grant access permissions exclusively to a specific HR application (but not to individual users).

More information

For more information about the two contrasting authorization approaches, see Authorization Approaches later in this chapter. For more information about role-based authorization and the various types of roles that can be used, see Role-Based Authorization later in this chapter.

Choose the Identities Used for Resource Access:


Choose the identity or identities that should be used to access resources across the layers of your application. This includes resources accessed from Web-based applications, and

Page 190

ASP.NET MATERIAL
optionally Web services, Enterprise Services and .NET Remoting components. In all cases, the identity used for resource access can be:

Original caller's identity. This assumes an impersonation/delegation model in which the original caller identity can be obtained and then flowed through each layer of your system. The delegation factor is a key criteria used to determine your authentication mechanism. Process identity. This is the default case (without specific impersonation). Local resource access and downstream calls are made using the current process identity. The feasibility of this approach depends on the boundary being crossed, because the process identity must be recognized by the target system. This implies that calls are made in one of the following ways: Within the same Windows security domain Across Windows security domains (using trust and domain accounts, or duplicated user names and passwords where no trust relationship exists) Service account. This approach uses a (fixed) service account. For example: o For database access this might be a fixed SQL user name and password presented by the component connecting to the database. o When a fixed Windows identity is required, use an Enterprise Services server application. Custom identity. When you don't have Windows accounts to work with, you can construct your own identities (using IPrincipal and IIdentity implementations) that can contain details that relate to your own specific security context. For example, these could include role lists, unique identifiers, or any other type of custom information.
o o

By implementing your custom identity with IPrincipal and IIdentity types and placing them in the current Web context (using HttpContext.User), you immediately benefit from built-in gatekeepers such as .NET roles and PrincipalPermission demands.

Consider Identity Flow


To support per-user authorization, auditing, and per-user data retrieval you may need to flow the original caller's identity through various application tiers and across multiple computer boundaries. For example, if a back-end resource manager needs to perform percaller authorization, the caller's identity must be passed to that resource manager. Based on resource manager authorization requirements and the auditing requirements of your system, identify which identities need to be passed through your application.

Page 191

ASP.NET MATERIAL
Choose an Authentication Approach
Two key factors that influence the choice of authentication approach are first and foremost the nature of your application's user base (what types of browsers are they using and do they have Windows accounts), and secondly your application's impersonation/delegation and auditing requirements.

More information
For more detailed considerations that help you to choose an authentication mechanism for your application, see Choosing an Authentication Mechanism later in this chapter.

Decide How to Flow Identity:


You can flow identity (to provide security context) at the application level or you can flow identity and security context at the operating system level. To flow identity at the application level, use method and stored procedure parameters. Application identity flow supports:

Per-user data retrieval using trusted query parameters


SELECT x,y FROM SomeTable WHERE username="bob"

Custom auditing within any application tier

Operating system identity flow supports:


Platform level auditing (for example, Windows auditing and SQL Server auditing) Per-user authorization based on Windows identities

To flow identity at the operating system level, you can use the impersonation/delegation model. In some circumstances you can use Kerberos delegation, while in others (where perhaps the environment does not support Kerberos) you may need to use other approaches such as, using Basic authentication. With Basic authentication, the user's credentials are available to the server application and can be used to access downstream network resources.

More information
For more information about flowing identity and how to obtain an impersonation token with network credentials (that is, supports delegation), see Flowing Identity later in this chapter.

Page 192

ASP.NET MATERIAL
Authorization Approaches:
There are two basic approaches to authorization:

Role based. Users are partitioned into application-defined, logical roles. Members of a particular role share the same privileges within the application. Access to operations (typically expressed by method calls) is authorized based on the rolemembership of the caller. Resources are accessed using fixed identities (such as a Web application's or Web service's process identity). The resource managers trust the application to correctly authorize users and they authorize the trusted identity.

Resource based. Individual resources are secured using Windows ACLs. The ACL determines which users are allowed to access the resource and also the types of operation that each user is allowed to perform (read, write, delete and so on). Resources are accessed using the original caller's identity (using impersonation).

Role Based:
With a role-based (or operations-based) approach to security, access to operations (not back-end resources) is authorized based on the role membership of the caller. Roles (analyzed and defined at application design time) are used as logical containers that group together users who share the same security privileges (or capabilities) within the application. Users are mapped to roles within the application and role membership is used to control access to specific operations (methods) exposed by the application. Where within your application this role mapping occurs is a key design criterion; for example:

On one extreme, role mapping might be performed within a back-end resource manager such as a database. This requires the original caller's security context to flow through your application's tiers to the back-end database. On the other extreme, role mapping might be performed within your front-end Web application. With this approach, downstream resource managers are accessed using fixed identities that each resource manager authorizes and is willing to trust. A third option is to perform role mapping somewhere in between the front-end and back-end tiers; for example, within a middle tier Enterprise Services application.

Page 193

ASP.NET MATERIAL
In multi-tiered Web applications, the use of trusted identities to access back-end resource managers provides greater opportunities for application scalability (thanks to connection pooling). Also, the use of trusted identities alleviates the need to flow the original caller's security context at the operating system level, something that can be difficult (if not impossible in certain scenarios) to achieve.

Resource Based:
The resource-based approach to authorization relies on Windows ACLs and the underlying access control mechanics of the operating system. The application impersonates the caller and leaves it to the operating system in conjunction with specific resource managers (the file system, databases, and so on) to perform access checks. This approach tends to work best for applications that provide access to resources that can be individually secured with Windows ACLs, such as files. An example would be an FTP application or a simple data driven Web application. The approach starts to break down where the requested resource consists of data that needs to be obtained and consolidated from a number of different sources; for example, multiple databases, database tables, external applications or Web services. The resource-based approach also relies on the original caller's security context flowing through the application to the back-end resource managers. This can require complex configuration and significantly reduces the ability of a multi-tiered application to scale to large numbers of users, because it prevents the efficient use of pooling (for example, database connection pooling) within the application's middle tier.

Resource Access Models:


The two contrasting approaches to authorization can be seen within the two most commonly used resource-access security models used by .NET Web applications (and distributed multi-tier applications in general). These are:

The trusted subsystem model The impersonation/delegation model

Each model offers advantages and disadvantages both from a security and scalability perspective. The next sections describe these models.

The Trusted Subsystem Model:


With this model, the middle tier service uses a fixed identity to access downstream services and resources. The security context of the original caller does not flow through

Page 194

ASP.NET MATERIAL
the service at the operating system level, although the application may choose to flow the original caller's identity at the application level. It may need to do so to support back-end auditing requirements, or to support per-user data access and authorization. The model name stems from the fact that the downstream service (perhaps a database) trusts the upstream service to authorize callers. Figure 3.1 shows this model. Pay particular attention to the trust boundary. In this example, the database trusts the middle tier to authorize callers and allow only authorized callers to access the database using the trusted identity.

Figure 3.1. The Trusted Subsystem model The pattern for resource access in the trusted subsystem model is the following:

Authenticate users Map users to roles Authorize based on role membership Access downstream resource manager using a fixed trusted identity

Fixed identities:
The fixed identity used to access downstream systems and resource managers is often provided by a preconfigured Windows account, referred to as a service account. With a Microsoft SQL Server resource manager, this implies Windows authentication to SQL Server. Alternatively, some applications use a nominated SQL account (specified by a user name and password in a connection string) to access SQL Server. In this scenario, the database must be configured for SQL authentication.

Page 195

ASP.NET MATERIAL
Using multiple trusted identities:
Some resource managers may need to be able to perform slightly more fine-grained authorization, based on the role membership of the caller. For example, you may have two groups of users, one who should be authorized to perform read/write operations and the other read-only operations. Consider the following approach with SQL Server:

Create two Windows accounts, one for read operations and one for read/write operations. More generally, you have separate accounts to mirror application-specific roles. For example, you might want to use one account for Internet users and another for internal operators and/or administrators.

Map each account to a SQL Server user-defined database role, and establish the necessary database permissions for each role. Map users to roles within your application and use role membership to determine which account to impersonate before connecting to the database.

Figure 3.2. Using multiple identities to access a database to support more finegrained authorization

The Impersonation / Delegation Model:


With this model, a service or component (usually somewhere within the logical business services layer) impersonates the client's identity (using operating system-level impersonation) before it accesses the next downstream service. If the next service in line is on the same computer, impersonation is sufficient. Delegation is required if the downstream service is located on a remote computer.

Page 196

ASP.NET MATERIAL
As a result of the delegation, the security context used for the downstream resource access is that of the client. This model is typically used for a couple of reasons:

It allows the downstream service to perform per-caller authorization using the original caller's identity. It allows the downstream service to use operating system-level auditing features.

As a concrete example of this technique, a middle-tier Enterprise Services component might impersonate the caller prior to accessing a database. The database is accessed using a database connection tied to the security context of the original caller. With this model, the database authenticates each and every caller and makes authorization decisions based on permissions assigned to the individual caller's identity (or the Windows group membership of the caller). The impersonation/delegation model is shown in Figure 3.3.

Figure 3.3. The impersonation/delegation model

Choosing a Resource Access Model:


The trusted subsystem model is used in the vast majority of Internet applications and large-scale intranet applications, primarily for scalability reasons. The impersonation model tends to be used in smaller-scale applications where scalability is not the primary concern and those applications where auditing (for reasons of non-repudiation) is a critical concern.

Advantage of the impersonation / delegation model:


The primary advantage of the impersonation / delegation model is auditing (close to the data). Auditing allows administrators to track which users have attempted to access specific resources. Generally auditing is considered most authoritative if the audits are generated at the precise time of resource access and by the same routines that access the resource.

Page 197

ASP.NET MATERIAL
The impersonation / delegation model supports this by maintaining the user's security context for downstream resource access. This allows the back-end system to authoritatively log the user and the requested access.

Disadvantages of the impersonation / delegation model:


The disadvantages associated with the impersonation / delegation model include:

Technology challenges. Most security service providers don't support delegation, Kerberos is the notable exception. Processes that perform impersonation require higher privileges (specifically the Actas part of the operating system privilege). This restriction applies to Windows 2000 and does not apply to Windows Server 2003.

Scalability. The impersonation / delegation model means that you cannot effectively use database connection pooling, because database access is performed by using connections that are tied to the individual security contexts of the original callers. This significantly limits the application's ability to scale to large numbers of users. Increased administration effort. ACLs on back-end resources need to be maintained in such a way that each user is granted the appropriate level of access. When the number of back-end resources increases (and the number of users increases), a significant administration effort is required to manage ACLs.

Advantages of the trusted subsystem model:


The trusted subsystem model offers the following advantages:

Scalability. The trusted subsystem model supports connection pooling, an essential requirement for application scalability. Connection pooling allows multiple clients to reuse available, pooled connections. It works with this model because all back-end resource access uses the security context of the service account, regardless of the caller's identity. Minimizes back-end ACL management. Only the service account accesses back-end resources (for example, databases). ACLs are configured against this single identity. Users can't access data directly. In the trusted-subsystem model, only the middle-tier service account is granted access to the back-end resources. As a result, users cannot directly access back-end data without going through the application (and being subjected to application authorization).

Page 198

ASP.NET MATERIAL
Disadvantages of the trusted subsystem model:
The trusted-subsystem model suffers from a couple of drawbacks:

Auditing. To perform auditing at the back end, you can explicitly pass (at the application level) the identity of the original caller to the back end, and have the auditing performed there. You have to trust the middle-tier and you do have a potential repudiation risk. Alternatively, you can generate an audit trail in the middle tier and then correlate it with back-end audit trails (for this you must ensure that the server clocks are synchronized). Increased risk from server compromise. In the trusted-subsystem model, the middle-tier service is granted broad access to back-end resources. As a result, a compromised middle-tier service potentially makes it easier for an attacker to gain broad access to back-end resources.

Flowing Identity:
Distributed applications can be divided into multiple secure subsystems. For example, a front-end Web application, a middle-tier Web service, a remote component, and a database represent four different security subsystems. Each performs authentication and authorization. You must identify those subsystems that must flow the caller's identity (and associated security context) to the next downstream subsystem in order to support authorization against the original caller.

Application vs. Operating System Identity Flow:


Strategies for flowing identities include using the delegation features of the operating system or passing tickets and/or credentials at the application level. For example:

To flow identity at the application level, you typically pass credentials (or tickets) using method arguments or stored procedure parameters. Note GenericPrincipal objects that carry the authenticated callers identity do not automatically flow across processes. This requires custom code. You can pass parameters to stored procedures that allow you to retrieve and process user-specific data. For example:
SELECT CreditLimit From Table Where UserName=Bob

This approach is sometimes referred to as a trusted query parameter approach.

Page 199

ASP.NET MATERIAL

Operating system identity flow requires an extended form of impersonation called delegation.

Impersonation and Delegation:


Under typical circumstances, threads within a server application run using the security context of the server process. The attributes that comprise the process' security context are maintained by the process' logon session and are exposed by the process level Windows access token. All local and remote resource access is performed using the process level security context that is determined by the Windows account used to run the server process.

Impersonation:
When a server application is configured for impersonation or uses programmatic impersonation, an impersonation token is attached to the thread used to process a request. The impersonation token represents the security context of the authenticated caller (or anonymous user). Any local resource access is performed using the thread impersonation token that results in the use of the caller's security context.

Delegation:
If the server application thread attempts to access a remote resource, delegation is required. Specifically, the impersonated caller's token must have network credentials. If it doesn't, all remote resource access is performed as the anonymous user (AUTHORITY\ANONYMOUS LOGON). There are a number of factors that determine whether or not a security context can be delegated. Table 3.1 shows the various IIS authentication types and for each one indicates whether or not the security context of the authenticated caller can be delegated. Table 3.1. IIS Authentication types Authentication Can Notes Type Delegate If the anonymous account (by default IUSR_MACHINE) is configured in IIS as a local account, it cannot be delegated unless the local (Web server) and remote computer have Anonymous Depends identical local accounts (with matching usernames and passwords). If the anonymous account is a domain account it can be delegated.

Page 200

ASP.NET MATERIAL
Basic Digest Yes No Integrated Windows authentication either results in NTLM or Kerberos (depending upon the version of operating system on client and server computer). NTLM does not support delegation. Depends Kerberos supports delegation with a suitably configured environment. For more information, see How To: Implement Kerberos Delegation for Windows 2000 in the References section of this guide. Can be delegated if used with IIS certificate mapping and the certificate is mapped to a local account that is duplicated on the remote computer or is mapped to a domain account. This works because the credentials for the mapped account Depends are stored on the local server and are used to create an Interactive logon session (which has network credentials). Active Directory certificate mapping does not support delegation. If Basic authentication is used with local accounts, it can be delegated if the local accounts on the local and remote computers are identical. Domain accounts can also be delegated.

Integrated Windows

Client Certificates

Important Kerberos delegation under Windows 2000 is unconstrained. In other words, a user may be able to make multiple network hops across multiple remote computers. To close this potential security risk, you should limit the scope of the domain account's reach by removing the account from the Domain Users group and allow the account to be used only to log on to specific computers. Note Windows Server 2003 introduces constrained delegation, which can be used to restrict the delegation to a particular service on a particular server.

Role-Based Authorization:
Most .NET Web applications will use a role-based approach for authorization. You need to consider the various role types and choose the one(s) most appropriate for your application scenario. You have the following options:

.NET roles Enterprise Services (COM+) roles SQL Server User Defined Database roles SQL Server Application roles

Page 201

ASP.NET MATERIAL
.NET Roles:
.NET roles are extremely flexible and can be used within Web applications, Web services, or remote components hosted within ASP.NET (and accessed using the HttpChannel). You can perform authorization using .NET roles either declaratively by using PrincipalPermission demands, or programmatically in code by using imperative PrincipalPermission demands or the IPrincipal.IsInRole method.

.NET roles with Windows authentication:


If your application uses a non-Windows authentication mechanism such as Forms or Passport, you must write code to create a GenericPrincipal object (or a custom IPrincipal object) and populate it with a set of roles obtained from a custom authentication data store such as a SQL Server database.

.NET roles with non-Windows authentication:


If your application uses a non-Windows authentication mechanism such as Forms or Passport, you must write code to create a GenericPrincipal object (or a custom IPrincipal object) and populate it with a set of roles obtained from a custom authentication data store such as a SQL Server database.

Custom IPrincipal objects


The .NET Role-based security mechanism is extensible. You can develop your own classes that implement IPrincipal and IIdentity and provide your own extended rolebased authorization functionality. As long as the custom IPrincipal object (containing roles obtained from a custom data store) is attached to the current request context (using HttpContext.User), basic rolechecking functionality is ensured. By implementing the IPrincipal interface, you ensure that both the declarative and imperative forms of PrincipalPermission demands work with your custom identity. Furthermore, you can implement extended role semantics; for example, by providing an additional method such as IsInMultipleRoles( string [] roles ) which would allow you to test and assert for membership of multiple roles.

Page 202

ASP.NET MATERIAL
Enterprise Services (COM+) Roles:
Using Enterprise Services (COM+) roles pushes access checks to the middle tier and allows you to use database connection pooling when connecting to back-end databases. However, for meaningful Enterprise Services (COM+) role-based authorization, your front-end Web application must impersonate and flow the original caller's identity (using a Windows access token) to the Enterprise Services application. To achieve this, the following entries must be placed in the Web application's Web.config file.
<authentication mode="Windows" /> <identity impersonate="true" />

If it is sufficient to use declarative checks at the method level (to determine which users can call which methods), you can deploy your application and update role membership using the Component Services administration tool. If you require programmatic checks in method code, you lose some of the administrative and deployment advantages of Enterprise Services (COM+) roles, because role logic is hard-coded.

SQL Server User Defined Database Roles:


With this approach, you create roles in the database, assign permissions based on the roles and map Windows group and user accounts to the roles. This approach requires you to flow the caller's identity to the back end (if you are using the preferred Windows authentication to SQL Server).

SQL Server Application Roles:


With this approach, permissions are granted to the roles within the database, but SQL Server application roles contain no user or group accounts. As a result, you lose the granularity of the original caller. With application roles, you are authorizing access to a specific application (as opposed to a set of users). The application activates the role using a built-in stored procedure that accepts a role name and password. One of the main disadvantages of this approach is that it requires the application to securely manage credentials (the role name and associated password).

.NET Roles versus Enterprise Services (COM+) Roles:


The following table presents a comparison of the features of .NET roles and Enterprise Services (COM+) roles.

Page 203

ASP.NET MATERIAL
Table 3.2. Comparing Enterprise Services roles with .NET roles Feature Administration Data Store Declarative Enterprise Services Roles Component Services Administration Tool COM+ Catalog Yes [SecurityRole("Manager")] Yes ContextUtil.IsCallerInRole() .NET Roles Custom Custom data store (for example, SQL Server or Active Directory) Yes [PrincipalPermission( SecurityAction.Demand, Role="Manager")] Yes (IPrincipal.IsInRole, and additionally Roles.IsUserInRole if you are running ASP.Net 2.0) Yes Yes (using custom IPrincipal implementation, and additionally creating a custom role provider if you are running ASP.NET 2.0) Yes When using WindowsPrincipals, roles ARE Windows groupsno extra level of abstraction

Imperative

Class, Interface and Method Level Yes Granularity Extensible No

Only for components that Available to all derive from ServicedComponent .NET components base class Role Membership Requires explicit Interface implementation Roles contain Windows group or user accounts

Yes To obtain method level No authorization, an interface must be explicitly defined and implemented

Using .NET Roles:


You can secure the following items with .NET roles:

Files Folders Web pages (.aspx files) Web services (.asmx files)

Page 204

ASP.NET MATERIAL

Objects Methods and properties Code blocks within methods

The fact that you can use .NET roles to protect operations (performed by methods and properties) and specific code blocks means that you can protect access to local and remote resources accessed by your application. To use .NET roles with a non-Windows authentication mechanism, you must write code to:

Capture the user's credentials. Validate the user's credentials against a custom data store such as a SQL Server database. Retrieve a role list, construct a GenericPrincipal object and associate it with the current Web request. Note When using the Role Manager feature of ASP.NET 2.0, you do not need to populate the GenericPrincipal class with the role set. The Role Manager feature automatically obtains the role information for the user. The GenericPrincipal object represents the authenticated user and is used for subsequent .NET role checks, such as declarative PrincipalPermission demands and programmatic IPrincipal.IsInRole checks.

Checking role membership:


The following types of .NET role checks are available: Important .NET role checking relies upon an IPrincipal object (representing the authenticated user) being associated with the current request. For ASP.NET Web applications, the IPrincipal object must be attached to HttpContext.User. For Windows Forms applications, the IPrincipal object must be attached to Thread.CurrentPrincipal.

Manual role checks. For fine-grained authorization, you can call the IPrincipal.IsInRole method to authorize access to specific code blocks based on the role membership of the caller. Both AND and OR logic can be used when checking role membership. Additionally, when using the Role Manager feature of ASP.Net 2.0, you can use Role APIs such as Role.IsUserInRole. Declarative role checks (gates to your methods). You can annotate methods with the PrincipalPermissionAttribute class (which can be shortened to PrincipalPermission), to declaratively demand role membership. These support OR logic only. For example you can demand that a caller is in at least one specific

Page 205

ASP.NET MATERIAL
role (for example, the caller must be a teller or a manager). You cannot specify that a caller must be a manager and a teller using declarative checks. Imperative role checks (checks within your methods). You can call PrincipalPermission.Demand within code to perform fine-grained authorization logic. Logical AND and OR operations are supported.

Choosing an Authentication Mechanism:


This section presents guidance that is designed to help you choose an appropriate authentication mechanism for common application scenarios. You should start by considering the following issues:

Identities. A Windows authentication mechanism is appropriate only if your application's users have Windows accounts that can be authenticated by a trusted authority accessible by your application's Web server. Credential management. One of the key advantages of Windows authentication is that it enables you to let the operating system take care of credential management. With non-Windows approaches, such as Forms authentication, you must carefully consider where and how you store user credentials. The two most common approaches are to use: o SQL Server databases o User objects within Active Directory Identity flow. Do you need to implement an impersonation/delegation model and flow the original caller's security context at the operating system level across tiers? For example, to support auditing or per-user (granular) authorization. If so, you need to be able to impersonate the caller and delegate their security context to the next downstream subsystem, as described in the "Delegation" section earlier in this chapter. Browser type. Do your users all have Internet Explorer or do you need to support a user base with mixed browser types? Table 3.3 illustrates which authentication mechanisms require Internet Explorer browsers, and which support a variety of common browser types. Table 3.3. Authentication browser requirements Authentication Type Forms Passport Requires Internet Explorer No No Notes

Page 206

ASP.NET MATERIAL
Integrated Windows (Kerberos or Yes NTLM) Basic Digest Certificate No Yes No Kerberos also requires Windows 2000 or later operating systems on the client and server computers. For more information, see How To: Implement Kerberos Delegation for Windows 2000 in the Reference section of this guide. Basic authentication is part of the HTTP 1.1 protocol that is supported by virtually all browsers Clients require X.509 certificates

Internet Scenarios:

The basic assumptions for Internet scenarios are: o Users do not have Windows accounts in the server's domain or in a trusted domain accessible by the server. o Users do not have client certificates.

Figure 3.4 shows a decision tree for choosing an authentication mechanism for Internet scenarios.

Figure 3.4. Choosing an authentication mechanism for Internet applications

Forms / Passport comparison:


This section summarizes the relative merits of Forms and Passport authentication.

Advantages of Forms authentication:

Supports authentication against a custom data store; typically a SQL Server database or Active Directory.

Page 207

ASP.NET MATERIAL

Supports role-based authorization with role lookup from a data store. Smooth integration with Web user interface. ASP.NET provides much of the infrastructure.

Advantages of Passport authentication


Passport is a centralized solution. It removes credential management issues from the application. It can be used with role-based authorization schemes. It is very secure as it is built on cryptography technologies.

Intranet / Extranet Scenarios:


Figure 3.5 shows a decision tree that can be used to help choose an authentication mechanism for intranet and extranet application scenarios.

Figure 3.5. Choosing an authentication mechanism for intranet and extranet applications

Authentication Mechanism Comparison:


The following table presents a comparison of the available authentication mechanisms.

Page 208

ASP.NET MATERIAL
Table 3.4: Available authentication methods Basic Digest NTLM Kerberos Certs Forms Passport Users need Windows accounts in Yes Yes server's domain Supports delegation* Yes No Yes No No No No Yes Yes Yes No No No Can do No No Yes No Yes No Yes Yes No Yes No No Yes

Requires Win2K clients and No Yes servers Credentials passed as clear text Yes No (requires SSL) Supports non-IE browsers Yes No

Summary:

Designing distributed application authentication and authorization approaches is a challenging task. Proper authentication and authorization design during the early design phases of your application development helps mitigate many of the top security risks. The following summarizes the information in this chapter: o Use the trusted subsystem resource access model to gain the benefits of database connection pooling. o If your application does not use Windows authentication, use .NET role checking to provide authorization. Validate credentials against a custom data store, retrieve a role list and create a GenericPrincipal object. Associate it with the current Web request (HttpContext.User). o If your application uses Windows authentication and doesn't use Enterprise Services, use .NET roles. Remember that for Windows authentication, .NET roles are Windows groups. o If your application uses Windows authentication and Enterprise Services, consider using Enterprise Services (COM+) roles. o For meaningful role-based authorization using Enterprise Services (COM+) roles, the original caller's identity must flow to the Enterprise Services application. If the Enterprise Services application is called from an ASP.NET Web application, this means that the Web application must use Windows authentication and be configured for impersonation. o Annotate methods with the PrincipalPermission attribute to declaratively demand role membership. The method is not called if the caller is not in the specified role and a security exception is generated. o Call PrincipalPermission.Demand within method code (or use IPrincipal.IsInRole, if you are running ASP.NET 2.0 with the Role

Page 209

ASP.NET MATERIAL
Manager feature, use Role API such as Roles.IsUserInRole for finegrained authorization decisions. Consider implementing a custom IPrincipal object to gain additional rolechecking semantics.

Windows Based Authentication:

Configuring Windows Authentication:


To configure your application to use Integrated Windows authentication, you must use IIS Manager to configure your application's virtual directory security settings and you must configure the <authentication> element in the Web.config file. To configure Windows authentication 1. 2. 3. 4. 5. Start Internet Information Services (IIS). Right-click your application's virtual directory, and then click Properties. Click the Directory Security tab. Under Anonymous access and authentication control, click Edit. Make sure the Anonymous access check box is not selected and that Integrated Windows authentication is the only selected check box.

In your application's Web.config file or in the machine-level Web.config file, ensure that the authentication mode is set to Windows as shown here.
... <system.web> ... <authentication mode="Windows"/> ... </system.web> ...

Using Impersonation with Windows Authentication :


By using impersonation, ASP.NET applications can execute code or access resources with the identity of the authenticated user or a fixed Windows identity. Standard impersonate-level impersonation tokens that are usually created when you enable impersonation allow you to access local resources only. To be able to access remote network resources, you require a delegate-level token. To generate a delegate-level token

Page 210

ASP.NET MATERIAL
when you impersonate, you need to use Kerberos authentication and your process account needs to be marked as trusted for delegation in Active Directory. By default, ASP.NET applications are not configured for impersonation. You can confirm this by reviewing the identity settings in the Machine.config.comments file. %windir%\Microsoft.Net\Framework\{Version}\CONFIG.

The <identity> element is configured as follows. Note that impersonation is disabled.


<identity impersonate="false" userName="" password="" />

Impersonating the Original Caller with Windows Authentication:


When you configure your application for impersonation, an impersonation token for the authenticated user is attached to the Web request thread. As a result, all local resource access is performed using the caller's identity. To configure ASP.NET to use Windows authentication with impersonation, use the following configuration.
... <system.web> ... <authentication mode="Windows"/> <identity impersonate="true"/> ... </system.web> ...

The resulting impersonation token and associated logon session does not have network credentials. If you access this Web site from a browser while logged onto a different machine in the same domain and the Web site attempts to access network resources, you end up with a null session on the remote server and the resource access will fail. To access remote resources, you need delegation.

Impersonating a Fixed Identity with Windows Authentication :


You can configure ASP.NET to impersonate a fixed identity. You specify the credentials of the impersonated identity on the <identity> element in the Web.config file as shown here.

Page 211

ASP.NET MATERIAL
... <system.web> ... <authentication mode="Windows"/> <identity impersonate="true" password="<password>"/> ... </system.web> ...

userName="<domain>\<UserName>"

If you specify credentials on the <identity> element, make sure they are stored in encrypted format by using the Aspnet_regiis.exe tool.

Impersonating the Original Caller Programmatically:


If you only require an impersonated identity to access specific resources or perform specific operations and can use your process identity the rest of the time, you can use programmatic impersonation to temporarily enable impersonation. To temporarily impersonate the authenticated user This procedure shows you how to temporarily impersonate the original caller by using the Windows token that is passed by IIS to your Web application and is available through the HttpContext object. 1. Check that your ASP.NET application is not configured for impersonation by ensuring that impersonate is set to false on the <identity> element in the Web.config file.
2. ... 3. <system.web> 4. ... 5. <authentication mode="Windows"/> 6. <identity impersonate="false"/> 7. ... 8. </system.web> 9. ...

10. Obtain the authenticated user's Windows token.


11. IIdentity WinId= HttpContext.Current.User.Identity; 12. WindowsIdentity wi = (WindowsIdentity)WinId;

13. Use the authenticated user's Windows token to temporarily impersonate the original user and remove the impersonation token from the current thread when you are finished impersonating.
14. // Temporarily impersonate the original user.

Page 212

ASP.NET MATERIAL
15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. WindowsImpersonationContext wic = wi.Impersonate(); try { // Access resources while impersonating. } catch { // Prevent exceptions propagating. } finally { // Revert impersonation. wic.Undo(); }

Authorizing Windows Users:


When you use Windows authentication to authenticate users, you can use the following authorization options:

File authorization provided by the FileAuthorizationModule. URL authorization provided by the UrlAuthorizationModule. Role-based authorization.

Configuring Windows ACLs for File Authorization:


Requests for file types mapped to the ASP.NET ISAPI extension are checked by the FileAuthorizationModule. When you use Windows authentication, the authenticated user's Windows token is compared against the ACL attached to the requested file. For static files types that are not mapped to the ASP.NET ISAPI extension, IIS performs access checks again by using the authenticated user's access token and the ACL attached to the file. You need to configure appropriate ACLs on the file types directly requested by the user and on the files and other Windows resources accessed by your application, as described here:

Forresources directly requested by the user. For resources such as Web pages (.aspx files) and Web services (.asmx files) directly requested by the user, the authenticated user's Windows access token is compared against the Windows ACL attached to the file. Make sure that the authenticated user is allowed to access the appropriate Web pages and Web services. For resources that the application accesses. If impersonation is enabled, resources such as files, databases, registry keys, and Active Directory objects are accessed by using the impersonated identity. Otherwise, your application's process identity, such as the Network Service account, is used for resource access.

Page 213

ASP.NET MATERIAL
For the resource access attempt to succeed, the ACL attached to these resources must be suitably configured to allow the process account or impersonated identity the access it requests, such as read access, or write access.

Configuring URL Authorization:


When you use Windows authentication, the UrlAuthorizationModule checks the access to requested files and folders based on the authenticated caller's identity. This is true regardless of whether your application is configured for impersonation. To configure URL authorization, add an <authorization> element to the Web.config file, and specify the domain name and user or group name when configuring <deny> and <allow> elements, as shown here.
<authorization> <deny users="DomainName\UserName" /> <allow roles="DomainName\WindowsGroup" /> </authorization> When you use Windows authentication, user names take the form domainName\userName. Windows groups are used as roles and they take the form domainName\windowsGroupName. Well known local groups such as Administrators and Users are referenced by using the "BUILTIN" prefix as shown here. <authorization> <allow users="DomainName\Bob, DomainName\Mary" /> <allow roles="BUILTIN\Administrators, DomainName\Manager" /> <deny users="*" /> </authorization>

Checking Role Membership in Code:


With Windows authentication, the user's Windows group membership can be used to determine the role membership and Window groups become the roles. You can perform role-based authorization in code either by performing explicit role checks (User.IsInRole or Roles.IsUserInRole), or by using PrincipalPermission demands. You can do the latter either imperatively in the body of a method or declaratively by adding attributes to your classes and methods. To use explicit role checks:

Use the IPrincipal interface of the User object attached to the current HTTP request. This approach works with ASP.NET versions 1.0, 1.1. and 2.0. When using Windows authentication, make sure to use the domainName\userName

Page 214

ASP.NET MATERIAL
format for the user name and the format domainName\groupName for the group name.
if(User.IsInRole(@"DomainName\Manager")) // Perform restricted operation else // Return unauthorized access error.

Alternatively, use role manager APIs introduced in ASP.NET version 2.0, which supports a similar Roles.IsUserInRole method, as shown here.
if(Roles.IsUserInRole(@"DomainName\Manager")) // Perform restricted operation else // Return unauthorized access error.

To use the role manager API, you must enable role manager. With Windows authentication, you can use the built-in AspNetWindowsTokenRoleProvider, which uses Windows groups as roles. To enable role manager and select this provider, add the following configuration to your Web.config file.
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider"/> When you use Windows authentication, you can use alternate role providers, such as the AuthorizationStoreRoleProvider and SqlRoleProvider, if you need to store roles in alternate role stores such as Authorization Manager policy stores or SQL Server databases.

To use PrincipalPermission demands


Construct a PrincipalPermission object, and then call its Demand method to perform authorization. For fine grained authorization, call PrincipalPermission.Demand within code, as shown here.
using System.Security.Permissions; ... // Imperative checks PrincipalPermission permCheckUser PrincipalPermission(@"Domain\Bob", null); permCheckUser.Demand();

new

Alternatively, you can decorate your classes PrincipalPermissionAttribute, as shown here.

or

methods

with

the

Page 215

ASP.NET MATERIAL
using System.Security.Permissions; ... [PrincipalPermission(SecurityAction.Demand,Role=@"Builtin\Admini strators")].

Forms Based Authentication:

ASP.NET Forms Authentication:


ASP.NET forms authentication occurs after IIS authentication is completed. You can configure forms authentication with the forms element.

Forms Authentication Configuration:


The default attribute values for forms authentication are shown in the following configuration-file fragment.
<system.web> <authentication mode="Forms"> <forms loginUrl="Login.aspx" protection="All" timeout="30" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="true" defaultUrl="default.aspx" cookieless="UseDeviceProfile" enableCrossAppRedirects="false" /> </authentication> </system.web>

The default attribute values are described below:

loginUrl points to your application's custom logon page. You should place the logon page in a folder that requires Secure Sockets Layer (SSL). This helps ensure the integrity of the credentials when they are passed from the browser to the Web server. protection is set to All to specify privacy and integrity for the forms authentication ticket. This causes the authentication ticket to be encrypted using the algorithm specified on the machineKey element, and to be signed using the hashing algorithm that is also specified on the machineKey element.

Page 216

ASP.NET MATERIAL

timeout is used to specify a limited lifetime for the forms authentication session. The default value is 30 minutes. If a persistent forms authentication cookie is issued, the timeout attribute is also used to set the lifetime of the persistent cookie. name and path are set to the values defined in the application's configuration file. requireSSL is set to false. This configuration means that authentication cookies can be transmitted over channels that are not SSL-encrypted. If you are concerned about session hijacking, you should consider setting requireSSL to true. slidingExpiration is set to true to enforce a sliding session lifetime. This means that the session timeout is periodically reset as long as a user stays active on the site. defaultUrl is set to the Default.aspx page for the application. cookieless is set to UseDeviceProfile to specify that the application use cookies for all browsers that support cookies. If a browser that does not support cookies accesses the site, then forms authentication packages the authentication ticket on the URL. enableCrossAppRedirects is set to false to indicate that forms authentication does not support automatic processing of tickets that are passed between applications on the query string or as part of a form POST.

Authorization Configuration:
In IIS, anonymous access is enabled for all applications that use forms authentication. The UrlAuthorizationModule class is used to help ensure that only authenticated users can access a page. You can configure UrlAuthorizationModule by using the authorization element as shown in the following example.
<system.web> <authorization> <deny users="?" /> </authorization> </system.web>

With this setting, all unauthenticated users are denied access to any page in your application. If an unauthenticated user tries to access a page, the forms authentication module redirects the user to the logon page specified by the loginUrl attribute of the forms element.

Forms Authentication Control Flow:


Figure 1 shows the sequence of events that occur during forms authentication.

Page 217

ASP.NET MATERIAL

Figure 1. Forms authentication control flow 1. The user requests the Default.aspx file from your application's virtual directory. IIS allows the request because anonymous access is enabled in the IIS metabase. ASP.NET confirms that the authorization element includes a <deny users="?" /> tag. 2. The server looks for an authentication cookie. If it fails to find the authentication cookie, the user is redirected to the configured logon page (Login.aspx), as specified by the LoginUrl attribute of the forms element. The user supplies and submits credentials through this form. Information about the originating page is placed in the query string using RETURNURL as the key. The server HTTP reply is as follows:
3. 302 Found Location: 4. http://localhost/FormsAuthTest/login.aspx?RETURNURL= %2fFormAuthTest%2fDefault.aspx

5. The browser requests the Login.aspx page and includes the RETURNURL parameter in the query string. 6. The server returns the logon page and the 200 OK HTTP status code. 7. The user enters credentials on the logon page and posts the page, including the RETURNURL parameter from the query string, back to the server.

Page 218

ASP.NET MATERIAL
8. The server validates user credentials against a store, such as a SQL Server database or an Active Directory user store. Code in the logon page creates a cookie that contains a forms authentication ticket that is set for the session. In ASP.NET 2.0, the validation of user credentials can be performed by the membership system. The Membership class provides the ValidateUser method for this purpose as shown here:
if (Membership.ValidateUser(userName.Text, password.Text)) { if (Request.QueryString["ReturnUrl"] != null) { FormsAuthentication.RedirectFromLoginPage(userName.Text, false); } else { FormsAuthentication.SetAuthCookie(userName.Text, false); } } else { Response.Write("Invalid UserID and Password"); }

9. For the authenticated user, the server redirects the browser to the original URL that was specified in the query string by the RETURNURL parameter. The server HTTP reply is as follows:
10. 302 Found Location: 11. http://localhost/TestSample/default.aspx

12. Following the redirection, the browser requests the Default.aspx page again. This request includes the forms authentication cookie. 13. The FormsAuthenticationModule class detects the forms authentication cookie and authenticates the user. After successful authentication, the FormsAuthenticationModule class populates the current User property, which is exposed by the HttpContext object, with information about the authenticated user. 14. Since the server has verified the authentication cookie, it grants access and returns the Default.aspx page.

Page 219

ASP.NET MATERIAL
FormsAuthenticationModule:
ASP.NET 2.0 defines a set of HTTP modules in the machine-level Web.config file. These include a number of authentication modules as shown here:
<httpModules> ... <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" /> <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" /> <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" /> ... </httpModules>

Only one authentication module is used for each request. The authentication module that is used depends on which authentication mode has been specified by the authentication element, usually in the Web.config file in the application's virtual directory. The FormsAuthenticationModule class is activated when the following element is in the Web.config file.
<authentication mode="Forms" />

The FormsAuthenticationModule class constructs a GenericPrincipal object and stores it in the HTTP context. The GenericPrincipal object holds a reference to a FormsIdentity instance that represents the currently authenticated user. You should allow forms authentication to manage these tasks for you. If your applications have specific requirements, such as setting the User property to a custom class that implements the IPrincipal interface, your application should handle the PostAuthenticate event. The PostAuthenticate event occurs after the FormsAuthenticationModule has verified the forms authentication cookie and created the GenericPrincipal and FormsIdentity objects. Within this code, you can construct a custom IPrincipal object that wraps the FormsIdentity object, and then store it in the HttpContext. User property.

Forms Authentication Cookies:


The FormsAuthentication class creates the authentication cookie automatically when the FormsAuthentication.SetAuthCookie or FormsAuthentication.RedirectFromLoginPage methods are called. The following properties are included in a typical forms authentication cookie:

Page 220

ASP.NET MATERIAL

Name. This property specifies the name of the cookie. Value. This property specifies value of the cookie.

In a typical forms authentication cookie, the value contains a string representation of the encrypted and signed FormsAuthenticationTicket object. The cookie contains the following properties:

Expires. This property specifies the expiration date and time for the cookie. Forms authentication only sets this value if your code indicates that a persistent forms-authentication cookie should be issued. Domain. This property specifies the domain with which the cookie is associated. The default value is null. o HasKeys. This property indicates whether the cookie has subkeys. HttpOnly. This property specifies whether the cookie can be accessed by client script. In ASP.NET 2.0, this value is always set to true. Internet Explorer 6 Service Pack 1 supports this cookie attribute, which prevents client-side script from accessing the cookie from the document.cookie property. If an attempt is made to access the cookie from client-side script, an empty string is returned. The cookie is still sent to the server whenever the user browses to a Web site in the current domain. Path. This property specifies the virtual path for the cookie. The default value is "/", indicating root directory. Secure. This property specifies whether the cookie should only be transmitted over an HTTPS connection. The Secure property should be set to true so that the cookie is protected by SSL encryption. Version. This property specifies the version number of the cookie.

Creating the Forms Authentication Cookie:


The forms authentication cookie is created by the FormsAuthentication class as follows. Once the user is validated, the FormsAuthentication class internally creates a FormsAuthenticationTicket object by specifying the cookie name; the version of the cookie; the directory path; the issue date of the cookie; the expiration date of the cookie; whether the cookie should be persisted; and, optionally, user-defined data.
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "userName", DateTime.Now, DateTime.Now.AddMinutes(30), // value of time out property false, // Value of IsPersistent property String.Empty, FormsAuthentication.FormsCookiePath);

Page 221

ASP.NET MATERIAL
Next, forms authentication uses the Encrypt method for encrypting and signing the forms authentication ticket, if the protection attribute of the forms element is set to All or Encryption.
string encryptedTicket = FormsAuthentication.Encrypt(ticket);

The following text shows the process used when the protection attribute is set to All:

Create a serialized forms authentication ticket. A byte array representation of the ticket is created. Sign the forms authentication ticket. The message authentication code (MAC) value for the byte array is computed by using the algorithm and key specified by the validation and validationKey attributes of the machineKey element. By default, the SHA1 algorithm is used. Encrypt forms authentication ticket. The second byte array that has been created is encrypted by using the Encrypt method of the FormsAuthentication class. The Encrypt method internally uses the algorithm and key specified by the decryption and decryptionKey attributes on the machineKey element. ASP.NET version 1.1 uses the 3DES algorithm by default. ASP.NET version 2.0 uses the Rinjdael (AES) algorithm by default. Create HTTP cookie or query string as appropriate. The encrypted authentication ticket is then added to an HttpCookie object or query string if forms authentication is configured for cookieless authentication. The cookie object is created using the following code:
HttpCookie authCookie = new HttpCookie( FormsAuthentication.FormsCookieName, encryptedTicket);

Set forms authentication cookie as secure. If the forms authentication ticket is configured to use SSL, the HttpCookie. Secure property is set to true. This instructs browsers to only send the cookie over HTTPS connections.
authCookie.Secure = true;

Set theHttpOnly bit. In ASP.NET 2.0, this bit is always set. Set appropriate cookie attributes. If needed, set the path, domain and expires attributes of the cookie. Add the cookie to the cookie collection. The authentication cookie is added to the cookie collection to be returned to the client browser.
Response.Cookies.Add(authCookie);

Page 222

ASP.NET MATERIAL
Each time a subsequent request is received after authentication, the FormsAuthenticationModule class retrieves the authentication ticket from the authentication cookie, decrypts it, computes the hash value, and compares the MAC value to help ensure that the cookie has not been tampered with. Finally, the expiration time contained inside of the forms authentication ticket is verified. Note ASP.NET does not depend on the expiration date of the cookie because this date could be easily forged.

Role Authorization:
In ASP.NET 2.0, role authorization has been simplified. You no longer need to retrieve role information when the user is authenticated or add role details to the authentication cookie. The .NET Framework 2.0 includes a role management API that enables you to create and delete roles, and add users to and remove users from roles. The role management API stores its data in an underlying data store that it accesses through an appropriate role provider for that data store. The following role providers are included with the .NET Framework 2.0 and can be used with forms authentication:

SQL Server. This is the default provider and it stores role information in a SQL Server database. Authorization Manager (AzMan). This provider uses an AzMan policy store in an XML file, in Active Directory, or in Active Directory Application Mode (ADAM) as its role store. It is typically used in an intranet or extranet scenario where Windows authentication and Active Directory are used for authentication.

. Cookieless Forms Authentication:


ASP.NET 2.0 supports cookieless forms authentication. This feature is controlled by the cookieless attribute of the forms element. This attribute can be set to one of the following four values:

UseCookies. This value forces the FormsAuthenticationModule class to use cookies for transmitting the authentication ticket. UseUri. This value directs the FormsAuthenticationModule class to rewrite the URL for transmitting the authentication ticket. UseDeviceProfile. This value directs the FormsAuthenticationModule class to look at the browser capabilities. If the browser supports cookies, then cookies are used; otherwise, the URL is rewritten. AutoDetect. This value directs the FormsAuthenticationModule class to detect whether the browser supports cookies through a dynamic detection mechanism. If the detection logic indicates that cookies are not supported, then the URL is rewritten.

Page 223

ASP.NET MATERIAL
If your application is configured to use cookieless forms authentication and the FormsAuthentication.RedirectFromLoginPage method is being used, then the FormsAuthenticationModule class automatically sets the forms authentication ticket in the URL. The section of the URL that is in parentheses contains the data that the cookie would usually contain. This data is removed by ASP.NET during request processing. This step is performed by the ASP.NET ISAPI filter and not in an HttpModule class. If you read the Request.Path property from an .aspx page, you won't see any of the extra information in the URL. If you redirect the request, the URL will be rewritten automatically.

Passport Authentication Provider


Passport authentication is a centralized authentication service provided by Microsoft that offers a single logon and core profile services for member sites. This benefits the user because it is no longer necessary to log on to access new protected resources or sites. If you want your site to be compatible with Passport authentication and authorization, this is the provider you should use. This topic provides some introductory material about Microsoft .NET Passport and the ASP.NET support for it. For more information, see the Passport documentation located at http://www.passport.com/business. In order to access the documentation, you must get a Passport and register. Passport is a cookies-based authentication service. A sample transaction conversation using Passport authentication might look similar to the following: 1. A client issues an HTTP GET request for a protected resource, such as http://www.contoso.com/default.aspx. 2. The client's cookies are examined for an existing Passport authentication ticket. If the site finds valid credentials, the site authenticates the client. If the request does not include a valid authentication ticket, the server returns status code 302 and redirects the client to the Passport Logon Service. The response includes a URL in the query string that is sent to the Passport logon service to direct the client back to the original site. 3. The client follows the redirect, issues an HTTP GET request to the Passport logon server, and transmits the query string information from the original site. 4. The Passport logon server presents the client with a logon form. 5. The client fills out the form and does a POST back to the logon server, using Secure Sockets Layer (SSL).

Page 224

ASP.NET MATERIAL
6. The logon server authenticates the user and redirects the client back to the original URL (http://www.contoso.com/default.aspx). The response contains an encrypted Passport cookie in the query string. 7. The client follows the redirect and requests the original protected resource again, this time with the Passport cookie. 8. Back on the originating server, the PassportAuthenticationModule detects the presence of the Passport cookie and tests for authentication. If successful, the request is then authenticated. Subsequent requests for protected resources at the site are authenticated at the originating server using the supplied ticket. Passport also makes provisions for ticket expiration and reusing tickets on other member sites. Passport uses the Triple DES encryption scheme. When member sites register with Passport, they are granted a site-specific key. The Passport logon server uses this key to encrypt and decrypt the query strings passed between sites. The ASP.NET PassportAuthenticationModule provides a wrapper around the .NET Passport SDK for ASP.NET applications, and provides Passport authentication services and profile information from an IIdentity-derived class called PassportIdentity. As is the case with WindowsIdentity, the primary purpose of handling the PassportAuthentication_OnAuthenticate event is to attach a custom IPrincipal object to the context. A special IIdentity-derived class called PassportIdentity provides an interface to the Passport profile information and methods to encrypt and decrypt Passport authentication tickets. To implement Passport authentication in an ASP.NET application: 1. Download, install, and configure the .NET Passport SDK from http://www.passport.com/business. You must complete a registration form to obtain the SDK. Windows Server 2003 includes the .NET Passport SDK and does not require this step. 2. Set up Passport as the authentication mode in the application configuration file as follows.
<authentication mode= "Passport"/>

3. Using the Passport documentation and the .NET Passport SDK functionality, implement Passport authentication and authorization.

Page 225

ASP.NET MATERIAL

XML WEB SERVICES


Introduction:
It may be necessary to have your in-process COM components run on a different server than Microsoft Internet Information Server (IIS), using Active Server Pages (ASP) technology to create an instance of your object and execute your application. An example of this would be the creation of a distributed (n-tier) environment in which you separate your components from the main Web server, therefore making your application scalable while taking system load off the main Web server. In this article, I would like to present a solution for managing your in-process COM components, using Microsoft Transaction Server (MTS), a sample Microsoft Visual Basic component, and ASP technology. We will take advantage of an n-tier architecture on two different servers running MTS. One server will host the in-process COM components under MTS, while the other server will run IIS to handle the incoming HTTP requests. An MTS component is a type of COM component that executes in the MTS run-time environment. In addition to the COM requirements, MTS requires that the component be a dynamic-link library (DLL). Components that are implemented as executable files (.exe files) cannot execute in the MTS run-time environment. For example, if you build a Remote Automation server executable file, you must rebuild it as a DLL. Exercise caution when registering a standard COM component (one developed without regard to MTS) to execute under MTS control. First, ensure that references are safely passed between contexts. Second, if the component uses other components, consider running them under MTS. Rewrite the code for creating objects in these components to use CreateInstance. You can call MTS components from ASP files. You can create an MTS object from an ASP file by calling Server.CreateObject. Note that if the MTS component has implemented the OnStartPage and OnEndPage methods, the OnStartPage method is called at this time. You can run your MTS components in-process with IIS, but be aware that if MTS encounters an unexpected internal error condition or an unhandled application error, such as a general-protection fault inside a component method call, it immediately results in a failfast, thus terminating the process and IIS.

Page 226

ASP.NET MATERIAL
If both the server and client computer are running MTS, you can distribute a package by "pulling" and "pushing" components between one or more computers. Pushing components means creating remote component entries on remote computers. Once the remote component entries are created, you have to add those component entries to your Remote Components folder on your local machine (pull the components). The following diagram illustrates pushing and pulling components to configure a remote computer running MTS. You can push and pull components only if a shared network directory has been established for storage and delivery of DLLs and type library files. (You can choose any shared directory as long as the component files are contained within one of the folders or subfolders of the shared directory.) The MTS Explorer will automatically locate available shared network directories on servers. On a given server you can have multiple shared directories to access different sets of component files.

Figure 1.

Page 227

ASP.NET MATERIAL
Requirements:

MTS needs to be installed on both local and remote machines. You must log on using a Microsoft Windows NT account that is a member of the Administrator's role of the System Package on the target computer. The target computer's System Package identity must map to a Windows NT account that is in the Reader role for your System Package. Security must be enabled for the System Package on both computers.

MTS Packages:
Before MTS can host an in-process component in its process space, it needs to have a package created. The package, which can easily be created in the MTS Explorer, is a collection of components that run in the same process. Creating packages is the final step in the development process. Package developers and advanced system and Web administrators use the MTS Explorer to create and deploy packages. You use the Explorer to implement the package and component configuration that is determined during development of the application. Packages define the boundaries for a server process running on a server computer. For example, if you group a sales component and a purchasing component in two different packages, these two components will run in separate processes with process isolation. Therefore, if one of the server processes terminates unexpectedly (such as an application fatal error), the other package can continue to execute in its separate process. A big advantage of using MTS packages is that you can specify a package identity, and all the components contained in the same package will use that identity when accessing and launching its components. This is very useful when the authenticated user (e.g., anonymous) does not have sufficient permissions to access and launch certain components.

On the Local Machine:


We wrote an ActiveX DLL with Visual Basic, using the following class and one method that returns the user context by calling the GetUserName API:
Private Declare Function GetUserName Lib "advapi32.dll" "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long Public Function WhoAmI() As String Dim sBuff$ Dim lConst& Dim lRet& Alias

Page 228

ASP.NET MATERIAL
Dim sName As String lConst& = 199 sBuff$ = Space$(200) lRet& = GetUserName(sBuff$, lConst&) WhoAmI = Trim$(Left$(sBuff$, lConst&)) End Function

After compiling and registering the component on the local machine, we need to create an empty package to host the remote component within the MTS Explorer. To create an empty package 1. In the left pane of MTS Explorer, select the computer for which you want to create a package. 2. Open the Packages Installed folder for that computer. 3. On the Action menu, click New. You can also select the Package Installed folder and either right-click and select New and then Package from the menu, or select the Create a new object button on the MTS toolbar. 4. Use the Package wizard to install either a pre-built package or to create an empty package. If you create an empty package, you must add components and roles before it will be functional. 5. Click the Create an empty package button. 6. Type a name for the new package, and click Next. 7. Specify the package identity in the Set Package Identity dialog box, and then click the Finish button.

Page 229

ASP.NET MATERIAL

Figure 2. The default selection for package identity is Interactive User. The interactive user is the user that logged on to the server computer on which the package is running. If nobody is logged on to that server computer, any requests to execute this package will fail, therefore it is recommended to specify a different user. You can select a different user by selecting the This user option and entering a specific Windows NT user or group. In many deployment scenarios, it is preferable to run a package as a Windows NT user account. If a package runs as a single Windows NT user account, you can configure database access for that account rather than for every client that uses the package. Permitting access to accounts rather than individual clients improves the scalability of your application.

Page 230

ASP.NET MATERIAL
When you would like to access network resources within the same NT domain, you'll need to specify an existing NT domain user account; otherwise, you'll have to copy the local NT user account onto the each network resource you'd like to access. By defining an identity, you are able to change user context between the user making the request and the user running the component. This way you can overcome the "doublehop" problem when using NTLM Authentication on the server.

On the Remote Machine:


Once the local component entries are created, you have to add those component entries to your Remote Components folder on your remote machine (pull the components). To add remote components, you must first add the appropriate computer or computers to your MTS Explorer and then add your components to the remote computer's Remote Components folder. Be sure that the remote components you want to add to your server are not already registered on that server. This usually happens when you're migrating from a centralized environment using only one server to a distributed environment using multiple servers. You can easily unregister existing components by using the regsvr32 command with the /u switch. To add components to the remote computer's Remote Components folder 1. Add the remote computer by selecting the Computers folder and clicking New in the Action menu. 2. Type a name for the computer you want to add, and then click OK. If you do not know the name, you can click the Browse button to select a computer. 3. In the MTS Explorer, open the Remote Components folder of the computer to which you want to add remote components. 4. On the Action menu, click New. You can also right-click and select New and then Component from the menu. 5. In the dialog box that appears, select the remote computer and package that contain the component you want to invoke remotely. 6. From the Available Components list, select the component that you want to invoke remotely, and click the down arrow (Add). This adds the component and the computer on which it resides to the Components to configure on box. If you click the Details checkbox, the Remote Computer, Package, and Path for DLLs are displayed in the Components to configure ondialog box. 7. Click OK.

Page 231

ASP.NET MATERIAL

Figure 3.

Creating the ASP File:


Now that we have done all the necessary steps to register the component with MTS, we can write an ASP file with the following code written in Visual Basic Scripting Edition (VBScript):
<%@ Language=VBScript %> <% Set oWhoAmIObject = Server.CreateObject ("WhoAmIComponent.WhoAmIClass") Response.Write "Who Am I: " & CStr(oWhoAmIObject.WhoAmI()) & " <BR>" Set oWhoAmIObject = Nothing %>

In this script we create an instance of our component using Server.CreateObject with the corresponding PROGID. You can find this PROGID in the MTS explorer under Remote Components. Now that we have created an instance of our object, we can call our method and write the results back to the client. We need to be sure that after usage of our object instance, we do our own clean up by setting the object to Nothing. Note We are instantiating our object in Page Scope. Using Page Scope will prevent us from using more system resources than necessary; it will create and destroy the object

Page 232

ASP.NET MATERIAL
within the running page, therefore releasing the used memory and threads. If you need to maintain state between HTTP requests, you should still use Page Scope to create instances of your objects, but store state information such as variables into Session Scope. Another alternative to maintain state is to store variables in hidden form fields. The last thing we need to do is to save this ASP file to the virtual directory on the IIS machine. We're now able to execute this ASP file from a browser, as shown in Figure 4.

Figure 4. The ASP file as viewed in a browser. Our request is being executed on the IIS machine, which in turn will make a request to MTS to create an instance of our object. Since MTS has this component registered as a remote component it will call the MTS package running on our local server, which will load the requested DLL into its memory space, create an instance of the requested object, and have the ASP code execute methods on it. Finally, we release our object instance, and we have finished our page.

DCOM versus Web Services DCOM Introduction:


DCOM is based on the original Distributed Computing Environment (DCE) standard Remote Procedure Call (RPC) infrastructure and was created as an extension of Component Object Model (COM) to allow the creation of server objects on remote machines. In order for COM to create remote objects, the COM libraries need to know the network name of the server. Once the server name and CLSID (a globally unique identifier representing a COM Class within the server) are known, the Service Control Manager (SCM) on the client machine connects to the SCM on the server machine and requests creation of the remote machine's server object. Because DCOM is an extension of COM, it relies on the registry and COM libraries to supply the type library information of the object to create on the remote server machine. The remote server name is either

Page 233

ASP.NET MATERIAL
configured in the registry or passed as an explicit parameter to a CoCreateInstanceEx call (in Visual Basic, this would be a CreateObject call).
Sub StartIE() Dim strProgID As String Dim oIE As InternetExplorer StrProgID = "InternetExplorer.Application.1" Set oIE=CreateObject(strProgID, "Defiant.waz.com") End Sub

The DCOM configuration tool (Dcomcnfg.exe) is provided as an alternative way to set the remote machine name and security settings rather than editing the registry directly. Some configuration is usually done on the both the client and server machines. Security settings are configured on the server machine, whereas the remote machine name is configured on the client machine. After the release of MTS, Microsoft Windows 2000, and COM+, remote object activation became a little easier. Developers could install their components (in process and out of process) as configured server application components under COM+ or as server packages in MTS. COM+ and MTS provided the surrogate server process that allowed activation of in process components from remote clients. Both MTS and COM+ facilitate the export of a client proxy in the form of a setup program. Once exported, the proxy setup could be run on the client machines, installing all necessary type library registration and remote server name entries into the registry and the COM+ catalog. Once a remote object activation request is made, the SCM uses the type library information on the client to create a proxy object that would then be used to marshal invocation calls to its corresponding stub object on the remote server. But DCOM wasn't perfect; it introduced new complexities. Like COM, whenever a server-side component is updated using DCOM, the type library information changes due to binary incompatibility. With DCOM, these changes need to be propagated to existing client machines. DCOM doesn't provide a mechanism for dynamically updating and binding to type library information; such information is stored in the registry, or with COM+ in the COM+ catalog. DCOM is a "chatty" protocol, pinging clients regularly to see if the clients are still alive. And because it doesn't support batch operations, it takes almost a dozen roundtrips to the remote server to complete a single method call. Using DCOM through firewalls becomes problematic because it dynamically allocates one port per process (configurable through the registry) and requires UPD and TCP ports 135-139 to be open. An alternative for enabling DCOM through firewalls exists by defining Tunneling TCP/IP as the underlying transport protocol. This allows DCOM to operate through some firewalls via port 80. But it's not very reliable, doesn't work through all

Page 234

ASP.NET MATERIAL
firewalls, and introduces other limitations (lack of callback support, etc.). DCOM has certainly evolved over the years, in an effort to accommodate the demands of a changing environment. But because of its roots in older binary and component-based protocols, it still fails to deliver the flexibility needed in today's enterprise. DCOM is still inefficient, cumbersome to deploy and requires a fair amount of manual maintenance.

XML Web Services Introduction:


XML Web services are based on open Web standards that are broadly supported and are used for communication and data formats. XML Web services provide the ability to expose application logic as URI-addressable resources, available to any client in a platform-independent way. COM-style type library information is no longer required on the client's machine and the Dcomcnfg.exe utility is no longer needed for distributed application configuration because Web services are self-describing. Any clients incorporating open Web standards for communication and data formatting (HTTP and XML) can query dynamically for Web service information and retrieve an XML document describing the location and interfaces supported by a particular XML Web service. These open standards make Web services indifferent to the operating system, object model, and programming language used. Web services are accessible to disparate systems, supporting application interoperability to an unprecedented level thanks to the ubiquity of HTTP and XML. Instead of binary communication methods between applications, Web services use XMLencoded messages. Because XML-based messaging is used for the data interchange, a high level of abstraction exists between a Web service implementation and the client. This frees the client from needing to know anything about a Web service except for its location, method signatures, and return values. Additionally, most Web services are exposed and accessed via HTTP, virtually eliminating firewall issues. Web services are not the ideal solution for all application models. Because it usually uses the HTTP transport and XML encoding, it's not as efficient or reliable as a binary protocol. On local Intranets, WANs, and LANs, .NET Remoting is a more appropriate solution. For Web services to provide a level of interoperability, loosely coupled programming models, and communication, they depend on an infrastructure that provides the following standards-based protocols:

SOAP: The explicit messaging protocol used in Web service message exchanges. Although HTTP is used by XML Web services to provide the SOAP message transport protocol, it is not presumed. SMTP may be used with SOAP as well. XML is the format in which the message is serialized before being bound to the transport protocol.

Page 235

ASP.NET MATERIAL

WSDL: Web Service Description Language (WSDL 1.1) is the grammar describing the location and interfaces that a particular Web service supports. A Web service uses it to deliver an XML-formatted document to any requesting client. In the COM world, WSDL can be seen as synonymous to a type library. WSDL is considered the "contract" for a Web service. DISCO: This is a Web Service Discovery mechanism. DISCO is the grammar used to describe the Uniform Resource Identifier (URI) of a Web service and contains references to the WSDL location. It usually resides at the root of a Web application and exists as an XML-formatted file. UDDI: Universal Description Discovery and Integration is the directory for all Web services. This is a protocol that allows businesses to publish their developed Web services to a central directory so that they can be easily found and consumed by other business clients. XML: Extensible Markup Language is a commonly used language for Internetready documents and development. Data is returned from a Web service in XML. If the Web service is invoked using SOAP, the parameters are also sent to the Web service method in XML.

A common scenario for a client that consumes application logic from a Web service might be (see Figure 1): 1. The client queries a UDDI directory over HTTP for the location of a Web service. 2. The client queries the Web service over HTTP for the location of the Web service's WSDL location via DISCO. This information is returned to the client in an XML-formatted message. 3. The client retrieves the WSDL information for the Web service. This information is returned in an XML message using the WSDL grammar. The client uses the WSDL information to dynamically determine the interfaces and return types available from the Web service. 4. The client makes XML/SOAP-encapsulated message calls to the Web service that conform to the WSDL information.

Page 236

ASP.NET MATERIAL

Figure 1. Web Service infrastructure example

DCOM versus Web Services:


DCOM enabled software developers to create applications that span multiple machine, network, and location boundaries, allowing scalability and ease-of-distribution across multiple tiers. Although additional complexity was introduced into the development effort, most of the benefits provided by DCOM (e.g., location independence, security and scalability) were realized to varying degrees. After the release of MTS and COM+, DCOM became easier to implement and became the standard protocol employed among

Page 237

ASP.NET MATERIAL
most Microsoft solution providers. Later, Microsoft Application Center was released and provided load balancing and fault tolerance to COM+ components. As the Internet evolves, the nature and scope of distributed applications must change to meet the underlying business needs. Businesses must integrate their applications with those that reside on heterogeneous platforms, and those that are built and deployed with varying programming models. Additionally, businesses need to communicate and expose their services to global clients and partners. To address these needs, XML Web services were introduced as part of ASP.NET, which is part of the .NET Framework. Web services are based on open Internet standards, such as HTTP, XML, and SOAP. Using these open standards, Web services deliver application functionality across the Web to any type of client, on any platform. Although XML Web services is the enabling technology, it is Visual Studio .NET that encapsulates its ease of use for developers. Visual Studio .NET provides a robust environment that allows the easy creation, deployment, and maintainability of applications developed using XML Web services.

Role of WSDL-.NET Support for Xml Web Services:

WSDL is a specification defining how to describe web services in a common XML grammar. WSDL describes four critical pieces of data:

Interface information describing all publicly available functions Data type information for all message requests and message responses Binding information about the transport protocol to be used Address information for locating the specified service

In a nutshell, WSDL represents a contract between the service requestor and the service provider, in much the same way that a Java interface represents a contract between client code and the actual Java object. The crucial difference is that WSDL is platform- and language-independent and is used primarily (although not exclusively) to describe SOAP services. Using WSDL, a client can locate a web service and invoke any of its publicly available functions. With WSDL-aware tools, you can also automate this process, enabling applications to easily integrate new services with little or no manual code. WSDL therefore represents a cornerstone of the web service architecture, because it provides a

Page 238

ASP.NET MATERIAL
common language for describing services and a platform for automatically integrating those services. This chapter covers all aspects of WSDL, including the following topics:

An overview of the WSDL specification, complete with detailed explanations of the major WSDL elements Two basic WSDL examples to get you started A brief survey of WSDL invocation tools, including the IBM Web Services Invocation Framework (WSIF), SOAP::Lite, and The Mind Electric's GLUE platform A discussion of how to automatically generate WSDL files from existing SOAP services An overview of using XML Schema types within WSDL, including the use of arrays and complex types

The WSDL Specification:


WSDL is an XML grammar for describing web services. The specification itself is divided into six major elements:
Definitions: The definitions

element must be the root element of all WSDL documents. It defines the name of the web service, declares multiple namespaces used throughout the remainder of the document, and contains all the service elements described here. The types element describes all the data types used between the client and server. WSDL is not tied exclusively to a specific typing system, but it uses the W3C XML Schema specification as its default choice. If the service uses only XML Schema built-in simple types, such as strings and integers, the types element is not required. A full discussion of the types element and XML Schema is deferred to the end of the chapter. The message element describes a one-way message, whether it is a single message request or a single message response. It defines the name of the message and contains zero or more message part elements, which can refer to message parameters or message return values.

Types:

Message:

PortType:

The portType element combines multiple message elements to form a complete one-way or round-trip operation. For example, a portType can combine one request and one response message into a single request/response operation, most

Page 239

ASP.NET MATERIAL
commonly used in SOAP services. Note that a portType can (and frequently does) define multiple operations.
Binding:

Service:

The binding element describes the concrete specifics of how the service will be implemented on the wire. WSDL includes built-in extensions for defining SOAP services, and SOAP-specific information therefore goes here. The service element defines the address for invoking the specified service. Most commonly, this includes a URL for invoking the SOAP service.

To help you keep the meaning of each element clear, Figure 6-1 offers a concise representation of the WSDL specification. As you continue reading the remainder of the chapter, you may wish to refer back to this diagram. Figure 6-1. The WSDL specification in a nutshell

In addition to the six major elements, the WSDL specification also defines the following utility elements:
Documentation: The documentation Import:

element is used to provide human-readable documentation and can be included inside any other WSDL element. The import element is used to import other WSDL documents or XML Schemas. This enables more modular WSDL documents. For example, two WSDL documents can import the same basic elements and yet include their own service elements to make the same service available at two physical addresses. Note, however, that not all WSDL tools support the import functionality as of yet.

Page 240

ASP.NET MATERIAL

Client Apps for WebServices:

We use an external web service from our application. It was working fine with out any issues, but from the past two days we are getting the error The request failed with HTTP status 401: Unauthorized. We got one more error while debugging with fiddler your Web browser is sending WWW-Authenticate header field that the Web server is not configured to accept. There are no code changes in our app and the target web service too. In our IIS 6.0 and windows server 2003 (latest service packs applied) we have the following settings 1. 2. 3. 4. Integrated Windows Authentication Checked Enable Anonymous Access is unchecked App pool runs under a service account. Web.config configuration <authentication mode="Windows" />

<identity impersonate="false" /> A sample code is mentioned below. If we run the code from Visual studio, it works fine with out issues. But when the code is built, published and deployed on a web server and access the site from a client(Web Browser), we get the error The request failed with HTTP status 401: Unauthorized when the application hits the web service. We have tried the following codes to replace System.Net.CredentialCache.DefaultCredentials also, but it is not working 1)System.Net.CredentialCache cache = new System.Net.CredentialCache(); cache.Add(new Uri("https://xxx/xxx.asmx"), "NTLM", System.Net.CredentialCache.DefaultCredentials.GetCredential(new Uri("https://xxx/xxx.asmx"), "NTLM")); webProxy.Credentials = cache; 2) webProxy.Credentials = new System.Net.NetworkCredential(uname,pwd,domain)-This worked but we cant use it,since uid and pwd needs to be hard coded. 3) webProxy.UseDefaultCredentials = true; webProxy.PreAuthenticate = true;

Issue seems to be appearing in the bold text portion below.

Page 241

ASP.NET MATERIAL
protected void Button1_Click(object sender, EventArgs e) { try { bool flag = true; String GetIO = ""; TrialService.OService webProxy = new TrialService.OService(); webProxy .Url = "https://xxx/xxx.asmx"; if (flag) { ImpersonateUser(); } webProxy .Credentials = System.Net.CredentialCache.DefaultCredentials; System.Xml.XmlNode xmlNode = webProxy .OBlock(); GetIO = xmlNode.OuterXml; TextBox1.Text = GetIO; } catch (Exception ex) { TextBox1.Text = ex.Message; } } *Code for Impersonate User * private void ImpersonateUser() { System.Security.Principal.WindowsPrincipal wp = (System.Security.Principal.WindowsPrincipal)System.Threading.Thread.CurrentPrincipa l; System.Security.Principal.WindowsIdentity windowsIdentity = (System.Security.Principal.WindowsIdentity)p.Identity; wc = windowsIdentity.Impersonate(); }

Page 242

ASP.NET MATERIAL

WSDL Utility:

The Web Services Description Language tool generates code for XML Web services and XML Web service clients from WSDL contract files, XSD schemas, and .discomap discovery documents. Remarks: Argument Description The URL to a WSDL contract file (.wsdl), XSD schema file (.xsd), or URL discovery document (.disco). Note that you cannot specify a URL to a .discomap discovery document. The path to a local WSDL contract file (.wsdl), XSD schema file (.xsd), or discovery document (.disco or .discomap). Path Note: Wsdl.exe does not retrieve includes and imports from the network when it is given a local file. To enable Wsdl.exe to retrieve network resources while processing a local file, pass a URL to the local file. For example, the following file uses the network to retrieve necessary resources: wsdl
File:///E:/Customers/WSDLS/Accounts.wsdl /out:proxy.cs

Option /appsettingurlkey:key or /urlkey:key

Description Specifies the configuration key to use to read the default value for the URL property when generating code. When using the /parameters option, this value is the <appSettingUrlKey> element and contains a string.

Specifies the base URL to use when calculating the URL /appsettingbaseurl:baseurl fragment. The tool calculates the URL fragment by converting the relative URL from the baseurl argument to or the URL in the WSDL document. You must specify the /appsettingurlkey option with this option. When using the /parameters option, this value is the <appSettingBaseUrl> /baseurl:baseurl element and contains a string. Specifies the domain name to use when connecting to a server that requires authentication. When using /d[omain]:domain the /parameters option, this value is the <domain> element and contains a string. /l[anguage]:language Specifies the language to use for the generated proxy class. You can specify CS (C#; default), VB (Visual Basic), JS (JScript) or VJS (Visual J#) as the language argument. You can also specify the fully-qualified name of a class that

Page 243

ASP.NET MATERIAL
implements the System.CodeDom.Compiler.CodeDomProvider Class. When using the /parameters option, this value is the <language> element and contains a string. Specifies the namespace for the generated proxy or template. The default namespace is the global namespace. When using the /parameters option, this value is the <namespace> element and contains a string. This element must be in the parameters file. Suppresses the Microsoft startup banner display. When using the /parameters option, this value is the <nologo> element and contains either true or false. Generates explicit order identifiers on particle members. Specifies the file (or directory) in which to save the generated proxy code. You can also specify a directory in which to create this file. The tool derives the default file name from the XML Web service name. The tool saves generated datasets in different files. When using the /parameters option, this value is the <out> element and contains a string. Reads command-line options from the specified XML file. Use this option to pass the Wsdl.exe tool a large number of options at one time. Short form is /par:. Option elements are contained inside a <wsdlParameters xmlns="http://microsoft.com/webReference/"> element. For details, see the Remarks section. Displays errors in a format similar to the error reporting format used by language compilers. When using the /parameters option, this value is the <parsableerrors> element and is either true or false. Specifies the password to use when connecting to a server that requires authentication. When using the /parameters option, this value is the <password> element and contains a string. Specifies the protocol to implement. You can specify SOAP (default), HttpGet, HttpPost, or a custom protocol specified in the configuration file. When using the /parameters option, this value is the <protocol> element and contains a string. Specifies the URL of the proxy server to use for HTTP requests. The default is to use the system proxy setting. When using the /parameters option, this value is the

/n[amespace]:namespace

/nologo /order

/o[ut]:filename or directoryname

/parameters

/parsableerrors

/p[assword]:password

/protocol:protocol /proxy:URL

Page 244

ASP.NET MATERIAL
<proxy> element and contains a string. /proxydomain:domain or /pd:domain /proxypassword:password or /pp:password /proxyusername:username or /pu:username /server Specifies the domain to use when connecting to a proxy server that requires authentication. When using the /parameters option, this value is the <proxydomain> element and contains a string. Specifies the password to use when connecting to a proxy server that requires authentication. When using the /parameters option, this value is the <proxypassword> element and contains a string. Specifies the user name to use when connecting to a proxy server that requires authentication. When using the /parameters option, this value is the <proxyusername> element and contains a string. Generates an abstract class for an XML Web service based on the contracts. The default is to generate client proxy classes. When using the /parameters option, this value is a <style> element that contains "server". Generates interfaces for server implementation of an ASP.NET Web Service. An interface is generated for each binding in the WSDL document(s). The WSDL alone implements the WSDL contract (classes that implement the interface should not include either of the following on the class methods: Web Service attributes or Serialization attributes that change the WSDL contract). Short form is /si. When using the /parameters option, this value is a <style> element that contains "serverInterface". Turns on the type sharing feature. This feature creates one code file with a single type definition for identical types shared between different services (the namespace, name, and wire signature must be identical). Reference the services with "http://" URLs as command-line parameters or create a discomap document for local files. When using the /parameters option, this value is the <sharetypes> element and is either true or false. Specifies the user name to use when connecting to a server that requires authentication. When using the /parameters option, this value is the <username> element and contains a string. Displays command syntax and options for the tool.

/serverInterface

/sharetypes

/u[sername]:username /?

Page 245

ASP.NET MATERIAL
A .wsdl file is an XML document written in an XML grammar called Web Services Description Language (WSDL). This file defines how an XML Web service behaves and instructs clients as to how to interact with the service. You can obtain discovery documents for an XML Web service using the Web Services Discovery Tool (Disco.exe). The .discomap, .disco, .wsdl, and .xsd files produced by this tool can be used as input to Wsdl.exe. When you use Wsdl.exe to create a proxy class, a single source file is created in the programming language that you specify. In the process of generating the source code for the proxy class, the tool determines the best type to use for objects specified in the service description. In some cases, the tool uses a least-common-denominator approach for casting objects to a type. As a result, the generated type in the proxy class might not be what the developer wants or expects. For example, when Wsdl.exe encounters an ArrayList type in a service description, it creates an Object Array in the generated proxy class. To ensure correct object type casts, open the file that contains the generated proxy class and change any incorrect object types to the expected object type.

The /parameters option specifies a file that contains elements that correspond to most of the command-prompt options. Some command-prompt options are available only in the /parameters file formats.

The XML file format accepted by the /parameters option is a series of elements inside an outer <wsdlParameters xmlns="http://microsoft.com/webReference/"> element. If command-prompt values are specified and a /parameters file is used that contains different options or values, the values specified at the command prompt are used. The <wsdlParameters xmlns="http://microsoft.com/webReference/"> element must contain a <nologo> element, a <parsableerrors> element, and a <sharetypes> element. Several options are passed as child elements of the <webReferenceOptions> element, which must contain a <verbose> element. Other child elements of <webReferenceOptions> are:

<style>. Contains either "client", "server", or "serverInterface". <schemaImporterExtension>. Contains any number of <type> elements. <codeGenerationOptions>. Can take a space-delimited set of the following strings. "properties" "newAsync"

Page 246

ASP.NET MATERIAL

"oldAsync" "order" "enableDataBinding"

See the following Examples section for some demonstrations of the /parameters option. Examples: The following command creates a client proxy class in the C# language for the XML Web service.
wsdl http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL

The following command creates a client proxy class in the C# language for an XML Web service located at the specified URL. The tool saves the client proxy class in the file myProxyClass.cs.
wsdl /out:myProxyClass.cs http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL

The following command creates a client proxy class in the Microsoft Visual Basic language for an XML Web service located at the specified URL. The tool saves the client proxy class in the file myProxyClass.vb.
wsdl /language:VB /out:myProxyClass.vb http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL

The following example code shows a basic /parameters WSDL file with only the required elements written that can be used, combined with a URL argument, at the command prompt.
<wsdlParameters xmlns="http://microsoft.com/webReference/"> <nologo>true</nologo> <parsableerrors>true</parsableerrors> <sharetypes>true</sharetypes> </wsdlParameters>

WSDL documents are added in the /parameters WSDL file using the <documents> element, as the following code example demonstrates. Any number of <document> elements can be used inside the <documents> element.
<wsdlParameters xmlns="http://microsoft.com/webReference/"> <nologo>true</nologo>

Page 247

ASP.NET MATERIAL
<parsableerrors>true</parsableerrors> <sharetypes>true</sharetypes> <documents> <document>http://www.contoso.com/service.asmx?WSDL</document> </documents> </wsdlParameters>

The following /parameters WSDL file demonstrates the use of the <codeGenerationOptions> and <style> elements inside the <webReferenceOptions> element. In this case, the file enables the new style of data binding in proxy code, specifies a schema importer extension that output is not to be verbose, and that Wsdl.exe is to create a client proxy.
<wsdlParameters xmlns="http://microsoft.com/webReference/"> <nologo>true</nologo> <parsableerrors>true</parsableerrors> <sharetypes>true</sharetypes> <documents> <document>http://www.contoso.com/service.asmx?WSDL</document> </documents> <webReferenceOptions> <verbose>false</verbose> <codeGenerationOptions>properties newAsync enableDataBinding</codeGenerationOptions> <schemaImporterExtension> <type>MyNamespace.MyCustomImporterExtension,ExtensionLibrary</typ e> </schemaImporterExtensions> <style>client</style> </webReferenceOptions> </wsdlParameters>

Caching with Web services:

Introduction:
Despite advancements in network and processor speeds, performance remains a key concern among application developers. So whether you are writing an XML Web service, pushing image bitmaps to a video card, or even engineering that next great processing chip, you will invariably want to consider utilizing a universal mechanism for improving performance: a cache. In this At Your Service column, we will look at how you as a developer and consumer of XML Web services can utilize caching. We'll take a look at ways you can do applicationlevel caching with ASP.NET, and will take a look at HTTP caching and its application for XML Web services. Finally, we will look at how we can take the sample MSDN

Page 248

ASP.NET MATERIAL
Pencil Company's Discovery service and implement a caching strategy that makes sense for providing a pencil catalog that is updated daily.

Questions to Ponder When Considering Caching Options:


There are a number of ways you could implement various caching capabilities when creating an XML Web service or consuming an XML Web service. However, not all mechanisms for implementing a cache will effectively enhance performance, or even offer the perception of enhanced performance. You must analyze what makes sense in your particular usage scenario. Here are some questions you will want to ask yourself when considering caching functionality for your XML Web service:

How much of my data is dynamic?


It is hardly a foregone conclusion that caching is always a good idea. For instance, if the data returned from an XML Web service is always different, then caching may not help much. However, just because data is dynamic, it doesn't mean that caching is out of the question. If even a portion of the response is relatively static, caching could improve your Web server's performance. Consider a scenario where information is changing, but not changing with each and every request? If you are receiving hundreds of requests a second for your temperature service, for example, you might want to send back cached data for most requests, and only update the data every 5 minutes or so.

Is my data private?
In many cases an XML Web service will deal with user-specific data. This tends to decrease the usefulness of cachingbut don't write off caching just because you are dealing with user-specific data. Say your XML Web service has a small number of users; it might make sense to cache information for each user, particularly if the user might request the same information multiple times. Even if a user does not request the same information every time, there may be a common instance of a class that could be referenced for each request from that same user. Be careful when caching private information, however, because bugs in this kind of code may allow private data to be compromised. To play it safe, it might be wise for your code to enforce access restrictions.

Does my XML Web service use resources that I can share between requests?
Caching is not limited to simply caching responses. You may be able to gain significant performance enhancements by caching any sort of application data or resources. It might make sense to keep around a dataset, for instance, to handle multiple queries. The

Page 249

ASP.NET MATERIAL
response data may vary depending upon the specific queries on the dataset, but the dataset data itself may remain the same for many requests.

Can I predict the use of future resources?


Consider the usage scenarios for your XML Web service. Are there behaviors that you can predict? Say, for instance, that an XML Web service allows consumers to search for a particular article, and then allows them to download that article. It may make sense to assume that once a successful search has been performed for an article, a download request will soon follow. Your XML Web service can start the potentially lengthy process of loading the article into memory (perhaps from a file or a database), so that it is all set to respond once it receives the request to download the article.

Where do I cache my XML Web service's data?


The correct answer to this question may often be, "everywhere." But what are the different options for caching data? To answer this question let's take a look at the potential XML Web service scenario shown in Figure 1.

Page 250

ASP.NET MATERIAL
Figure 1. Caching possibilities for one XML Web service scenario The figure starts in the upper left with an end user browsing to the Web site located in the yellow box. Unbeknownst to the user, the Web site sits behind an HTTP proxy server. The Web server then makes a SOAP request to a Web service in a different organization (represented by the green box). The SOAP request also goes through an HTTP proxy. The first Web service must then forward the request to a second, internal Web service, the internal Web service queries a Microsoft SQL Server for the data required, and the response is finally returned. The SQL data is used to build the internal Web service response, and the internal Web service response is used to build the response to the initial Web service. The Web site uses the Web service response to create an HTML page that is returned to the end-user browser.All this happens through the various proxies and routers along the way. So where can the response data be cached? At every point in this scenario: The SQL Server could cache query results. The internal Web service could cache the SQL query results. The initial Web service could cache the results from the internal Web service, and the green organization's HTTP proxy could cache the results as well. The Web server could cache the Web service's response. The yellow organization's proxy could cache the Web server's response, and the end-user's browser could cache the HTML page.

When will my data expire?


One of the key problems when designing caching strategies is determining when the data in the cache should be removed from the cache. Sometimes this is fairly simple to determine, since a process that updates the data may run at regular intervals. However, there may be other situations where the data is updated at relatively random intervals. In either case, the key is to figure out the optimal time interval for updating the cache, so that a balance can be achieved between the harm of returning stale data against the performance improvements provided by returning cached information. Once you have figured out this optimal interval, you can include that information with your data, so that the caching systems can update their data appropriately.

How do I notify consumers of my XML Web service that my data will expire?
The answer to this question depends upon how you are doing your caching. It may make sense for the client application to cache the data. If this is the case, then you need to inform the client application when the data expires. Presumably, applications will need you to include expiration information in the data being returned. For your Web service, this may mean adding a field to the XML response that specifically states an expiration time.If you are depending on other pre-built solutions for performing your cache, these usually provide mechanisms for indicating an expiration time. In the case of using HTTP caching, you can set the HTTP headers that indicate to proxies and client systems when the data expires. ASP.NET includes a cache class that you can insert data into. When

Page 251

ASP.NET MATERIAL
inserting the data, you have the ability to specify when the data will be removed from the cache.

Can I depend on the data being in the cache?


The short answer is, no. Almost every caching mechanism ever designed has an algorithm for removing old information from the cache. Data can be removed because it expired, but it can also be removed because it has not been accessed recently and there is other data to be added to the relatively limited cache resource. Therefore, most caching mechanisms do not guarantee that data will remain in the cache. This is particularly true of shared caching mechanisms, such as HTTP proxy caches, or even ASP.NET caches.

What ramifications will there be if consumers of your XML Web service do not use cached data?
There are a number of reasons why data may not be cached. As mentioned above, it could simply be that higher priority data replaced your application's data in the shared cache. It could also be that the developer writing the code to access your XML Web service is not being responsible about reusing data previously acquired. When designing your XML Web service, take into account the possibility for performance improvements based off of caching scenarios, but also allow for cases where your data does not get cached for any number of reasons. You will need to be able to deal with situations where caching is not working optimally.

Proxy with Asynchronous Methods:

Every Web method on a Web service proxy class has an asynchronous counterpart. The proxy class automatically generates asynchronous methods and a corresponding event for every Web method. When the asynchronous method is called, it executes on another thread and raises its corresponding event when it returns. You can execute code when an asynchronous method returns by creating a handler for its corresponding event.

To call a Web method asynchronously with Visual Basic:


1. Declare an instance of the Web service proxy class using the WithEvents keyword, as shown below: 2. Dim WithEvents myWebService As New Service1. 3. In the Code Editor, use the Handles keyword to create an event handler for the MethodCompleted event that corresponds to the method you want to call. For example, if you were calling a method called HelloWorld asynchronously, you would create a method similar to the following:

Page 252

ASP.NET MATERIAL
Private Sub HelloWorldComplete(ByVal sender As Object, _ ByVal completed As localhost.HellowWorldCompletedEventArgs) _ Handles myWebService.HelloWorldCompleted ' Insert code to implement the method here End Sub

4. Call the Web method using the MethodAsync form of the method. For example, if you were calling a Web method called HelloWorld asynchronously, it would look as follows:
HelloWorldAsync

Note that the return value of the method is available in the Result property of the EventArgs.

To call a Web method asynchronously with C#:


1. Declare an instance of the Web service proxy class, as shown below:
private localhost.Service1 myWebService = new localhost.Service1 (); In the Code Editor, add an event handler for the MethodCompleted event that corresponds to the method you want to call. For example, if you were calling a method called HelloWorld asynchronously, you would create a method similar to the following: private void HelloWorldCompleted(Object sender, localhost.HelloWorldCompletedEventArgs Completed) { // Insert code to implement the method here }

2. In the constructor for the class, add the MethodCompleted event handler to the list of handlers for that event, as shown below:
private void Form1_Load(object sender, EventArgs e) { myWebService.HelloWorldCompleted += new localhost.HelloWorldCompletedEventHandler(HelloWorldCompleted ); }

3. Call the Web method using the MethodAsync form of the method. For example, if you were calling a Web method called HelloWorld asynchronously, it would look as follows:

Page 253

ASP.NET MATERIAL
HelloWorldAsync();

Web Service wire Formats-HTTP Post:

Binary protocols such as DCOM consist of a method request layer riding on top of a proprietary communication protocol. Such protocols are not conducive to creating universally available XML Web services. This does not preclude you from using such protocols in an XML Web service scenario, but the drawback of using them is that such protocols depend on the specific architectures of their underlying systems and therefore limit the spectrum of potential clients. Alternatively, you can construct XML Web services to work with one or more open protocols, such as a combination of HTTP and SOAP. As you would expect, the infrastructure required to support different protocols will vary. XML Web services are not limited to providing remote procedure call (RPC) access. They can also be built to exchange structured information, such as purchase orders and invoices, and can be used to automate and connect internal and external business processes.

HTTP-GET and HTTP-POST:


HTTP-GET and HTTP-POST are standard protocols that use HTTP (Hypertext Transfer Protocol) verbs for the encoding and passing of parameters as name/value pairs, along with the associated request semantics. Each consists of a series of HTTP request headers that among other things define what the client is requesting from the server, which responds with a series of HTTP response headers and the requested data if successful. HTTP-GET passes its parameters in the form of urlencoded text using the MIME type application/x-www-form-urlencoded, which is appended to the URL of the server handling the request. Urlencoding is a form of character encoding that ensures that the passed parameters consist of conforming text, such as encoding a space as %20. The appended parameters are also referred to as a query string. Similar to HTTP-GET, HTTP-POST parameters are also urlencoded. However, instead of being passed as part of the URL, the name/value pairs are passed inside the actual HTTP request message.

SOAP:

Page 254

ASP.NET MATERIAL
SOAP is a simple, lightweight XML-based protocol for exchanging structured and type information on the Web. The overall design goal of SOAP is to keep it as simple as possible, and to provide a minimum of functionality. The protocol defines a messaging framework that contains no application or transport semantics. As a result, the protocol is modular and very extensible. By traveling over standard transport protocols, SOAP is able to leverage the existing open architecture of the Internet and gain easy acceptance by any arbitrary system capable of supporting the most basic Internet standards. You could view the infrastructure required to support a SOAP-compliant XML Web service as rather simplistic, yet powerful, since it adds relatively little to the existing infrastructure of the Internet and still facilitates universal access to the services built with SOAP. The SOAP protocol specification consists of four main parts. The first part defines a mandatory extensible envelope for encapsulating data. The SOAP envelope defines a SOAP message and is the basic unit of exchange between SOAP message processors. This is the only mandatory part of the specification. The second part of the SOAP protocol specification defines optional data-encoding rules for representing application-defined data types and directed graphs, and a uniform model for serializing non-syntactic data models. The third part defines an RPC-style (request/response) message exchange pattern. Each SOAP message is a one-way transmission. Although SOAP's roots are in RPC, it is not limited to being a request/response mechanism. XML Web services often combine SOAP messages to implement such patterns, but SOAP does not mandate a message exchange pattern and this part of the specification is also optional. The fourth part of the specification defines a binding between SOAP and HTTP. However, this part is also optional. You can use SOAP in combination with any transport protocol or mechanism that is able to transport the SOAP envelope, including SMTP, FTP, or even a floppy disk. For the SOAP specification, see the W3C Web site (http://www.w3.org/TR/soap).

HTTP Post & Get-SOAP Envelope:

SOAP and HTTP GET and POST:

Page 255

ASP.NET MATERIAL
All of the recent discussion about when, where and how to use HTTP GET and POST with SOAP has led me to go back and reevaluate the use of SOAP over HTTP and the use of the various core HTTP operations. First, let's look at the core HTTP 1.1 operations.... Operation Description OPTIONS "Represents a request for information about the communication options available on the request/response chain identified by the Request-URI". In Web Services, this could be interpreted as a request for the WSDL description of the Service. GET "The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a dataproducing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process." HEAD "The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response" POST "The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line" PUT "The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server." DELETE "The DELETE method requests that the origin server delete the resource identified by the Request-URI." TRACE "The TRACE method is used to invoke a remote, application-layer loop- back of the request message." CONNECT "This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel" Looking these over, there are a couple of things to consider. First, the "resource" identified by the HTTP Request URI is the Web Service itself, not the data that the Web service deals with. The Web Service is a data-producing resource. That said, a SOAP HTTP GET operation implies a request for the Web Service to produce a SOAP message. (Example 1)
Example 1: SOAP HTTP GET operation

Page 256

ASP.NET MATERIAL
Request GET /StockQuoteService?symbol=IBM HTTP/1.1 Host: www.ibm.com Response HTTP/1.1 200 OK Content-Type: application/soap-xml; charset="utf-8" Content-Length: nnnn <env:Envelope>...</env:Envelope>

The HTTP POST operation is a bit strange when it comes to Web services, but based on the language used to describe the POST operation semantics within the HTTP specification, it is extremely clear that the use of POST for a RPC invocation is clearly very wrong. That said, other than GET, there is no other core HTTP Operation that can be used for RPC invocations, therefore, I would go so far as to propose a new HTTP method called "INVOKE". The INVOKE operation indicates that the operation indicated by the HTTP data entity (the SOAP Envelope) should be invoked against the Web service indicated by the URI. If the INVOKE operation results in a response SOAP Envelope, the HTTP server should respond with a 200 OK response that contains the resulting SOAP envelope. If no response SOAP Envelope is created, the HTTP server should respond with a 204 No Content response.
Example 2: SOAP HTTP INVOKE operation Request INVOKE /StockQuoteService HTTP/1.1 Host: ww.ibm.com Content-Type: application/soap-xml; charset="utf-8" Content-Length: nnnn <env:Envelope>...</env:Envelope> Response HTTP/1.1 200 OK Content-Type: application/soap-xml; charset="utf-8" Content-Length: nnnn <env:Envelope>...</env:Envelope>

Going through this process, we see a number of interesting side effects of applying the various HTTP core operations to Web services. For example, the PUT and DELETE operations actually map to the deployment and undeployment of Web services. In other words, when you do a "DELETE" against a URI that indicates a Web service, the Web service should be deleted. When you do a "PUT" against a URI, the Web service is deployed.

Page 257

ASP.NET MATERIAL
The OPTIONS HTTP method would probably be best for returning the WSDL description for a Web Service since the WSDL is what would be used to express the communication options for the Web Service. The bottom line is, I'm starting to agree that using HTTP POST for SOAP RPC invocations is not the proper approach. Creating a new INVOKE operation would be.

UDDI Registry:

-UDDI (Universal Description, Discovery, and Integration) is an XML-based registry for businesses worldwide to list them on the Internet. Its ultimate goal is to streamline online transactions by enabling companies to find one another on the Web and make their systems interoperable for e-commerce. UDDI is often compared to a telephone book's white, yellow, and green pages. The project allows businesses to list themselves by name, product, location, or the Web services they offer. Microsoft, IBM, and Ariba spearheaded UDDI. The project now includes 130 companies, including some of the biggest names in the corporate world. Compaq, American Express, SAP AG, and Ford Motor Company are all committed to UDDI, as is Hewlett-Packard, whose own XML-based directory approach, called e-speak, is now being integrated with UDDI. While the group does not refer to itself as a standards body, it does offer a framework for Web services integration. The UDDI specification utilizes World Wide Web Consortium (W3C) and Internet Engineering Task Force (IETF) standards such as XML, HTTP, and Domain Name System (DNS) protocols. It has also adopted early versions of the proposed Simple Object Access Protocol (SOAP) messaging guidelines for cross platform programming. In November 2000, UDDI entered its public beta-testing phase. Each of its three founders - Microsoft, IBM, and Ariba - now operates a registry server that is interoperable with servers from other members. As information goes into a registry server, it is shared by servers in the other businesses. The UDDI beta is scheduled to end in the first quarter of 2001. In the future, other companies will act as operators of the UDDI Business Registry. UDDI registration is open to companies worldwide, regardless of their size. Learn more about UDDI (Universal Description, Discovery and Integration) Mule architect sees REST with Atom rising, UDDI fading: Dan Diephouse, the creator of XFire and software architect at MuleSource Inc., discusses the advantages in using REST

Page 258

ASP.NET MATERIAL
and the Atom Publishing Protocol. Boubez: SOA virtualization, SLAs and access control policy: WS-Policy for SOA is good to go but work remains to bring access control and service level agreement policy language specifications, says Toufic Boubez. Anne Thomas Manes: Why SOA needs UDDI now: The original definition of Web services included SOAP, WSDL and UDDI, but the latter was often ignored. UDDI v3.0 is emerging as a key standard for SOA registry and repository. Burton: IBM SOA registry/repository competes with UDDI: The good news is that IBM has produced a technologically solid registry/repository, says a Burton Group report, but the bad news is that it largely ignores UDDI. Utterly UDDI: UDDI stands for Universal Description, Discovery and Integration. Learn all you ever needed to know about UDDI with our white papers, articles, news stories and expert responses. Free UDDI advice: Got questions about UDDI? Systinet CTO Adam Blum is here to lend his expertise. Read his previous answers and pose your own UDDI question anonymously. UDDI Learning Guide: This guide explains what UDDI is, how it's used, and how it fits into the world of Web services. Check back often for updates and new additions. UDDI Crash Course: Need a quick knowledge fix on UDDI? This week we present UDDI articles, tutorials, examples, tips, tools, white papers, expert advice and more to pump up your UDDI know-how. Divorcing SOA and Web services: Jason Bloomberg gives a history of the evolution of SOA and Web services and discusses the common misconception that they are the same thing.

Securing Web Services:

Web services are used by an increasing number of companies as they expose products and services to customers and business partners through the Internet and corporate extranets. The security requirements for these service providers are of paramount importance. In some cases, primarily intranet or extranet scenarios where you have a degree of control over both endpoints, the platform-based security services provided by the operating system and Internet Information Services (IIS) can be used to provide point-to-point security solutions. However, the message based architecture of Web services and the heterogeneous environments that span trust boundaries in which they are increasingly being used pose new challenges. These scenarios require security to be addressed at the message level to support cross-platform interoperability and routing through multiple intermediary nodes.

Page 259

ASP.NET MATERIAL
security standard designed Enhancements (WSE) 2.0 supports WS-Security and implement message level digital signatures. Web Services Security (WS-Security) is the emerging to address these issues. Microsoft has released Web Services for Microsoft .NET 1.1 and WSE 3.0 for .NET 2.0, which a related family of emerging standards. WSE allows you to security solutions including authentication, encryption and

Security Engineering Approach:


Patterns & practices Security Engineering includes specific security-related activities that help you meet your application security objectives as shown in Figure 1.

Security Overlay

Figure 1. Security activities in the application development life cycle There is a core set of activities common to application development approaches, such as architecture and design reviews, code reviews and deployment reviews. patterns & practices Security Engineering extends these proven core activities to create security specific activities. These activities include:

Security objectives. Threat modeling. Security design guidelines. Security architecture and design reviews. Security code reviews.

Page 260

ASP.NET MATERIAL

Security testing. Security deployment reviews.

Security Engineering Overviews:


To design, build, and deploy secure applications, you must integrate security into your application development life cycle and adapt your current software engineering practices and methodologies to include specific security-related activities. The following overview shows you how to integrate security into your application development:

Security Objectives:
Setting objectives helps you scope and prioritize your work by setting boundaries and constraints. Setting security objectives helps you identify where to start, how to proceed, and when you are done.

Security Design Guidelines:


Creating design guidelines is a common practice at the start of an application project to guide development and share knowledge across the team. Effective design guidelines for security organize security principles, practices, and patterns by actionable categories. See the following security design guidelines resource:

Threat Modeling:
Threat modeling is an engineering technique that can help you identify threats, attacks, vulnerabilities, and countermeasures that could affect your application. You can use threat modeling to shape your application's design, meet your company's security objectives, and reduce risk. See the following Threat Modeling resource:

Security Architecture and Design Reviews:


Security architecture and design reviews are an effective way to identify problems in your application design. By using pattern-based categories and a question-driven approach, you simplify evaluating your design against root cause security issues. See the following security architecture and design review resources.

Security Code Reviews:

Page 261

ASP.NET MATERIAL
Many security defects are found during code reviews. Analyzing code for security defects includes knowing what to look for and how to look for it. Security code reviews optimize reviewing code for common security issues. See the following security code review resources:

Security Deployment Reviews:


When you deploy your application during your build process or staging process, you have an opportunity to evaluate runtime characteristics of your application in the context of your infrastructure. Deployment reviews for security focus on evaluating your security design and configuration of your application, host, and network. See the following deployment review resources:

Security Guidelines:
You can use Security Guidelines guidance modules to support the activities above. Security Guidelines are specific, actionable recommendations at the implementation level. Each recommendation is presented to address "what to do", "why", and "how." The recommendations are principle-based and they are organized using pattern-based categories for easy consumption.

Security Practices:
You can use Security Practices guidance modules to support the activities above. Security Practices are proven and emerging practices expressed as precisely as possible. Each practice is presented using a problem and solution format and the set of practices are organized using pattern-based categories.

IP Address & Domain Registration:

This issue can occur if one of the network adapters is attached to an external network (such as the Internet) on the multihomed domain controller, and if Lightweight Directory Access Protocol (LDAP) and Kerberos traffic between the internal and external networks is partially or completely restricted because of a Proxy, ISA Server,NATServer. In this scenario, network adapters on the multihomed domain controllers are registering both the inside and outside Internet Protocol (IP) addresses with the DNS server. DNS name resolution lookup requests return records in a "round robin" fashion, alternating the internal and external IP addresses. Replication operations require multiple

Page 262

ASP.NET MATERIAL
lookup requests of SRV records. In this case, half of the DNS lookup requests return an IP address that cannot be contacted, and the replication operation fails. To resolve this issue: 1. Disable registration on the outside network adapter on the multihomed domain controller. To do so: a. Click Start, click Settings, and then click Network and Dial-Up Connections. b. Right-click the outside local area network (LAN) connection, and then click Properties. c. Click TCP/IP, and then click Properties. d. Click Advanced, and then click to clear the Register DNS for this connection check box. 2. Disable the round robin functionality on the DNS server. To do so: a. Click Start, click Settings, click Administrative Tools, and then click DNS. b. Open the properties for the DNS server's name. c. Click the Advanced tab, and then click to clear the Enable round robin check box. 2. Remove the existing entries in DNS. To do so: a. Browse to the following location: Under DNS\DNS Servername\Forward Lookup Zones\Domain Name Remove Host (A) record entries that refer to the domain controller's computer name for the outside network adapter IP addresses. Remove Host (A) record entries for the same name as the parent folder for the network adapter IP addresses. Start the DNS Management Console, right-click the server name, and then click Properties. Click the Interfaces tab, and then remove the external IP address so that DNS does not listen on it. Open a command prompt, type ipconfig /flushdns, press ENTER, type ipconfig /registerdns, and then press ENTER. Change the binding order of your network adapters so that the Internal adapter is the first bound adapter. To do this, follow these steps:

Page 263

ASP.NET MATERIAL
Click Start, click Settings, and then click Network and Dial-Up Connections. 1. On the Advanced menu, click Advanced. 2. Verify that the internal network adapter is listed first in the Connections box.

SSL[Secured Socket Layer]-SOAP Header:

SA: See security association (SA). SAD: See security association database (SAD). Salt: An additional random quantity, specified as input to an encryption function that is used to increase the strength of the encryption. Sanitized name: The form of a certification authority (CA) name that is used in file names and in other contexts where character sets are restricted. The process of sanitizing the CA name is necessary to remove characters that are illegal for file names, registry key names, or distinguished name (DN) values, or that are illegal for technology-specific reasons. SASL: The Simple Authentication and Security Layer, as specified in [RFC2222]. This is an authentication mechanism used by the Lightweight Directory Access Protocol (LDAP). Schedule: The frequency at which data replicates. Schema: The set of attributes and object classes that govern the creation and update of objects. Schema container: The root object of the schema NC. Schema naming context (schema NC): A specific type of naming context (NC) or an instance of that type. A forest has a single schema NC, which is replicated to each domain controller (DC) in the forest. No other NC replicas can contain these objects. Each attribute and class in the forest's schema is represented as a corresponding object in the forest's schema NC. Schema object: An object that defines an attribute or an object class. Schema objects are contained in the schema naming context (NC).

Page 264

ASP.NET MATERIAL
Scope of management (SOM): An Active Directory site, domain, or organizational unit container. These containers contain user and computer accounts that can be managed through Group Policy. These SOMs are themselves associated with Group Policy objects (GPOs), and the accounts within them are considered by the Group Policy Protocol [MSGPOL] to inherit that association. Scoped Group Policy object (GPO) distinguished name (DN): A Group Policy object (GPO) distinguished name (DN) where the set of "CN=<cn>" elements is prepended with "CN=User" for the user policy mode of Policy Application and with "CN=Machine" for computer policy mode. Scoped Group Policy object (GPO) path: A Group Policy object (GPO) path appended with "\User" for the user policy mode of policy application, and "\Machine" for the computer policy mode. Screen coordinates: Coordinates relative to the top-left corner of the screen, which has the coordinates (0,0). SCSI: See small computer system interface (SCSI). SCSI logical unit number (LUN): logical unit number (LUN). SCSI port number: A number that uniquely identifies a port on a small computer system interface (SCSI) disk controller. Each SCSI disk controller may support multiple SCSI bus attachments or ports for connecting SCSI devices to a computer. SCSI protocol: An architecture for SCSI, consisting of a group of standards created and maintained by the Technical Committee (T10) of the InterNational Committee on Information Technology Standards (INCITS). SD: See security descriptor. Secret key: A symmetric encryption key shared by two entities, such as between a user and the domain controller (DC), with a long lifetime. A password is a common example of a secret key. When used in a context that implies Kerberos only, a principal's secret key. Secret object: An element of the Local Security Authority (LSA) Policy Database, which contains a value that is secret in that access to it is strictly controlled through cryptographic protections and restrictive access control mechanisms. Sector: The smallest addressable unit of a disk.

Page 265

ASP.NET MATERIAL
Secure channel: An authenticated remote procedure call (RPC) connection between two machines in a domain with an established security context used for signing and encrypting RPC packets. Secure desktop: Only trusted processes running as SYSTEM are allowed to run on the secure desktop. Secure/Multipurpose Internet Mail Extensions (S/MIME): A standard for encrypted and digitally signed electronic mail that allows users to send encrypted messages and authenticate received messages. Secure Sockets Layer (SSL): A security protocol that supports confidentiality and integrity of messages in client and server applications communicating over open networks. SSL uses two keys to encrypt dataa public key known to everyone and a private or secret key known only to the recipient of the message. SSL supports server and, optionally, client authentication using X.509 certificates (for more information, see [X509]). The SSL protocol is precursor to Transport Layer Security (TLS). The TLS version 1.0 specification is based on SSL version 3.0. Security account manager (SAM) built-in database: Microsoft-specific terminology for the part of the user account database that contains account information (such as account names and passwords) for accounts and groups that are pre-created at the database installation. Security association (SA): A simplex "connection" that provides security services to the traffic carried by it. See [RFC4301] for more information. Security association database (SAD): A database that contains parameters that are associated with each established (keyed) security association. Security context: (1) An abstract data structure that contains authorization information for a particular security principal in the form of a collection of security identifiers (SIDs). One SID identifies the principal specifically, whereas others may represent other capabilities. A server uses the authorization information in a security context to check access to requested resources. (2) An association of mutually established cryptographic keys with a key identifier. Security descriptor: A data structure containing the security information associated with a securable object. A security descriptor identifies an object's owner by its security identifier (SID).

Page 266

ASP.NET MATERIAL
If access control is configured for the object, its security descriptor contains a discretionary access control list (DACL) with SIDs for the security principals who are allowed or denied access. Applications use this structure to set and query an object's security status. The security descriptor is used to guard access to an object as well as to control which type of auditing takes place when the object is accessed. Security identifier (SID): An identifier for security principals in Windows that is used to identify an account or a group. Conceptually, the SID is composed of an account authority portion (typically a domain) and a smaller integer representing an identity relative to the account authority, termed the relative identifier (RID). The SID format is specified in [MS-DTYP] section 2.4.2; a string representation of SIDs is specified in [MS-DTYP] section 2.4.2 and [MS-WSO] section 3.1.2.1.3. Security policy: In the form of a collection of security policy settings, the policy itself is an expression of administrative intent regarding how computers and resources on a network should be secured. Security policy database (SPD): A database that specifies the policies that determine the disposition of all IP traffic inbound or outbound from a host or security gateway. Security policy settings: Contained in security policies, the policy settings are the actual expression of how various security-related parameters on the computer are to be configured. Security principal: (1) A unique entity identifiable through cryptographic means by at least one key. A security principal often corresponds to a human user but can also be a service offering a resource to other security principals. Sometimes referred to simply as a "principal". (2) An identity that can be used to regulate access to resources, as specified in [MSWSO]. A security principal can be a user, a computer, or a group that represents a set of users. Security principal name (SPN): The name that identifies a security principal (for example, machinename$@domainname for a machine joined to a domain or username@domainname for a user). Domainname is resolved using the Domain Name System (DNS). Security principal object: An object that corresponds to a security principal. A security principal object contains an identifier, used by the system and applications to name the principal, and a secret that is shared only by the principal. In Active Directory, a security principal object has the objectSid attribute. In Active Directory, the user, computer, and

Page 267

ASP.NET MATERIAL
group object classes are examples of security principal object classes (though not every group object is a security principal object). Security protocol: A protocol that performs authentication and possibly additional security services on a network. Security provider: A pluggable security module that is specified by the protocol layer above remote procedure call (RPC), and will cause RPC to use this module to secure messages in a communication session with the server. Sometimes referred to as an authentication service. For more information, see [C706] and [MS-RPCE]. Security support provider (SSP): A dynamic-link library (DLL) that implements the Security Support Provider Interface (SSPI) by making one or more security packages available to applications. Each security package provides mappings between an application's SSPI function calls and an actual security model's functions. Security packages support security protocols such as Kerberos authentication and NTLM. Security Support Provider Interface (SSPI): A Windows-specific API implementation that provides the means for connected applications to call one of several security providers to establish authenticated connections and to exchange data securely over those connections. This is the Windows equivalent of Generic Security Services (GSS)-API, and the two families of APIs are on-the-wire compatible. Security token: An opaque message or data packet produced by a Generic Security Services (GSS)-style authentication package and carried by the application protocol. The application has no visibility into the contents of the token. Seed file or seed data: A file or files on the client that are used to supply data for reconstructing the source file. Remote differential compression (RDC) may use an arbitrary number of seed files in the process of copying a single source file. Sometimes called just "seed". Selecting seed files is implementation-specific, but can be guided by using similarity traits. Selective single master: A replication mode in which changes from only a single machine propagate to other machines. Self-signed certificate: A certificate that is signed by its creator and verified using the public key contained in it. Such certificates are also termed root certificates. Semisynchronous operation: An operation that is executed on the server side while the client is regularly checking to see if there is no response available from the server.

Page 268

ASP.NET MATERIAL
Sequence ID: A monotonically increasing 8-bit identifier for packets. This is typically represented as a field named bSeq in packet structures. Serial storage architecture (SSA) bus: Serial storage architecture (SSA) is a standard for high-speed access to high-capacity disk storage. An SSA bus is implemented to the SSA standard. Serialize: The process of taking an in-memory data structure, flat or otherwise, and turning it into a flat stream of bytes. See also, marshal. Server: (1) A computer on which the remote procedure call (RPC) server is executing. (2) A replicating machine that sends replicated files to a partner (client). The term "server" refers to the machine acting in response to requests from partners that want to receive replicated files. (3) A DirectPlay System application that is hosting a DirectPlay game session. In the context of DirectPlay 8, the term is reserved for hosts using client/server mode. Server-activated object (SAO): A server object that is created on demand in response to a client request. See also marshaled server object. Server authentication: A mode of authentication in which only the server in the transaction proves its identity. Server challenge: A 64-bit nonce generated on the server side. Server Group Policy object (GPO) distinguished name (DN): A Group Policy object (GPO) distinguished name (DN) that uses a specific server in the Lightweight Directory Access Protocol (LDAP) path syntax, as specified in [RFC2251], where the server name is a domain controller (DC) that is located as specified in [MS-NRPC] section 3.5.5.2.2. Server Group Policy object (GPO) path: A Group Policy object (GPO) path in which the Distributed File System (DFS) path contains a server name in the Distributed File System (DFS) path syntax and where the server name is a domain controller (DC). Server locator: Enables exporting of entries to the remote procedure call (RPC) name service. Server Message Block (SMB): A protocol that is used to request file and print services from server systems over a network. The SMB protocol extends the CIFS protocol with additional security, file, and disk management support. For more information, see [CIFS] and [MS-SMB].

Page 269

ASP.NET MATERIAL
Server object: A class of object in the config NC. A server object can have an nTDSDSA object as a child. Server role: The state of a domain controller (DC), which can be one of two values primary DC or backup DC. Server-scoped Group Policy object (GPO) distinguished name (DN): A scoped Group Policy object (GPO)distinguished name (DN) with a server name included in the path, as is the case for a server GPO DN. Server-scoped Group Policy object (GPO) path: A Group Policy object (GPO) path with a server name included in the path, as is the case for a server GPO path. Service: A process or agent that is available on the network, offering resources or services for clients. Examples of services include file servers, Web servers, and so on. Service account: A stored set of attributes that represent a principal that provides a security context for services. Service for User (S4U): Microsoft-specific extensions to the Kerberos protocol that allow a service to obtain a Kerberos service ticket for a user that has not authenticated to the key distribution center (KDC). S4U includes S4U2proxy and S4U2self. Service for User to Proxy (S4U2proxy): An extension that allows a service to obtain a service ticket on behalf of a user to a different service. Service for User to Self (S4U2self): An extension that allows a service to obtain a Kerberos service ticket to itself. The service ticket contains the user's groups and can therefore be used in authorization decisions. Service principal: An entity that represents a service at the key distribution center (KDC). The service principal has a name and an associated key. A subclass of principal, a service principal generally does not correspond to a human user of the system, but rather to an automated service providing a resource, such as a file server. Service principal name (SPN): The name by which a client uniquely identifies an instance of a service for mutual authentication. See [SPNNAMES] for more information about SPN format and composing a unique SPN. Also see [RFC1964] section 2.1.1. Service provider: A module that abstracts details of underlying transports for generic DirectPlay message transmission. Each DirectPlay message is transmitted by a DirectPlay service provider. The service providers that shipped with DirectPlay 4 are modem, serial, IPX, and TCP/IP.

Page 270

ASP.NET MATERIAL
Service (SRV) resource record: A domain name system (DNS) resource record used to identify computers that host specific services, as specified in [RFC2782]. SRV resource records are used to locate domain controllers (DCs) for Active Directory. Service set identifier (SSID): A sequence of characters that names a wireless local area network (WLAN). Service ticket: A ticket for any service other than the ticket-granting service (TGS). A service ticket serves only to classify a ticket as not a ticket-granting ticket (TGT) or cross-realm TGT, as specified in [RFC4120]. Session: (1) In Kerberos, an active communication channel established through Kerberos that also has an associated cryptographic key, message counters, and other state. (2) In Server Message Block (SMB), a persistent-state association between an SMB client and SMB server. A session is tied to the lifetime of the underlying NetBIOS or TCP connection. (3) In the Challenge-Handshake Authentication Protocol (CHAP), a session is a lasting connection between a peer and an authenticator. (4) In the Workstation service, an authenticated connection between two computers. (5) An active communication channel established through NTLM, that also has an associated cryptographic key, message counters, and other state. (6) In OleTx, a transport-level connection between a Transaction Manager and another Distributed Transaction participant over which multiplexed logical connections and messages flow. A session remains active so long as there are logical connections using it. Session key: A relatively short-lived symmetric key (a cryptographic key negotiated by the client and the server based on a shared secret). A session key's lifespan is bounded by the session to which it is associated. A session key should be strong enough to withstand cryptanalysis for the lifespan of the session. Session layer: The fifth layer in the Open Systems Interconnect (OSI) architectural model as defined by the International Organization for Standardization (ISO). The session layer is used for establishing a communication session, implementing security, and performing authentication. The session layer responds to service requests from the presentation layer and issues service requests to the transport layer.

Page 271

ASP.NET MATERIAL
Session Multiplex Protocol (SMUX): An entity on a network that implements the Secure Socket Tunneling Protocol (SSTP) and that listens for Secure Socket Tunneling Protocol (SSTP) connections over TCP port 443. Session security: The provision of message integrity and/or confidentiality to a session. SHA-1 hash: A hashing algorithm as specified in [FIPS180-2] that was developed by the National Institute of Standards and Technology (NIST) and the National Security Agency (NSA). Shadow copy: A duplicate of data held on a volume at a well-defined instant in time. Share: A resource offered by a Common Internet File System (CIFS) server for access by CIFS clients over the network. A share typically represents a directory tree and its included files (referred to commonly as a "disk share" or "file share") or a printer (a "print share"). If the information about the share is saved in persistent store (for example, Windows registry) and reloaded when a file server is restarted, then the share is referred to as a "sticky share". Some share names are reserved for specific functions and are referred to as special shares:

IPC$, reserved for interprocess communication. ADMIN$, reserved for remote administration. A$, B$, C$ (and other local disk names followed by a dollar sign), assigned to local disk devices.

share connect: The act of establishing authentication and shared state between a Common Internet File System (CIFS) server and client that allows a CIFS client to access a share offered by the CIFS server. Shell: Part of the Windows user interface (UI) that organizes and controls user access to a wide variety of objects necessary for running applications and managing the operating system. The most numerous are the folders and files that reside on computer storage media. There are also a number of virtual objects such as network printers and other computers. The shell organizes these objects into a hierarchical namespace and provides an API to access them. Shell link: A data object that contains information used to access another object in the shell's namespacethat is, any object visible through Windows Explorer. The types of objects that can be accessed through shell links include files, folders, disk drives, and printers. A shell link allows an application to access an object from anywhere in the namespace. The application does not need to know the current name and location of the object.

Page 272

ASP.NET MATERIAL
Shell shortcut: A shell link that has a shortcut icon; however, the terms shell link and shell shortcut are often used interchangeably. SID: See security identifier. Signal: In OleTx, the act of communicating an event between facets inside a transaction manager. Signature: A structure that contains a hash and block chunk size. The hash field is 16 bytes, and the chunk size field is a 2-byte unsigned integer. Signature file: A file containing the signatures of another (source) file. There is a simple header that identifies the type of the file as a signature file, the size of the header itself, and the remote differential compression (RDC) library version number. Following the header are the signatures from the source file in the order they are generated from the chunks. Signing certificates: The certificate that represents the identity of an entity (for example, a certificate authority (CA), a Web server or an S/MIME mail author) and is used to verify signatures made by the private key of that entity. For more information, see [RFC3280]. Similarity data: Information about a file that can be used to determine an appropriate seed file to select to reduce the amount of data transferred. Similarity data can be computed in any implementation-specific way. Similarity traits: Similarity data consists of one or more traits. Each trait summarizes an independent feature of a file. The features are computed by taking min-wise independent hash functions of a file's signatures. Similarity traits are used in selecting seed files. Simple and Protected GSS-API Negotiation Mechanism (SPNEGO): An authentication mechanism that allows Generic Security Services (GSS) peers to determine whether their credentials support a common set of GSS-API security mechanisms, to negotiate different options within a given security mechanism or different options from several security mechanisms, to select a service, and to establish a security context among themselves using that service. SPNEGO is specified in [RFC4178]. Simple Mail Transfer Protocol (SMTP): A TCP/IP protocol used in sending and receiving e-mail. Simple volume: A volume whose data exists on a single partition.

Page 273

ASP.NET MATERIAL
Single-instance storage (SIS): An NTFS feature that implements links with the semantics of copies for files stored on an NTFS volume. SIS uses copy-on-close to implement the copy semantics of its links. Single-phase commit: An optimization of the Two-Phase Commit Protocol in which a transaction manager delegates the right to decide the outcome of a transaction to its only subordinate participant. This optimization can result in an In Doubt outcome. site: An Active Directory term that defines a set of one or more TCP/IP subnets, where the subnets have high connectivity as measured in terms of latency (low) and bandwidth (high). By defining sites (represented by site objects) an administrator can easily configure Active Directory access and replication topology to take advantage of the physical network. When users log on, Active Directory clients find domain controllers (DCs) that are in the same site as the user or are near the same site if there is no DC in the site. For more information, see [MS-ADTS]. Site coverage: The set of sites for which a domain controller (DC) is responsible, as configured by the administrator. Site distinguished name (DN): The distinguished name for an object in Active Directory that represents a site. Site object: An object of class site, representing a site. Site of domain controller (DC): The site object that is an ancestor of the DC's nTDSDSA object. Site settings object: For a given site with site object s, its site settings object o is the child of s such that o is of class nTDSSiteSettings and the RDN of o is CN=NTDS site settings. SKU: See Stock Keeping Unit (SKU). Slow sync: The nominator for a synchronization subprotocol that is used to perform a consistency check between the databases of two partners. Small computer system interface (SCSI): A set of standards for physically connecting and transferring data between computers and peripheral devices. Small computer system interface (SCSI) bus: A standard for connecting peripheral devices to a computer. A SCSI bus is an implementation of this standard.

Page 274

ASP.NET MATERIAL
Smart card: A portable device that is shaped like a business card and is embedded with a memory chip and either a microprocessor or some non-programmable logic. Smart cards are often used as authentication tokens and for secure key storage. Smart cards used for secure key storage have the ability to perform cryptographic operations with the stored key without allowing the key itself to be read or otherwise extracted from the card. SMB connection: A transport connection between a Server Message Block (SMB) client and an SMB server. The SMB connection is assumed to provide reliable in-order message delivery semantics. An SMB connection can be established over any available SMB transport that is supported by both the SMB client and the SMB server, as specified in [MS-CIFS]. SMB dialect: There are several different versions and subversions of the Server Message Block (SMB) protocol. A particular version of the SMB protocol is referred to as an SMB dialect. Different SMB dialects can include both new SMB messages as well as changes to the fields and semantics of existing SMB messages used in other SMB dialects. When an SMB client connects to an SMB server, the client and server negotiate the SMB dialect to be used. SMB session: An authenticated user connection established between an SMB client and an SMB server over an SMB connection. There can be multiple active SMB sessions over a single SMB connection. The Uid field in the SMB packet header distinguishes the various sessions. SMTP: See Simple Mail Transfer Protocol (SMTP). Snapshot: The point in time at which a shadow copy of a volume is made. SOAP: A lightweight protocol for exchanging structured information in a decentralized, distributed environment. SOAP uses XML technologies to define an extensible messaging framework, which provides a message construct that can be exchanged over a variety of underlying protocols. The framework has been designed to be independent of any particular programming model and other implementation-specific semantics. SOAP 1.2 supersedes SOAP 1.1. SOAP 1.1: Version 1.1 of the SOAP (Simple Object Access Protocol) standard. For the complete definition of SOAP 1.1, see [SOAP1.1]. SOAP 1.2: Version 1.2 of the SOAP standard. Some examples of changes introduced in SOAP 1.2 include an updated envelope structure, as well as updates to the structure and sematics for SOAP faults. The binding framework was also updated to allow binding to non-HTTP transports. Starting with version 1.2, SOAP is no longer an acronym. See also SOAP.

Page 275

ASP.NET MATERIAL
SOAP action: The HTTP request header field used to indicate the intent of the SOAP request, using a URI value. See [SOAP1.1] section 6.1.1 for more information. SOAP body: A container for the payload data being delivered by a SOAP message to its recipient. See [SOAP1.2-1/2007] section 5.3 for more information. SOAP envelope: A container for SOAP message information and the root element of a SOAP document. See [SOAP1.2-1/2007] section 5.1 for more information. SOAP fault: A container for error and status information within a SOAP message. See [SOAP1.2-1/2007] section 5.4 for more information. SOAP fault code: The algorithmic mechanism for identifying a SOAP fault. See [SOAP1.2-1/2007] section 5.6 for more information. SOAP fault detail: A string containing a human-readable explanation of a SOAP fault, which is not intended for algorithmic processing. See [SOAP1.2-1/2007] section 5.4.5 for more information. SOAP header: A mechanism for implementing extensions to a SOAP message in a decentralized manner without prior agreement between the communicating parties. See [SOAP1.2-1/2007] section 5.2 for more information. SOAP header block: The XML block containing the SOAP header entries within a SOAP header. See [SOAP1.2-1/2007] section 5.2.1 for more information. SOAP message: An XML document consisting of a mandatory SOAP envelope, an optional SOAP header, and a mandatory SOAP body. See [SOAP1.2-1/2007] section 5 for more information. SOAP mustUnderstand attribute: A global, Boolean attribute that is used to indicate whether a header entry is mandatory or optional for the recipient to process. See [SOAP1.2-1/2007] section 5.2.3 for more information. Software installation package: A file that describes other files and metadata necessary to describe an application's executable files and state and to install that application. Also referred to as a "package". Software installation package modification: A file that allows an administrator to specify configuration for an application that is installed on the client through a software installation package.

Page 276

ASP.NET MATERIAL
Software maintenance utility: An application that allows users to perform software management activities such as installation, uninstallation, or inventory of applications available through the software installation extension. Software package container distinguished name (DN): A DN of the form "CN=Packages,<ClassStore>" where <ClassStore> is a class store container DN. Software package distinguished name (DN): A DN of the form "CN=<SoftwarePackageId>,CN=Packages,<ClassStore>", where <ClassStore> is a class store container DN and <SoftwarePackageId> is a curly braced GUID string. Software scripts path: A file system path to a directory with a path of the form "<ScopedGPOPath>\Applications", where <ScopedGPOPath> is a scoped GPO path. Source file, source data: A file on a server that is to be copied by remote differential compression (RDC). Sometimes referred to as "source". Sparse file: A file that has regions of data containing all zeros and in which some of the zero regions do not have disk space allocated for them. SPD: See security policy database. SPN: See service principal name. Spool file: A representation of application content data than can be processed by a print driver. Common examples are enhanced metafile format and XML paper specification. For more information, see [MSDN-META] and [MSDN-XMLP]. SSL: See Secure Sockets Layer (SSL). SSL/TLS handshake: The process of negotiating and establishing a connection protected by SSL or TLS. For more information, see [SSL3] and [RFC2246]. Staging file: The backup of the changed file or folder. It encapsulates the data and attributes associated with a replicated file or folder. By creating the staging file, File Replication Service (FRS) ensures that file data can be supplied to partners regardless of any activity that might prevent access to the original file. The staging files can be compressed to save disk space and network bandwidth during replication. Stamp: Information that describes an originating update by a domain controller (DC). The stamp is not the new data value; the stamp is information about the update that created the new data value. A stamp is often called metadata, because it is additional information that "talks about" the conventional data values. A stamp contains the

Page 277

ASP.NET MATERIAL
following pieces of information: the unique identifier of the DC that made the originating update; a sequence number characterizing the order of this change relative to other changes made at the originating DC; a version number identifying the number of times the data value has been modified; and the time when the change occurred. Standalone CA: A certificate authority (CA) that is not a member of a domain. For more information, see [MSFT-PKI]. Standalone machine: A machine that is not a domain member or a domain controller (DC). Standard user: A user that does not have administrative rights defined in its token and is a member of the users group. Users are prevented from making accidental or intentional system-wide changes but can perform normal daily computer tasks. State machine: A model of computing behavior composed of a specified number of states, transitions between those states, and actions to be taken. A state stores information about past transactions as it reflects input changes from the startup of the system to the present moment. A transition (such as connecting a network share) indicates a state change and is described by a condition that would need to be fulfilled to enable the transition. An action is a description of an activity that is to be performed at a given moment. There are several action types:

Entry action: Performed when entering the state. Exit action: Performed when exiting the state. Input action: Performed based on the present state and input conditions. Transition action: Performed when executing a certain state transition.

Statement of health (SoH): A collection of data generated by a system health entity, as specified in [MS-SOH], which defines the health state of a machine. The data is interpreted by a Health Policy Server, which determines whether the machine is healthy or unhealthy according to the policies defined by an administrator. Statement of health (SoH) client: A synonym for system health entity. Statement of health response (SoHR): A collection of data that represents the evaluation of the statement of health (SoH) according to network policies, as specified in [MS-SOH]. Station (STA): Any device that contains an IEEE 802.11 conformant medium access control and physical layer (PHY) interface to the wireless medium (WM).

Page 278

ASP.NET MATERIAL
Station management entity (SME): In general, a station management entity (SME) is regarded as responsible for functions such as the gathering of layer-dependent status from the various layer management entities and setting the value of layer-specific parameters. An SME would typically perform such functions on behalf of general system management entities and would implement standard management protocols. Stock Keeping Unit (SKU): A unique code that refers to a particular manufactured object or source of revenue. An SKU can refer to a retail product (software in a box that is sold through a channel), a subscription program (such as MSDN), or an online service (such as MSN). Stored procedure: A function/method that predefines a set of T-SQL commands that resides in a database server and is available to be called by client applications. StoreMaster: The single agent responsible for performing certain updates to file-link information stored in VolumeTable and FileTable within an Active Directory Table (ADT). For more information on VolumeTable and FileTable, see [MSDLT]. Stream: A sequence of bytes written to a file on the NTFS file system. Every file stored on a volume that uses the NTFS file system contains at least one stream, which is normally used to store the primary contents of the file. Additional streams within the file may be used to store file attributes, application parameters, or other information specific to that file. Every file has a default data stream, which is unnamed by default. That data stream, and any other data stream associated with a file, may optionally be named. Strict NDR/NDR64 data consistency check: A set of related rules for data validation during processing of an octet stream. Structural class: See structural object class. Structural object class: An object class that is not an 88 object class and can be instantiated to create a new object. Sub-authentication: Optional and additional authentication functionality, usually provided by extending an authentication algorithm. Sub-authentication package: An optional component that provides additional authentication functionality. If a sub-authentication package is installed, the authentication package calls the sub-authentication package before returning its authentication result. The request to verify by a sub-authentication package is indicated by the ParameterControl field of the LogonInformation parameter (see [MS-APDS] section 3.1.5.2.1, Verifying Responses with Sub-Authentication Packages).

Page 279

ASP.NET MATERIAL
Subkey: A child node in the logical tree of the hierarchical data store. Subnet site: The association of a site with a particular client, based on the client's IP address. Subordinate transaction manager: A role taken by a transaction manager that is responsible for voting on the outcome of an atomic transaction. A subordinate transaction manager coordinates the voting and notification of its subordinate participants on behalf of its superior transaction manager. When communicating with those subordinate participants, the subordinate transaction manager acts in the role of superior transaction manager. The root transaction manager is never a subordinate transaction manager. A subordinate transaction manager has exactly one superior transaction manager. SubRequest: A request within a SYNC_VOLUME or SEARCH request. Superclasses and subclasses: Types of common Information Model (CIM) classes. A subclass is derived from a superclass. The subclasses inherit all features of its superclass but can add new features or redefine existing ones. A superclass is the CIM class from which a CIM class inherits. Superior transaction manager: A role taken by a transaction manager that is responsible for gathering outcome votes and providing the final transaction outcome. A root transaction manager can act as a superior transaction manager to a number of subordinate transaction managers. A transaction manager can act as both a subordinate transaction manager and a superior transaction manager on the same transaction. Symbolic link: A symbolic link is a reparse point that points to another file systemobject. The object being pointed to is called the target. Symbolic links are transparent to users; the links appear as normal files or directories, and can be acted upon by the user or application in exactly the same manner. Symbolic links can be created using the FSCTL_SET_REPARSE_POINT request as specified in [MS-FSCC] section 2.3.53. They can be deleted using the FSCTL_DELETE_REPARSE_POINT request as specified in [MS-FSCC] section 2.3.5. Implementing symbolic links is optional for a file system. Symmetric algorithm: A cryptographic algorithm that uses one secret key that may be shared between authorized parties. The key must be kept secret between communicating parties. The same key is used for both encryption and decryption. For an introduction to this concept and terminology, see [CRYPTO] section 1.5, [IEEE1363] section 3, and [SP800-56A] section 3.1. Symmetric encryption: An encryption method that uses the same cryptographic key to encrypt and decrypt a given message.

Page 280

ASP.NET MATERIAL
Symmetric key: A secret key used with a cryptographic symmetric algorithm. The key needs to be known to all communicating parties. For an introduction to this concept, see [CRYPTO] section 1.5. Synchronous operation: An operation that is executed on the server side while the client is waiting for the response message. System access control list (SACL): An access control list (ACL) that controls the generation of audit messages for attempts to access a securable object. The ability to get or set an object's SACL is controlled by a privilege typically held only by system administrators. System command: A message that is sent to a window or notification icon via its system menu, or via a keyboard shortcut. Common system commands include minimize, maximize, move, and so on. system directory: A directory that contains system files comprising the operating system. system health entity: The entity on a machine that can generate a statement of health (SoH) for the machine and consume the corresponding statement of health response (SoHR). System menu: See window menu. system partition: A partition that contains the boot loader needed to invoke the operating system on the boot partition. A system partition must also be an active partition. It can be, but is not required to be, the same partition as the boot partition. system volume (SYSVOL): A shared directory that stores the server copy of the domain's public files that must be shared for common access and replication throughout a domain.

Page 281

ASP.NET MATERIAL

MASTER PAGES
Need of a Master Page, Basics of a Master Page, Content Page: Introduction:
One attribute of a well-designed website is a consistent site-wide page layout. Take the www.asp.net website, for example. At the time of this writing, every page has the same content at the top and bottom of the page. As Figure 1 shows, the very top of each page displays a gray bar with a list of Microsoft Communities. Beneath that is the site logo, the list of languages into which the site has been translated, and the core sections: Home, Get Started, Learn, Downloads, and so forth. Likewise, the bottom of the page includes information about advertising on www.asp.net, a copyright statement, and a link to the privacy statement.

Page 282

ASP.NET MATERIAL

Figure 01: Another attribute of a well-designed site is the ease with which the site's appearance can be changed. Figure 1 shows the www.asp.net homepage as of March 2008, but between now and this tutorial's publication, the look and feel may have changed. Perhaps the menu items along the top will expand to include a new section for the MVC framework. Or maybe a radically new design with different colors, fonts, and layout will be unveiled. Applying such changes to the entire site should be a fast and simple process that does not require modifying the thousands of web pages that make up the site. Creating a site-wide page template in ASP.NET is possible through the use of master pages. In a nutshell, a master page is a special type of ASP.NET page that defines the markup that is common among all content pages as well as regions that are customizable on a content page-by-content page basis. (A content page is an ASP.NET page that is bound to the master page.) Whenever a master page's layout or formatting is changed, all of its content pages' output is likewise immediately updated, which makes applying sitewide appearance changes as easy as updating and deploying a single file (namely, the master page). This is the first tutorial in a series of tutorials that explore using master pages. Over the course of this tutorial series we:

Examine creating master pages and their associated content pages, Discuss a variety of tips, tricks, and traps, Identify common master page pitfalls and explore workarounds, See how to access the master page from a content page and vice-a-versa, Learn how to specify a content page's master page at runtime, and Other advanced master page topics.

Page 283

ASP.NET MATERIAL
These tutorials are geared to be concise and provide step-by-step instructions with plenty of screen shots to walk you through the process visually. Each tutorial is available in C# and Visual Basic versions and includes a download of the complete code used. This inaugural tutorial starts with a look at master page basics. We discuss how master pages work, look at creating a master page and associated content pages using Visual Web Developer, and see how changes to a master page are immediately reflected in its content pages. Let's get started!

Understanding How Master Pages Work:


Building a website with a consistent site-wide page layout requires that each web page emit common formatting markup in addition to its custom content. For example, while each tutorial or forum post on www.asp.net have their own unique content, each of these pages also render a series of common <div> elements that display the top-level section links: Home, Get Started, Learn, and so on. There are a variety of techniques for creating web pages with a consistent look and feel. A naive approach is to simply copy and paste the common layout markup into all web pages, but this approach has a number of downsides. For starters, every time a new page is created, you must remember to copy and paste the shared content into the page. Such copying and pasting operations are ripe for error as you may accidentally copy only a subset of the shared markup into a new page. And to top it off, this approach makes replacing the existing site-wide appearance with a new one a real pain because every single page in the site must be edited in order to use the new look and feel. Prior to ASP.NET version 2.0, page developers often placed common markup in User Controls and then added these User Controls to each and every page. This approach required that the page developer remember to manually add the User Controls to every new page, but allowed for easier site-wide modifications because when updating the common markup only the User Controls needed to be modified. Unfortunately, Visual Studio .NET 2002 and 2003 - the versions of Visual Studio used to create ASP.NET 1.x applications - rendered User Controls in the Design view as gray boxes. Consequently, page developers using this approach did not enjoy a WYSIWYG design-time environment. The shortcomings of using User Controls were addressed in ASP.NET version 2.0 and Visual Studio 2005 with the introduction of master pages. A master page is a special type of ASP.NET page that defines both the site-wide markup and the regions where associated content pages define their custom markup. As we will see in Step 1, these regions are defined by ContentPlaceHolder controls. The ContentPlaceHolder control simply denotes a position in the master page's control hierarchy where custom content can be injected by a content page.

Page 284

ASP.NET MATERIAL
Note: The core concepts and functionality of master pages has not changed since ASP.NET version 2.0. However, Visual Studio 2008 offers design-time support for nested master pages, a feature that was lacking in Visual Studio 2005. We will look at using nested master pages in a future tutorial. Figure 2 shows what the master page for www.asp.net might look like. Note that the master page defines the common site-wide layout - the markup at the top, bottom, and right of every page - as well as a ContentPlaceHolder in the middle-left, where the unique content for each individual web page is located.

Figure 02: A Master Page Defines the Site-Wide Layout and the Regions Editable on a Content Page-by-Content Page Basis Once a master page has been defined it can be bound to new ASP.NET pages through the tick of a checkbox. These ASP.NET pages - called content pages - include a Content control for each of the master page's ContentPlaceHolder controls. When the content page is visited through a browser the ASP.NET engine creates the master page's control

Page 285

ASP.NET MATERIAL
hierarchy and injects the content page's control hierarchy into the appropriate places. This combined control hierarchy is rendered and the resulting HTML is returned to the end user's browser. Consequently, the content page emits both the common markup defined in its master page outside of the ContentPlaceHolder controls and the page-specific markup defined within its own Content controls. Figure 3 illustrates this concept.

Page 286

ASP.NET MATERIAL

Figure 03: The Requested Page's Markup is Fused into the Master Page. Now that we have discussed how master pages work, let's take a look at creating a master page and associated content pages using Visual Web Developer.

Page 287

ASP.NET MATERIAL
Note: In order to reach the widest possible audience, the ASP.NET website we build throughout this tutorial series will be created using ASP.NET 3.5 with Microsoft's free version of Visual Studio 2008, Visual Web Developer 2008. If you have not yet upgraded to ASP.NET 3.5, don't worry - the concepts discussed in these tutorials work equally well with ASP.NET 2.0 and Visual Studio 2005. However, some demo applications may use features new to the .NET Framework version 3.5; when 3.5-specific features are used, I include a note that discusses how to implement similar functionality in version 2.0. Do keep in mind that the demo applications available for download from each tutorial target the .NET Framework version 3.5, which results in a Web.config file that includes 3.5specific configuration elements. Long story short, if you have yet to install .NET 3.5 on your computer then the downloadable web application will not work without first removing the 3.5-specific markup from Web.config.

Step 1: Creating a Master Page:


Before we can explore creating and using master and content pages, we first need an ASP.NET website. Start by creating a new file system-based ASP.NET website. To accomplish this, launch Visual Web Developer and then go to the File menu and choose New Web Site, displaying the New Web Site dialog box (see Figure 4). Choose the ASP.NET Web Site template, set the Location drop-down list to File System, choose a folder to place the web site, and set the language to Visual Basic. This will create a new web site with a Default.aspx ASP.NET page, an App_Data folder, and a Web.config file.

Page 288

ASP.NET MATERIAL

Figure 04: Create a New File System-Based Web Site . Next, add a master page to the site in the root directory by right-clicking on the Project name, choosing Add New Item, and selecting the Master Page template. Note that master pages end with the extension .master. Name this new master page Site.master and click Add.

Page 289

ASP.NET MATERIAL

Figure 05: Add a Master Page Named Site.master to the Website. Adding a new master page file through Visual Web Developer creates a master page with the following declarative markup:
<%@ Master Language="VB" CodeFile="Site.master.vb" Inherits="Site" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> <asp:ContentPlaceHolder id="head" runat="server"> </asp:ContentPlaceHolder> </head> <body> <form id="form1" runat="server"> <div> <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </div> </form> </body> </html>

The first line in the declarative markup is the @Master directive. The @Master directive is similar to the @Page directive that appears in ASP.NET pages. It defines the server-side language (VB) and information about the location and inheritance of the master page's code-behind class. The DOCTYPE and the page's declarative markup appears beneath the @Master directive. The page includes static HTML along with four server-side controls:

Page 290

ASP.NET MATERIAL

A Web Form (the <form runat="server">) - because all ASP.NET pages typically have a Web Form - and because the master page may include Web controls that must appear within a Web Form - be sure to add the Web Form to your master page (rather than adding a Web Form to each content page). A ContentPlaceHolder control named ContentPlaceHolder1 - this ContentPlaceHolder control appears within the Web Form and serves as the region for the content page's user interface. A server-side <head> element - the <head> element has the runat="server" attribute, making it accessible through server-side code. The <head> element is implemented this way so that the page's title and other <head>-related markup may be added or adjusted programmatically. For example, setting an ASP.NET page's Title property changes the <title> element rendered by the <head> server control. A ContentPlaceHolder control named head - this ContentPlaceHolder control appears within the <head> server control and can be used to declaratively add content to the <head> element.

This default master page declarative markup serves as a starting point for designing your own master pages. Feel free to edit the HTML or to add additional Web controls or ContentPlaceHolders to the master page. Note: When designing a master page make sure that the master page contains a Web Form and that at least one ContentPlaceHolder control appears within this Web Form.

Creating a Simple Site Layout:


Let's expand Site.master's default declarative markup to create a site layout where all pages share: a common header; a left column with navigation, news and other site-wide content; and a footer that displays the "Powered by Microsoft ASP.NET" icon. Figure 6 shows the end result of the master page when one of its content pages is viewed through a browser. The red circled region in Figure 6 is specific to the page being visited (Default.aspx); the other content is defined in the master page and therefore consistent across all content pages.

Page 291

ASP.NET MATERIAL

Figure 06: The Master Page Defines the Markup for the Top, Left, and Bottom Portions. To achieve the site layout shown in Figure 6, start by updating the Site.master master page so that it contains the following declarative markup:
<%@ Master Language="VB" CodeFile="Site.master.vb" Inherits="Site" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> <asp:ContentPlaceHolder id="head" runat="server"> </asp:ContentPlaceHolder> <link href="Styles.css" rel="stylesheet" type="text/css" /> </head> <body> <form id="form1" runat="server"> <div id="topContent"> <a href="Default.aspx">Master Pages Tutorials</a> </div> <div id="mainContent"> <asp:ContentPlaceHolder id="MainContent" runat="server"> </asp:ContentPlaceHolder> </div> <div id="leftContent"> <h3>Lessons</h3> <ul> <li>TODO</li> </ul> <h3>News</h3> <ul> <li>TODO</li> </ul> </div> <div id="footerContent"> <img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" /> </div> </form> </body> </html>

Page 292

ASP.NET MATERIAL
The master page's layout is defined using a series of <div> HTML elements. The topContent <div> contains the markup that appears at the top of each page, while the mainContent, leftContent, and footerContent <div>s are used to display the page's content, the left column, and the "Powered by Microsoft ASP.NET" icon, respectively. In addition to adding these <div> elements, I also renamed the ID property of the primary ContentPlaceHolder control from ContentPlaceHolder1 to MainContent. The formatting and layout rules for these assorted <div> elements is spelled out in the Cascading Stylesheet (CSS) file Styles.css, which is specified via a <link> element in the master page's <head> element. These various rules define the look and feel of each <div> element noted above. For example, the topContent <div> element, which displays the "Master Pages Tutorials" text and link, has its formatting rules specified in Styles.css as follows:
#topContent { text-align: right; background-color: #600; color: White; font-size: x-large; text-decoration: none; font-weight: bold; padding: 10px; height: 50px; }

If you are following along at your computer, you will need to download this tutorial's accompanying code and add the Styles.css file to your project. Similarly, you will also need to create a folder named Images and copy the "Powered by Microsoft ASP.NET" icon from the downloaded demo website to your project.

Creating a Master Page Using an Existing Design Template:


Over the years I've built a number of ASP.NET web applications for small- to mediumsized companies. Some of my clients had an existing site layout they wanted to use; others hired a competent graphics designer. A few entrusted me to design the website layout. As you can tell by Figure 6, tasking a programmer to design a website's layout is usually as wise as having your accountant perform open-heart surgery while your doctor does your taxes. Fortunately, there are innumerous websites that offer free HTML design templates Google returned more than six million results for the search term "free website templates." One of my favorite ones is OpenDesigns.org. Once you find a website template you like, add the CSS files and images to your website project and integrate the template's HTML into your master page.

Step 2: Creating Associated Content Pages:


With the master page created, we are ready to start creating ASP.NET pages that are bound to the master page. Such pages are referred to as content pages.

Page 293

ASP.NET MATERIAL
Let's add a new ASP.NET page to the project and bind it to the Site.master master page. Right-click on the project name in Solution Explorer and choose the Add New Item option. Select the Web Form template, enter the name About.aspx, and then check the "Select master page" checkbox as shown in Figure 7. Doing so will display the Select a Master Page dialog box (see Figure 8) from where you can choose the master page to use.

Figure 07: Add a New Content Page.

Page 294

ASP.NET MATERIAL

Figure 08: Select the Site.master Master Page. As the following declarative markup shows, a new content page contains a @Page directive that points back to its master page and a Content control for each of the master page's ContentPlaceHolder controls.
<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="About.aspx.vb" Inherits="About" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> </asp:Content>

When rendering a content page, the ASP.NET engine must fuse the page's Content controls with its master page's ContentPlaceHolder controls. The ASP.NET engine determines the content page's master page from the @Page directive's MasterPageFile attribute. As the above markup shows, this content page is bound to ~/Site.master. Because the master page has two ContentPlaceHolder controls - head and MainContent Visual Web Developer generated two Content controls. Each Content control references a particular ContentPlaceHolder via its ContentPlaceHolderID property. Where master pages shine over previous site-wide template techniques is with their design-time support. Figure 9 shows the About.aspx content page when viewed through

Page 295

ASP.NET MATERIAL
Visual Web Developer's Design view. Note that while the master page content is visible, it is grayed out and cannot be modified. The Content controls corresponding to the master page's ContentPlaceHolders are, however, editable. And just like with any other ASP.NET page, you can create the content page's interface by adding Web controls through the Source or Design views.

Figure 09: The Content Page's Design View Displays Both the Page-Specific and Master Page Contents.

Adding Markup and Web Controls to the Content Page:


Take a moment to create some content for the About.aspx page. As you can see in Figure 10, I entered an "About the Author" heading and a couple of paragraphs of text, but feel free to add Web controls, too. After creating this interface, visit the About.aspx page through a browser.

Page 296

ASP.NET MATERIAL

Figure 10: Visit the About.aspx Page Through a Browser. It is important to understand that the requested content page and its associated master page are fused and rendered as a whole entirely on the web server. The end user's browser is then sent the resulting, fused HTML. To verify this, view the HTML received by the browser by going to the View menu and choosing Source. Note that there are no frames or any other specialized techniques for displaying two different web pages in a single window.

Binding a Master Page to an Existing ASP.NET Page:


As we saw in this step, adding a new content page to an ASP.NET web application is as easy as checking the "Select master page" checkbox and picking the master page. Unfortunately, converting an existing ASP.NET page to a master page is not as easy. To bind a master page to an existing ASP.NET page you need to perform the following steps:

Page 297

ASP.NET MATERIAL
1. Add the MasterPageFile attribute to the ASP.NET page's @Page directive, pointing it to the appropriate master page. 2. Add Content controls for each of the ContentPlaceHolders in the master page. 3. Selectively cut and paste the ASP.NET page's existing content into the appropriate Content controls. I say "selectively" here because the ASP.NET page likely contains markup that's already expressed by the master page, such as the DOCTYPE, the <html> element, and the Web Form. For step-by-step instructions on this process along with screen shots, check out Scott Guthrie's Using Master Pages and Site Navigation tutorial. The "Update Default.aspx and DataSample.aspx to use the Master Page" section details these steps. Because it is much easier to create new content pages than it is to convert existing ASP.NET pages into content pages, I recommend that whenever you create a new ASP.NET website add a master page to the site. Bind all new ASP.NET pages to this master page. Don't worry if the initial master page is very simple or plain; you can update the master page later.

Step 3: Updating the Master Page's Markup:


One of the primary benefits of master pages is that a single master page may be used to define the overall layout for numerous pages on the site. Therefore, updating the site's look and feel requires updating a single file - the master page. To illustrate this behavior, let's update our master page to include the current date in at the top of the left column. Add a Label named DateDisplay to the leftContent <div>.
<div id="leftContent"> <p style="text-align: center;"> <asp:Label ID="DateDisplay" runat="server"></asp:Label> </p> <h3>Lessons</h3> <ul> <li>TODO</li> </ul> <h3>News</h3> <ul> <li>TODO</li> </ul> </div>

Next, create a Page_Load event handler for the master page and add the following code:
Protected Sub Page_Load(ByVal sender As System.EventArgs) Handles Me.Load DateTime.Now.ToString("dddd, MMMM dd") End Sub Object, ByVal e DateDisplay.Text As =

The above code sets the Label's Text property to the current date and time formatted as the day of the week, the name of the month, and the two-digit day (see Figure 11). With this change, revisit one of your content pages. As Figure 11 shows, the resulting markup is immediately updated to include the change to the master page.

Page 298

ASP.NET MATERIAL

Figure 11: The Changes to the Master Page are Reflected When Viewing the a Content Page.

Summary:
Master pages enable ASP.NET developers to design a consistent site-wide layout that is easily updateable. Creating master pages and their associated content pages is as simple as creating standard ASP.NET pages, as Visual Web Developer offers rich design-time support. The mater page example we created in this tutorial had two ContentPlaceHolder controls, head and MainContent. We only specified markup for the MainContent ContentPlaceHolder control in our content page, however. In the next tutorial we look at using multiple Content controls in the content page. We also see how to define default markup for Content controls within the master page, as well as how to toggle between using the default markup defined in the master page and providing custom markup from the content page.

Page 299

ASP.NET MATERIAL

LOCALIZATION AND GLOBALIZATION

Introduction to mobile Programming:

The mobile controls provided by ASP .NET target, as the name suggests, mobile devices (cell phones, Palms, etc.). This article will give you an idea of how to develop mobile web applications using ASP .NET and the Microsoft Visual Studio .NET environment. It will describe some of the most important mobile specific controls but won't go deep into the subject. At the end we'll also take a look at the Pocket PC Emulator 2002 which is included in Visual Studio .NET. The ways mobile pages are organized differ from the classic web pages that you see on your computer. One mobile page is represented by a Form and a typical file (MobileWebForm1.aspx) can contain multiple forms, therefore multiple pages. This way when you open a page with the WAP browser actually multiple pages will be loaded (represented by forms) and when you click a link to one of the other forms there will be no loading time because they are in the same page. There is a good reason for this. Some WAP browsers disconnect after they retrieve the webpage to save the battery of the mobile phone and the money if the connection is charged per minute. This way they won't have to reconnect every time a new form is loaded, if it is located in the same file. Create a new ASP .NET Mobile Web Application project in Visual Studio .NET.

MobileWebForm1.aspx

is

created

with

form

on

it:

Page 300

ASP.NET MATERIAL

Also if you look in the HTML code you can see the tags that define this form:

<mobile:Form id=Form1 runat="server"></mobile:Form>

If you wish, you can add some content to it and view it on your mobile phone:

<mobile:Form id=Form1 runat="server"> Hello <i>visitor</i>! </mobile:Form>

If you don't have one (do you live in a cave?) you can compile and see the result in the IE window. Or you could download a simulator like the popular Openwave. The result is nothing extraordinary, just some simple text. Earlier in the article I said that an ASP .NET mobile page can contain multiple forms. In the following example we add a second form, Form2 and we link to it from Form1:

<mobile:form id=Form1 runat="server"> Hello <i>visitor</i>!<br /><br /> <mobile:link id="Link1" Runat="server" NavigateUrl="#Form2"> - About us </mobile:link> </mobile:form>

<mobile:form id=Form2 runat="server">

Page 301

ASP.NET MATERIAL
<b>About us</b><br /><br /> Here goes some information about the website. </mobile:form>

The linking is not done with the typical <a href> tag. Of course, after the code is compiled the HTML actually uses an <a href> tag but that's its job and not ours. As you can see the linking to the other form is done exactly like when using anchors. The result in the Openwave simulator is the following:

When you click that link you get to Form2 which displays the text "About us. Here goes

Page 302

ASP.NET MATERIAL
some information about the website." Displaying a graphic on a mobile phone is as easy as displaying it in a usual web browser. You don't use an <img> tag, but this one:

<mobile:Image id="Link2" Runat="server" NavigateUrl="#Form3" ImageUrl="http://www.yourwebsite.com/logo.gif" />

The List control:


This is a basic control that you'll be using in almost any WAP website. It provides sufficient functionality to prove itself useful. Let's see it in action. First add a link to the Form that includes the control:

<mobile:link id="Link2" Runat="server" NavigateUrl="#Form3"> - Get product list </mobile:link>

As you can see here, "Get product list" links to Form3, so let's create this form:

<mobile:form id="Form3" runat="server"><B>Product list</B><BR><BR></mobile:form>

Let's add to this form a specific ASP .NET mobile control - List.

<mobile:form id="Form3" runat="server"><B>Product list</B><BR><BR> Currently we have the following products for sale: <mobile:List id="List1" runat="server">

Page 303

ASP.NET MATERIAL
<Item Text="Microsoft Natural Keyboard" /> <Item Text="Philips 5.1 Surround Sound" /> <Item Text="HP LaserJet Printer" /> </mobile:List> </mobile:form>

If you run this application you can see that the result is just a simple list of the products we entered, if you look at the source code in Internet Explorer you can see that it's created with the help of a table. So what's so special about this control? Well depending on which device the page containing the control is opened, it will be displayed differently. For example on the web browser the list is created using a HTML table, while on a WML browser it will be created much simpler, by separating the items with <br /> tags. Another feature of Lists is that you can bind them to different data sources, like databases or XML files.

The AdRotator control:


Banner advertisements on WAP page appeared a short while after WAP was born. The AdRotator mobile control acts in the same way as the original AdRotator control does. The mobile control has a very useful feature - you can choose to display one type of image for typical computer browsers and other type of image for WML browsers.

The Calendar control:


Let's take a look at another mobile control - the Calendar. Adding a functional calendar to a WAP page was a very difficult task in the past, but with the Calendar control it's just a matter of dragging and dropping. So add a new link in Form1 that points to a new form, Form4:

<mobile:link id="Link3" Runat="server" NavigateUrl="#Form4"> - Calendar

Page 304

ASP.NET MATERIAL
</mobile:link>

Also add Form4 now:

<mobile:form id="Form4" runat="server"><B>Calendar</B><BR><BR></mobile:form>

If you drag and drop the Calendar control from the Toolbox inside Form4, the following tag will be added:

<mobile:Calendar id="Calendar1" runat="server"></mobile:Calendar>

The calendar control offers great functionality, of course a bit limited for WAP devices. The most important event of this control is called Calendar_SelectionChanged() and, as the name implies, occurs when the visitor selects a date on the calendar. You could build an entire mobile website based on this control. For example the user picks a day on the calendar and he can see the TV guide for that day, or the movies that run at some cinema.

The SelectionList control:


This control acts exactly as a typical DropDown control and also looks like one. Only that it can be made to look like a ListBox also, or like a radio control, or checkbox, or a ListBox that allows multiple items to be selected. This control can change its functionality by changing one of its properties called SelectType.

Page 305

ASP.NET MATERIAL

Also the tags generated by this control are different depending on the devices on which the page is loaded. On an usual computer browser it would display the typical HTML controls. Whereas on a WML browser it would be rendered using WML compatible tags. From a cell phone browser the visitor will have to select the item he wants by using the numeric key pad or by navigating to the wished item.

Pocket PC 2002 Emulator:


This emulator comes with the Microsoft Visual Studio .NET package and it's a really nice software to play with if you don't own a Pocket PC. After you're tired of playing with it you can use it for more productive purposes, developing and testing applications and web applications with it. You can fire up this emulator from the Tools menu, Connect to Device item. Choose Pocket PC 2002 Emulator (Default). You probably noticed there's a Windows CE .NET emulator also. Click Connect and the emulator should start in a few seconds. The first thing you'll want to do is set up your internet connection on it. You can do that from the Start menu -> Settings -> Connections tab -> Connections icon. Aside from the fact that this emulator is a very useful tool for testing your Pocket PC applications, you can also use it to see how your ASP .NET mobile pages look like on the Internet Explorer mobile browser. Open the MobileWebForm we created earlier in this article to see how the forms and controls we added look like on this device. Here's the calendar,forexample.

Page 306

ASP.NET MATERIAL

You can apply some stylesheet to it so it will look much better than it does now. So this emulator can also be used for testing web application, not just Windows mobile applications. A useful tool along with the emulators from Openwave and your WAP enabled cell phone. Using these you can develop flawless mobile applications.

Mobile Asp.Net Architecture:

Mobile Application Architecture:


Although ASP.NET integrates technology to make ASP.NET mobile Web application development follow the same paradigm as traditional Web application development, the architecture's primary intent is not to allow you to create single pages that can target browsers in both desktop and mobile devices. You can create adapters for individual ASP.NET or for mobile Web server controls that allow these controls to render for both desktop and mobile device browsers, but the limitations of browsers on mobile devices often mean that pages designed for desktop browsers do not translate very well to mobile device browsers. For example, if you create an ASP.NET Web page that includes a site header, a navigation bar along the top of the page, a secondary navigation structure along the side

Page 307

ASP.NET MATERIAL
of the page, and then content in the rest of the page, the page will render as designed in a desktop browser. In that case, there is usually ample space to render all the controls and still provide a scrollable content area. However, in many mobile device browsers, this layout would be impossible. Many mobile devices have a smaller screen area than desktop monitors, so even navigation becomes a multi-step process in which the user must click several controls to get to page content. Presentation logic follows a similar pattern. For example, when the user fills in a Web form using a desktop browser, the user can see many controls on the screen at once. When the form is validated on the server, validation errors can be displayed next to the controls. With a mobile device, form input and validation can be much harder to display in a format is usable. Additionally, for mobile devices you might choose to provide shortcuts that allow the user to fill in information with less typing because the device might be difficult to type on. For these reasons, it is recommended that you create separate pages in your ASP.NET Web application for use in desktop and mobile device browsers. A page developed specifically for mobile device browsers allows you to break down presentation logic into smaller pieces that work better for the device's display area and input hardware. When considering building such pages, therefore, you should use mobile Web server controls if your application must support a wide range of mobile devices, support browsers that do not use HTML, or support devices with limited display and input capabilities.

Mobile Web Server Controls:


The ASP.NET 2.0 System.Web.Mobile namespace is devoted specifically to mobile Web development. You can create a mobile Web page from the MobilePage base class and add mobile Web server controls from the System.Web.Mobile namespace. Mobile Web server controls have a number of specialized adapters in the framework and are therefore especially geared to developing mobile Web applications that target a wide range of mobile devices.

ASP.NET Web Server Controls and the Unified Adapter Architecture:


All ASP.NET 2.0 Web server controls adhere to the unified adapter architecture. This means that all controls can render and behave differently depending on the requesting device by calling a custom adapter that provides appropriate behaviors for that device, such as creating the proper markup language. If an adapter is configured in the browser definitions file for the requesting device or browser, ASP.NET calls the adapter at each life cycle stage of a Web server control. The adapter can then adjust rendered output and handle any device-specific view state logic or device idiosyncrasies. Browser definition files can be found in the Browsers folder of the .NET Framework Config directory or in the App_Browsers folder of a Web application.

Page 308

ASP.NET MATERIAL
You can create custom adapters for each device and have the ASP.NET page framework use those adapters when a specific device accesses your page.

Choosing Custom Adapters or Mobile Controls:


For most page developers, using the mobile Web server controls and creating pages that inherit from MobilePage is the recommended approach to mobile development. These controls support many mobile devices such as cell phones. ASP.NET includes mobile Web server controls for a wide variety of general Web development and mobile-specific needs. Additionally, mobile control device adapters already exist for major devices and their markup languages. Microsoft will continue to provide adapter updates for the mobile Web server controls when major markup languages evolve. This allows you to support new markup languages with the same controls that you are already using. For example, if you are creating an ecommerce site that supports desktop browsers as well as a large array of mobile devices, the recommended approach is to create a set of ASP.NET pages that inherit from the Page class and a separate set of pages that inherit from the MobilePage base class and use mobile controls. This provides you with mobile support without having to create custom adapters. The mobile Web server controls also follow the unified adapter architecture, so if you need to, you can create your own custom adapters or modify existing ones where new devices dictate new behavioral requirements in mobile Web server controls. There are scenarios where using ASP.NET Web server controls and writing custom adapters makes sense. These typically will be applications for rich desktop browsers where browser behavior variations are required, or for applications to be targeted by a constrained device class for which mobile controls and their feature set is not warranted. One example might be if you were creating an insurance claim application that had a browser-based interface for office use and a rich-device interface for field use. Your application could then use the same base page classes for both the regular pages and the rich-device pages. You would then need to create custom adapters only for the device that was deployed in the field. A benefit of creating custom adapters for the ASP.NET Web server controls is therefore that you can use the Page base class for your Web pages and be able to take full advantage of the ASP.NET 2.0 feature set.

Page 309

ASP.NET MATERIAL
Introduction: The ASP.NET Mobile controls are formerly known as the Microsoft Mobile Internet Toolkit (MMIT). Mobile controls extend the power of the .NET Framework and Visual Studio to build Mobile Web applications. The ASP.NET Mobile controls reduce the work required for developers to target a wide variety of browsers by eliminating the need to write and maintain numerous web applications each targeted to a specific browser. The ASP.NET Mobile controls render the appropriate markup (HTML 3.2, WML 1.1, cHTML. XHTML) while dealing with different screen sizes, orientations and device capabilities. Mobile Web Forms Controls: Mobile Web Forms Controls generate markup language for different devices. These are ASP.NET server side controls that provide user interface elements such as: List Command Call Calendar Form Panel Image, etc. The Mobile controls generate the correct markup for the device that makes the request at execution time. As a result, you can write a Mobile application once and access it from multiple devices.

MMIT [Microsoft Mobile Internet Toolkit]:

Because these Mobile controls are based on the ASP.NET controls, you can leverage your current desktop development skill set when creating mobile applications. You can also reuse the same business logic and data access code that you use in your desktop application. Mobile and desktop Web Forms can reside in the same Visual Studio .NET project. This makes an application faster to develop and lowers your maintenance cost. Mobile Web forms controls are as follows:

Page 310

ASP.NET MATERIAL

Figure 1: Mobile Web Form Controls. Creating Mobile Web Form Controls: There are the following steps for creating the Mobile Web Form Controls. Step 1: For creating a Mobile Web project open the new Web site in Microsoft visual studio 2005. You will get the following window.

Page 311

ASP.NET MATERIAL

Figure 2: Open New Website. Step 2: After open the New Website, go to the Solution Explorer right click on the Website and click on Add New item then you will get the following window:

Figure 3: Add New Item in Solution Explorer. Step 3: Add a mobile Web Forms page to the project. You will see the following code-

Page 312

ASP.NET MATERIAL
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %> <%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls" Assembly="System.Web.Mobile" %> Step 4: Drag a Mobile Web Forms control onto the form. Suppose we want to print Name and Address of any user in the Textbox. Then we drag two Textbox and two labels. Label is optional. The source code is as follows: <%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl2.ascx.cs"Inherits="WebUserControl2"%> <%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"Assembly="System.Web.Mobile" %> <table cellpadding="0" cellspacing="0" border="2" height="50px" style="width: 33%"> <tr> <td align="center" valign="top" style="padding-top:20px;"> <mobile:Label ID="Label1" Runat="server" BackColor="Gold" Visible="False">User name</mobile:Label> <mobile:TextBox ID="TextBox1" Runat="server" BackColor="#FFFFC0" Visible="False"></mobile:TextBox> <mobile:Label ID="Label2" Runat="server" BackColor="Gold" Visible="False">Address</mobile:Label> <mobile:TextBox ID="TextBox2" Runat="server" BackColor="#FFFFC0" Visible="False"></mobile:TextBox> </td> </tr> </table> In the following figure two Labels and two Textbox are drag from the Mobile controls. So the design view of the source code is as follows:

Figure 4: Design view of the above source code. Step 5: Double-click the control to write the logic.

Page 313

ASP.NET MATERIAL
Step 6: Rebuild the application. Step 7: Run the application. Mobile Internet Designer: The Mobile Internet Designer extends the Visual Studio .NET IDE to create Mobile applications. After you install the Mobile Internet Designer, you can create and develop your Mobile application in the same way that you would develop a Windows Forms or Web Forms application. The Mobile Internet Designer makes it fast and easy to build and maintain Mobile Web applications. DeviceCapabilityMechanism: Accurate information about the display capabilities of the target device is essential for the successful rendering of Mobile controls. Mobile controls need the following information about a device: Markup language (HTML, WML, cHTML) Browser Number of display lines Cookie support Screen size The Mobile Internet Toolkit adds these mobile device capabilities to the server's machine.config file (desktop ASP.NET applications use this file to maintain device and

browser information). Advanced Features: Extensibility Device adapter includes in the Mobile Internet Toolkit for a variety of mobile devices. Through the device capabilities mechanism The Mobile Internet Toolkit supports device adapters for additional devices. You can create new aggregate controls from existing Mobile controls. Conclusion: The Mobile Internet Toolkit provides the technology and tools to build, deploy, and maintain sophisticated Mobile applications quickly. Additional device support can be added using the Mobile Internet Toolkit's extensibility features.

Page 314

ASP.NET MATERIAL
Creating Mobile ASP.NET Page

ASP.NET Mobile Controls Overview:


Writing dynamic, high-performance mobile Web applications has never been easier. Over the past few years, the world has seen an explosion of new wireless devices, such as cell phones, pagers, and personal digital assistants (PDAs), which enable users to browse Web sites at any time from any location. Developing applications for these devices is challenging for the following reasons:

Different markup languages are necessary, including HTML for PDAs, wireless markup language (WML) for wireless application protocol (WAP) cell phones, and compact HTML (cHTML) for Japanese i-mode phones. Devices have different form factors. For example, devices have varying numbers of display lines, horizontal or vertical screen orientation, and color or black and white displays. Devices have different network connectivity, ranging from 9.6 KB cellular connections to 11 MB Wireless LANs. Devices have different capabilities. Some devices can display images, some can make phone calls, and some can receive notification messages.

The Microsoft Mobile Internet Toolkit addresses these challenges by isolating them from the details of wireless development. Thus, developers can quickly and easily build a single, mobile Web application that delivers appropriate markup for a wide variety of mobile devices.

Figure 1. The Hello, World program renders to both a cell phone and a Pocket PC

Page 315

ASP.NET MATERIAL
The Mobile Internet Toolkit contains:

Mobile Web Forms Controls that generate markup language for different devices. Mobile Internet Designer that works with the Visual Studio .NET integrated design environment (IDE) to provide a drag-and-drop mobile development environment. Browser Capabilities that are rich enough to extend ASP.NET device capabilities to mobile devices. QuickStart Tutorial with sample code. Developer Documentation. Device adapter code samples.

Mobile Web Forms Controls:


The mobile Web Forms controls are ASP.NET server-side controls that provide user interface elements such as list, command, call, calendar, and so on. At execution time, the mobile controls generate the correct markup for the device that makes the request. As a result, you can write a mobile application once and access it from multiple devices. Because these mobile controls are based on the ASP.NET controls, you can leverage your current desktop development skill set when creating mobile applications. You can also reuse the same business logic and data access code that you use in your desktop application. Mobile and desktop Web Forms can reside in the same Visual Studio .NET project. This makes an application faster to develop and lowers your maintenance cost. The following example provides just a taste of programming with mobile controls. In this example, the Hello, World program creates a mobile Web Forms page with a single form on it. That form contains a Label control with the string: Hello, Mobile World.
<%@ Page language="C#" Inherits="System.Web.UI.MobileControls.MobilePage" %> <%@ Register TagPrefix="Mobile" Namespace="System.Web.UI.MobileControls" Assembly="System.Web.Mobile" %> <mobile:Form id=Form1 runat="server"> <mobile:Label id=Test World</mobile:Label> </mobile:Form> Runat="Server">Hello, Mobile

In Figure 1 above, you can see how this code renders on different devices. The first device is a cell phone running a WAP browser that supports WML. The second device is Pocket PC running an HTML browser.

Page 316

ASP.NET MATERIAL
The Mobile Internet Toolkit also enables you to customize the markup that is generated by mobile controls for a specific device. You can designate templates and styles for a specific device within the mobile page.

Mobile Internet Designer:


The Mobile Internet Designer extends the Visual Studio .NET IDE to create mobile applications. After you install the Mobile Internet Designer, you can create and develop your mobile application in the same way that you would develop a Windows Forms or Web Forms application. The Mobile Internet Designer leverages the traditional Visual Studio design environment so that you can:

Create a mobile Web project. Add a mobile Web Forms page to the project. Drag a mobile Web Forms control onto the form. Double-click the control to write the logic. Rebuild the application. Run the application.

The Mobile Internet Designer makes it fast and easy to build and maintain mobile Web applications. In addition, it enables today's desktop developers to quickly learn how to create mobile applications by using Visual Studio .NET. The following illustration shows a mobile application developed in Visual Studio .NET with the Mobile Internet Designer.

Figure 2. Device Capability Mechanism

Page 317

ASP.NET MATERIAL
Accurate information about the display capabilities of the target device is essential for the successful rendering of mobile controls. At a minimum, mobile controls need the following information about a device:

Markup language (HTML, WML, cHTML) Browser Number of display lines Cookie support Screen size

The Mobile Internet Toolkit adds these mobile device capabilities to the server's machine.config file (desktop ASP.NET applications use this file to maintain device and browser information).

Advanced Features: Extensibility:


In addition to adding device characteristics, the Mobile Internet Toolkit includes device adapters for a variety of mobile devices. The device capabilities information in the machine.config file allows device adapters to optimize markup for specific devices. You can create new aggregate controls from existing mobile controls. The Mobile Internet Toolkit supports device adapters for additional devices through the device capabilities mechanism.

Conclusion:
The Mobile Internet Toolkit provides the technology and tools to build, deploy, and maintain sophisticated mobile applications quickly. Tight integration with Visual Studio .NET ensures that developers can leverage their existing desktop skill set and produce mobile applications. Additional device support can be added using the Mobile Internet Toolkit's extensibility features.

Page 318

ASP.NET MATERIAL

SITE NAVIGATION
ASP.NET Site Navigation Overview:
You can use ASP.NET site-navigation features to provide a consistent way for users to navigate your site. As your site grows, and as you move pages around in the site, it can become difficult to manage all of the links. ASP.NET site navigation enables you to store links to all of your pages in a central location, and render those links in lists or navigation menus on each page by including a specific Web server control. To create a consistent, easily managed navigation solution for your site, you can use ASP.NET site navigation. ASP.NET site navigation offers the following features:

Site maps You can use a site map to describe the logical structure of your site. You can then manage page navigation by modifying the site map as pages are added or removed, instead of modifying hyperlinks in all of your Web pages. ASP.NET controls You can use ASP.NET controls to display navigation menus on your Web pages. The navigation menus are based on the site map. Programmatic control You can work with ASP.NET site navigation in code to create custom navigation controls or to modify the location of information that is displayed in a navigation menu. Access rules You can configure access rules that display or hide a link in your navigation menu. Custom site-map providers You can create custom site-map providers that allow you to work with your own site-map back end (for example, a database where you store link information) and plug your provider into the ASP.NET sitenavigation system.

How Site Navigation Works:


With ASP.NET site navigation, you describe the layout of your site as a hierarchy. For example, a fictional online computer store might have a site comprised of eight pages, which are laid out in the following manner.
Home Products Hardware Software Services Training Consulting Support

Page 319

ASP.NET MATERIAL
To use site navigation, start by creating a site map, or a representation of your site. You can describe the hierarchy of your site in an XML file, but other options are also available. After you create a site map, you can display the navigation structure on an ASP.NET page by using a site-navigation control.

Site-Map Load Process:


The default ASP.NET site-map provider loads site-map data as an XML document and caches it as static data when the application starts. An excessively large site-map file can use a lot of memory and CPU power at load time. The ASP.NET site-navigation features depend on file notifications to keep navigation data up-to-date. When a site-map file is changed, ASP.NET reloads the site-map data. Make sure you configure any virusscanning software so that it does not modify site-map files.

Site-Navigation Controls:
Creating a site map that reflects the structure of your site is one part of the ASP.NET sitenavigation system. The other part is to display your navigation structure in your ASP.NET Web pages so that users can move easily around your site. You can easily build navigation into your pages by using the following ASP.NET site-navigation controls:

SiteMapPath This control displays a navigation path which is also known as a breadcrumb or eyebrow that shows the user the current page location and displays links as a path back to the home page. The control provides many options for customizing the appearance of the links. TreeView This control displays a tree structure, or menu, that users can traverse to get to different pages in your site. A node that contains child nodes can be expanded or collapsed by clicking it. Menu This control displays an expandable menu that users can traverse to get to different pages in your site. A node that contains child nodes is expanded when the cursor hovers over the menu.

If you add a SiteMapPath control to the Training page from the online computer store in the preceding example, the SiteMapPath control will display something like the following, with Home and Services rendered as hyperlinks: You can use the SiteMapPath control to create site navigation without code and without explicit data binding. The control can read and render the site-map information automatically. However, if necessary, you can also customize the SiteMapPath control with code.

Page 320

ASP.NET MATERIAL
The SiteMapPath control allows users to navigate backward from the current page to pages higher in the site hierarchy. However, the SiteMapPath control does not allow you to navigate forward from the current page to another page deeper in the hierarchy. The SiteMapPath control is useful in newsgroup or message-board applications when users want to see the path to the article that they are browsing. With the TreeView or Menu controls, users can open nodes and navigate directly to a specific page. These controls do not directly read the site map, as the SiteMapPath control does. Instead, you add a SiteMapDataSource control to a page that can read the site map. You then bind the TreeView or Menu control to the SiteMapDataSource control, resulting in the site map being rendered on the page. The TreeView control will display something like the following:

Site-Navigation API:
You can use navigation controls to add site navigation to your pages with little or no code, but you can also work with site navigation programmatically. When your Web application runs, ASP.NET exposes a SiteMap object that reflects the site-map structure. All of the members of the SiteMap object are static. The SiteMap object, in turn, exposes a collection of SiteMapNode objects that contain properties for each node in the map. (When you use the SiteMapPath control, the control works with the SiteMap and SiteMapNode objects to render the appropriate links automatically.) You can use the SiteMap, SiteMapNode, and SiteMapProvider objects in your own code to traverse the site-map structure or create a custom control to display site-map data. You cannot write to the site map, but you can alter site-map nodes in the instance of the object.

Relationships Between Site-Navigation Components:


The following illustration shows the relationships between the ASP.NET site-navigation components.

Page 321

ASP.NET MATERIAL

Page 322

ASP.NET MATERIAL

ASP.NET AJAX
Microsoft Ajax Overview: When you build an Ajax application, you provide your users with a richer and more responsive user experience. You can use Ajax features to enhance server-based ASP.NET Web Forms applications by using server-side ASP.NET controls, such as the UpdatePanel control. This topic focuses on enhancing server-based ASP.NET Web Forms applications. Why Use Microsoft Ajax Features? Web Forms applications that use Ajax features offer the following features:

Familiar interactive UI elements such as progress indicators, tooltips, and pop-up windows. Improved efficiency for Web Forms application, because significant parts of a Web page's processing can be performed in the browser. Partial-page updates that refresh only the parts of the Web page that have changed. Client integration with ASP.NET application services for forms authentication, roles, and user profiles. Auto-generated proxy classes that simplify calling Web service methods from client script. The ability to customize server controls to include client capabilities. Support for the most popular browsers, which includes Microsoft Internet Explorer, Mozilla Firefox, and Apple Safari.

Architecture of Microsoft Ajax Applications: A Microsoft Ajax Web application consists of either a client-only solution or a client and server solution. A client-only solution uses Microsoft Ajax Library but does not use any ASP.NET server controls. For instance, an HTML can include script elements that reference the Microsoft Ajax Library .js files. The Microsoft Ajax Library allows Ajax applications to perform all processing on the client. A client and server solution consists of using both the Microsoft Ajax Library and ASP.NET server controls. The following illustration shows the functionality that is included in the client-script libraries and server components that are included with .NET Framework 4.

Page 323

ASP.NET MATERIAL
Microsoft Ajax client and server architecture:

The illustration shows the functionality of the client-based Microsoft Ajax Library, which includes support for creating client components, browser compatibility, and networking and core services. The illustration also shows the functionality of server-based Microsoft Ajax features, which include script support, Web services, application services, and server controls. The following sections describe the illustration in more detail. Microsoft Ajax Client Architecture: The client architecture includes libraries for component support, browser compatibility, networking, and core services.

Components:
Client components enable rich behaviors in the browser without postbacks. Components fall into three categories:

Components, which are non-visual objects that encapsulate code. Behaviors, which extend the behavior of existing DOM elements. Controls, which represent a new DOM element that has custom behavior.

Page 324

ASP.NET MATERIAL
The type of component that you use depends on the type of client behavior you want. For example, a watermark for an existing text box can be created by using a behavior that is attached to the text box.

Browser Compatibility:
The browser compatibility layer provides Microsoft Ajax scripting compatibility for the most frequently used browsers (including Microsoft Internet Explorer, Mozilla Firefox, and Apple Safari). This enables you to write the same script regardless of which supported browser you are targeting.

Networking:
The networking layer handles communication between script in the browser and Webbased services and applications. It also manages asynchronous remote method calls. In many scenarios, such as partial-page updates that use the UpdatePanel control, the networking layer is used automatically and does not require that you write any code. The networking layer also provides support for accessing server-based forms authentication, role information, and profile information in client script. This support is also available to Web applications that are not created by using ASP.NET, as long as the application has access to the Microsoft Ajax Library.

Core Services:
The Ajax client-script libraries in ASP.NET consist of JavaScript (.js) files that provide features for object-oriented development. The object-oriented features included in the Microsoft Ajax client-script libraries enable a high level of consistency and modularity in client scripting. The following core services are part of the client architecture:

Object-oriented extensions to JavaScript, such as classes, namespaces, event handling, inheritance, data types, and object serialization. A base class library, which includes components such as string builders and extended error handling. Support for JavaScript libraries that are either embedded in an assembly or are provided as standalone JavaScript (.js) files. Embedding JavaScript libraries in an assembly can make it easier to deploy applications and can help solve versioning issues.

Page 325

ASP.NET MATERIAL
Debugging and Error Handling:
The core services include the Sys.Debug class, which provides methods for displaying objects in readable form at the end of a Web page. The class also shows trace messages, enables you to use assertions, and lets you break into the debugger. An extended Error object API provides helpful exception details with support for release and debug modes.

Globalization
The Ajax server and client architecture in ASP.NET provides a model for localizing and globalizing client script. This enables you to design applications that use a single code base to provide UI for many locales (languages and cultures). For example, the Ajax architecture enables JavaScript code to format Date or Number objects automatically according to culture settings of the user's browser, without requiring a postback to the server. Ajax Server Architecture: The server pieces that support Ajax development consist of ASP.NET Web server controls and components that manage the UI and flow of an application. The server pieces also manage serialization, validation, and control extensibility. There are also ASP.NET Web services that enable you to access ASP.NET application services for forms authentication, roles, and user profiles.

Script Support:
Ajax features in ASP.NET are commonly implemented by using client script libraries that perform processing strictly on the client. You can also implement Ajax features by using server controls that support scripts sent from the server to the client. You can also create custom client script for your ASP.NET applications. In that case, you can also use Ajax features to manage your custom script as static .js files (on disk) or as .js files embedded as resources in an assembly. Ajax features include a model for release and debug modes. Release mode provides error checking and exception handling that is optimized for performance, with minimized script size. Debug mode provides more robust debugging features, such as type and argument checking. ASP.NET runs the debug versions when the application is in debug mode. This enables you to throw exceptions in debug scripts while minimizing the size of release code. Script support for Ajax in ASP.NET is used to provide two important features:

Page 326

ASP.NET MATERIAL

The Microsoft Ajax Library, which is a type system and a set of JavaScript extensions that provide namespaces, inheritance, interfaces, enumerations, reflection, and additional features. Partial-page rendering, which updates regions of the page by using an asynchronous postback.

Localization:
The Microsoft Ajax architecture builds on the foundation of the ASP.NET 2.0 localization model. It provides additional support for localized .js files that are embedded in an assembly or that are provided on disk. ASP.NET can serve localized client scripts and resources automatically for specific languages and regions.

Web Services:
With Ajax functionality in an ASP.NET Web page, you can use client script to call both ASP.NET Web services (.asmx) and Windows Communication Foundation (WCF) services (.svc). The required script references are automatically added to the page, and they in turn automatically generate the Web service proxy classes that you use from client script to call the Web service. You can also access ASP.NET Web services without using Microsoft Ajax server controls (for example, if you are using a different Web development environment). To do so, in the page, you can manually include references to the Microsoft Ajax Library, to script files, and to the Web service itself. At run time, ASP.NET generates the proxy classes that you can use to call the services.

Application Services:
Application services in ASP.NET are built-in Web services that are based on ASP.NET forms authentication, roles, and user profiles. These services can be called by client script in an Ajax-enabled Web page, by a Windows client application, or by a WCF-compatible client.

Server Controls:
Ajax server controls consist of server and client code that integrate to produce rich client behavior. When you add an Ajax-enabled control to an ASP.NET Web page, the page automatically sends supporting client script to the browser for Ajax functionality. You can provide additional client code to customize the functionality of a control, but this is not required.

Page 327

ASP.NET MATERIAL
The following list describes the most frequently used Ajax server controls. Control Description Manages script resources for client components, partial-page rendering, localization, globalization, and custom user scripts. The ScriptManager ScriptManager control is required in order to use the UpdatePanel, UpdateProgress, and Timer controls. However, the ScriptManager control is not required when creating a client-only solution. Enables you to refresh selected parts of the page, instead of refreshing the UpdatePanel whole page by using a synchronous postback. Provides status information about partial-page updates in UpdatePanel UpdateProgress controls. Performs postbacks at defined intervals. You can use the Timer control to Timer post the whole page, or use it together with the UpdatePanel control to perform partial-page updates at a defined interval. You can also create custom ASP.NET server controls that include Ajax client behaviors. Custom controls that enhance the capabilities of other ASP.NET Web controls are referred to as extendercontrols Ajax Control Toolkit: The Ajax Control Toolkit contains controls that you can use to build highly responsive and interactive Ajax-enabled Web applications. These controls do not require knowledge of JavaScript or Ajax. They are designed using concepts that are familiar to ASP.NET Web Forms application developers. Using the Ajax Control Toolkit, you can build Ajaxenabled ASP.NET Web Forms applications and ASP.NET MVC Web applications by dragging the controls from the Visual Studio Toolbox onto a page. The Ajax Control Toolkit is an open-source project that is part of the CodePlex Foundation. For more information, see the Ajax Control Toolkit on the CodePlex Web site.

INTRODUCTION TO VISUAL STUDIO 2008

Page 328

ASP.NET MATERIAL
This introduce the main features of the Visual Basic 2008 Express Edition, and walks you through some of the most common tasks youll be doing as you create your programs. Youll be more familiar with the development environment and able to get started creating your first application. Some of the topics covered :

Setup Creating a Project The Windows Form Designer Writing Visual Basic code Compiling, Running and Saving your project Errors and Debugging Project Files, Properties and Customization Data Where to go from here

In This Section: Installation and Setup Essentials Find out about side-by-side support for earlier Visual Studio versions, the features available in each edition, and other information related to installing and maintaining Visual Studio. Introducing Visual Studio Find out more about what's new in Visual Studio, learn more about the .NET Framework, and find pointers on how to get started with this version of Visual Studio. Application Development in Visual Studio Find out about designing, developing, debugging, testing, deploying, and managing applications created by using Visual Studio.

Windows-based Applications, Components, and Services

Page 329

ASP.NET MATERIAL
Decide which tools and technologies to use when you build applications and components, and also what items that you can create with Visual Studio. .NET Framework Programming in Visual Studio Learn how to use the .NET Framework when you develop applications in Visual Basic, and Visual C#. Visual Basic Learn what's new in Visual Basic, and discover how to use Visual Basic to develop applications. Visual C# Learn what's new in Visual C#, and discover how to use Visual C# to develop applications. Visual C++ Find out about what's new in Visual C++ and discover how to use Visual C++ to develop applications. JScript Find out about JScript, a true object-oriented scripting language. Visual Web Developer Learn about Visual Web Developer and discover how to use Visual Web Developer to create Web applications. Visual Studio Tools for Office Find out how to create business applications that collect, analyze, adjust, or present information, and that take advantage of the functionality of Microsoft Office. Smart Device Development Learn how to develop software that runs on Windows CE-based smart devices such as Pocket PCs and Smartphones.

Page 330

ASP.NET MATERIAL
Tools and Features Read about Crystal Reports, programming for Windows Server features, and Application Verifier. Visual Studio SDK Find out about the Visual Studio Software Development Kit (SDK), which provides extensibility options and toolkits. Visual Studio Tools for Applications 2.0 Lets you customize existing applications by using Visual Basic and Visual C# to create add-ins. Visual Studio and .NET Framework Glossary Read through definitions for common terms used in the .NET Framework. Related Sections Deciding Which Technologies and Tools To Use Learn about the tools and technologies available to create various types of applications by using Visual Studio.

Page 331

ASP.NET MATERIAL
WCF [Windows Communication Foundation]
Windows Communication Foundation: Windows Communication Foundation (WCF) is Microsofts unified programming model for building service-oriented applications. It enables developers to build secure, reliable, transacted solutions that integrate across platforms and interoperate with existing investments.

In This Section:
Guide to the Documentation A set of suggested topics to read, depending on your familiarity (novice to wellacquainted) and requirements. Conceptual Overview The larger concepts behind WCF. Getting Started Tutorial A set of walkthrough topics that introduces you to the experience of programming WCF applications. Basic WCF Programming A set of primer topics that you should understand to become a proficient WCF programmer. WCF Feature Details Topics that let you choose which WCF feature or features you need to employ. Extending WCF Topics that describe extending or customizing WCF to suit your unique requirements. Guidelines and Best Practices Topics that can help you to avoid mistakes and to create reusable applications. WCF Administration and Diagnostics Topics that describe a set of WCF functionalities that can help you monitor the different stages of an applications life and diagnose problems. WCF System Requirements A list of WCF requirements.

Page 332

ASP.NET MATERIAL
Operating System Resources Required by WCF A list of the resources that are provided by the operating system. Troubleshooting Setup Issues Describes how to troubleshoot WCF setup issues. Windows Communication Foundation Glossary Glossary terms used in WCF. WCF Samples Downloadable samples that provide working code projects that demonstrate features and programming techniques for WCF. WCF Tools Tools that help you to create and debug WCF applications. General Reference Topics that document the XML elements used to configure services and client applications. Feedback and Community Information about sending your comments or sharing information with others interested in WCF. Windows Communication Foundation Privacy Information (Version 3.0) Information on a feature-by-feature basis about what WCF applications reveal about end users.

Reference:
System.Runtime.Serialization System.Runtime.Serialization.Configuration System.IdentityModel.Claims System.IdentityModel.Policy System.IdentityModel.Selectors System.ServiceModel.Security.Tokens System.ServiceModel

Page 333

ASP.NET MATERIAL
System.ServiceModel.Channels System.ServiceModel.Configuration System.ServiceModel.Security System.ServiceModel.Description System.IdentityModel.Tokens System.ServiceModel.MsmqIntegration System.ServiceModel.PeerResolvers System.Xml System.ServiceModel.Dispatcher System.IO.Log System.ServiceModel.Activation

Page 334

ASP.NET MATERIAL

INTRODUCTION TO SILVER LIGHT

What is Silverlight?
is a browser plug-in that that extends the web development experience far beyond the limitations of plain HTML and JavaScript. Being a Microsoft product, you might expect it to work best (or only) on Windows and Internet Explorer. So you may be pleasantly surprised to know that it works equally well on Windows and on the Mac, and it also works equally well on the Firefox and Safari web browsers. Since Silverlight is a client side technology, it doesn't matter what backend server software or platform you're running - even Apache/Linux will do just fine.
Silverlight

Version 1.0
version 1.0 - scheduled for release this summer - is very comparable to Adobe Flash. It delivers high performance multimedia and animation capabilities that can blend seamlessly with HTML. It's capable of playing a variety of audio and video file formats, such as MP3, WMA, and WMV. It handles streaming quite well, so media can start playing immediately without having to wait for the entire file to download.
Silverlight

Silverlight's user interface is defined with a subset of XAML - an XML format shared with Windows Presentation Foundation (WPF). This facilitates vector based animations, a claim that goes beyond Flash's current capabilities. Silverlight's compiled object model can be navigated via JavaScript for seamless interaction between embedded Silverlight components and the page that hosts them. When users encounter a Silverlight 1.0 enhanced web page for the first time, they'll be prompted with the quick & easy installation that's only about a 1.2 megabyte download.

Version 1.1:
While the multimedia and animation capabilities of Silverlight 1.0 are certainly great for graphic designers, Silverlight version 1.1 (currently in alpha) starts to provide the kind of business oriented functionality that the majority of web developers need. Probably the most exciting feature of version 1.1 is the built-in cross platform subset of the .NET Framework. While you can still mix in as much (or as little) JavaScript as you'd like, you'll now have the option of running your own fully compiled .NET code within IE, Firefox, or Safari. Those developers who hate JavaScript should be thrilled to know they can now write their client side code in C#, VB.NET, or any other .NET

Page 335

ASP.NET MATERIAL
language. This .NET code can interact with the browser's object model so it can manipulate the page's HTML in addition to interacting with any Silverlight user interface that may be embedded in the page. You'll now be able to replace slow performing JavaScript code with fully compiled .NET code that could easily execute hundreds of times faster. A variety of useful classes are included in Silverlight 1.1 for working with cutting edge technologies like LINQ, generics, multithreading, and invocation of Windows Communication Foundation (WCF) web services. There's also support for XML manipulation, networking, I/O, collections, globalization, and JSON serialization. support is also provided for things like personalization, profiles, role membership, and invocation of ASMX web services. On a related note, the next release of ASP.NET is expected to include a variety of tools for easing Silverlight development, including built-in controls that make it easy to embed Silverlight content.
ASP.NET

Unfortunately there are currently no definite plans to include any significant number of controls in Silverlight 1.1 - not even a basic button control is currently in the mix. They do at least provide a control class that can be used to build your own controls, and alternately it's not terribly difficult to make basic controls using XAML and some custom code - but certainly we'd prefer not to have to write such basic code. Luckily there are several controls available in the separate Silverlight 1.1 Alpha SDK download. Since Silverlight 1.1 is still only in alpha, its uncertain exactly what other functionality may ultimately make it into the release version. The current download size for this far more functional version of Silverlight hovers at around 4MB.

Future Versions:
From my conversations with Silverlight mastermind Scott Guthrie and his merry band of genius underlings, they've got a lot of mouthwatering functionality planned for upcoming versions of Silverlight. General themes include a rich set of built-in controls, data binding support, XLINQ, RSS, Xml Serialization, Opera support, and improved layout management. And that's just for starters. In general the vision is to transform Silverlight from its current 1.0 state of multimedia powerhouse into a highly productive business tool capable of powering rich applications of virtually every kind. Even with all this extra functionality, Silverlight's team has a long term secret goal of keeping the download size under 5MB. Shhhh! Don't tell anybody!

Page 336

ASP.NET MATERIAL
Development Tools:
Currently the lack of polished tools for developing Silverlight applications is its biggest hindrance. The next version of Visual Studio (codenamed Orcas) is expected to ship with rich Silverlight support. However, the current beta version of Orcas clearly still needs a lot of work before achieving this goal. If you're brave enough to be tinkering with the Orcas beta then you might as well download the Silverlight Tools Alpha add-on to try out its Silverlight development capabilities. Microsoft's new Expression suite of products is currently closer to being in a finished state. They are presently more polished and less buggy than Orcas. Specifically, Expression Blend is probably the most valuable Expression product for Silverlight development. However, be forewarned that the Expression suite is intended more for graphic designers than software developers. Therefore Visual Studio-oriented developers should expect a significant learning curve.

Summary:
is a brilliant idea that still has a ways to go before it reaches its potential. Nevertheless, it should definitely be on every web developer's radar. It's a distinct possibility that Silverlight could be the future of web development. Imagine a world where web developers no longer deal with HTML, and instead write rich, compiled .NET code that runs everywhere as ubiquitously as HTML does now. If Microsoft plays its cards right, this will happen.
Silverlight

References:
Silverlight's web site Silverlight download Silverlight documentation Free video tutorials Visual Studio "Orcas" Beta 1 Microsoft Silverlight Tools Alpha for Visual Studio codename Orcas Beta 1 Microsoft Expression Blend 2 Free Trial Microsoft ASP.NET Futures

Page 337

Das könnte Ihnen auch gefallen