Asp .Net Material
Asp .Net Material
Asp .Net Material
NET MATERIAL
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.
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.
Page 2
ASP.NET MATERIAL
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
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.
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.
Passport
Page 5
ASP.NET MATERIAL
ASP.NET authentication provider Description
authentication
offers a single logon and core profile services for member sites.
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 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 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 %>
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
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.
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.
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 %>
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.
ASP:
Page 14
ASP.NET MATERIAL
<% Dim Connection Set Connection = Server.CreateObject("ADODB.Connection") %> Asp.net: <% Dim Connection Connection = Server.CreateObject("ADODB.Connection") %>
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.
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
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
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.
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.
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.
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
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.
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.
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
Page 24
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
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
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
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.
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.
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
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.
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:
<script language="Javascript"> <!-/* ... Code goes here ... */ --> </script>
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")
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:
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.
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.
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
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.
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
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
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.
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);
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.
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();
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.
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.
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.
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:
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.
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.
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.
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.
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);
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"]); }
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 {
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); }
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);
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.
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:
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.
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.
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.
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>
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.
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)))
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)))
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.
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.
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.
Install Software:
Install DB2 Express-C by following the instructions in the installation program.
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
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
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).
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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. } " +
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. } " +
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.
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
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.
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
Use ASP.NET session state to store and retrieve values for a user. This topic contains:
Page 168
ASP.NET MATERIAL
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.
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.
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.
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 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.
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.)
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.
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.
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.
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.
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.
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.
Each model offers advantages and disadvantages both from a security and scalability perspective. The next sections describe these models.
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
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.
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.
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.
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.
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
Page 199
ASP.NET MATERIAL
Operating system identity flow requires an extended form of impersonation called delegation.
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.
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.
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
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
Files Folders Web pages (.aspx files) Web services (.asmx files)
Page 204
ASP.NET MATERIAL
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.
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.
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.
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.
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.
Figure 3.5. Choosing an authentication mechanism for intranet and extranet applications
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.
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> ...
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 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.
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.
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(); }
File authorization provided by the FileAuthorizationModule. URL authorization provided by the UrlAuthorizationModule. Role-based authorization.
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.
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.
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
or
methods
with
the
Page 215
ASP.NET MATERIAL
using System.Security.Permissions; ... [PrincipalPermission(SecurityAction.Demand,Role=@"Builtin\Admini strators")].
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.
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.
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.
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.
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.
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
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.
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.
Page 231
ASP.NET MATERIAL
Figure 3.
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.
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.
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
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.
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
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
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;
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
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
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>
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.
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.
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.
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.
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.
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.
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.
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();
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.
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).
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.
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 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 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.
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:
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 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.
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.
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!
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.
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.
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.
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.
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.
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.
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.
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
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:
If you wish, you can add some content to it and view it on your mobile phone:
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>
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:
As you can see here, "Get product list" links to Form3, so let's create this 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.
Page 304
ASP.NET MATERIAL
</mobile:link>
If you drag and drop the Calendar control from the Toolbox inside Form4, the following tag will be added:
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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).
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.
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-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.
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.
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.
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
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