Cutting Border

The Client Side of ASP.Net Pages

Dino Esposito

Code download available at:  Cut Border 2006_12.exe(153 KB)

Contents

Analysis of the ASPX Code
Analysis of the HTML Client Code
The View State Field
The PostBack Mechanism
Assay of Course Code

There's a trend in the software industry towards moving much of the burden of code writing to the infrastructure of the underlying platform. A variety of development platforms ask developers to provide a loftier-level description of the information they need in a relatively loose syntax, instead of hard-coding every single byte of it according to a strict ready of syntax rules. It is at present common for developers to use an XML dialect to describe the desired result and accept a compiler or runtime engine parse and process the contents into traditional and executable code.

For example, Windows® Presentation Foundation, one of the pillars of the .Cyberspace Framework 3.0, uses XAML as the XML-based presentation language to describe the user interface of the form. The Microsoft AJAX Library (part of the system formerly code-named ASP.NET "Atlas") applies the same principle to rich Spider web pages with its XML-Script metalanguage (although, technically, XML-Script is not part of the core release, simply rather it'due south being shared as an unofficial sample technology). A declarative layout linguistic communication, XML-Script wires up HTML elements and script together and forms virtual client-side controls. In the end, XML-Script injects logic and functionality in client pages.

There are a few advantages to using a declarative language to writer Web pages and forms. In this mode, server-side components can more than easily generate pages and forms than if they had to emit actual Visual Basic®, C#, or JavaScript code. Furthermore, declarative markup is inherently easier to devise and design for authoring tools such every bit Visual Studio®. From an architectural standpoint, by using a declarative approach you bespeak what folio elements will do, simply non how they will do information technology. In this way, you create an additional abstraction layer.

The first concrete programming environment to have advantage of such a model was ASP.NET, starting with version 1.0. As most Web developers should know past now, an ASP.Internet page is typically written in one or ii files: an .aspx markup file and, optionally, a code-backside file. The code-behind contains a class file written in any supported programming language, though typically Visual Basic or C#. The .aspx markup file contains HTML tags, ASP.Internet command tags, and literals that grade the structure of the page (it can besides contain code). This text is parsed at run time and transformed into a page class. Such a page form, combined with the lawmaking-behind grade and some system-generated code, comprise the executable lawmaking that processes any posted information, generates the response, and sends it dorsum to the client.

While the overall model is known to the vast majority of ASP.Net developers, a number of black holes exist that simply a small group of developers understand with much depth. MSDN®, books, and online manufactures explicate single aspects of the page machinery, but an overall and unified coverage of the page internals is still lacking. If you take a look at the HTML source code of an ASP.NET folio you see a number of hidden fields and automatically injected blocks of JavaScript code that y'all may hardly make sense of. Still, these fields and blocks contribute to make the Web folio work. In this column I'll analyze the client-side source lawmaking that ASP.Net pages generate. I'll encompass subconscious fields such every bit the well-known view state, but also piddling known ones such as control state, effect validation, outcome target, and argument and organization-provided script code.

Much of the implementation details I comprehend here are specific to the electric current version of ASP.Cyberspace. These details could modify in the future (they have changed in the past), and you shouldn't build any production lawmaking that depends on any undocumented details.

Analysis of the ASPX Code

Figure 1 shows a minimal just working ASP.NET page. Despite its farthermost simplicity, this is a adept sample equally it includes typical elements of a real-world ASP.Internet page-input fields, clickable postback elements, and read-only elements.

Figure one Sample ASP.Internet Page Set up for Dissection

              <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs"     Inherits="Examination" %>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="https://www.w3.org/1999/xhtml" > <caput runat="server"><title>Test page</title></head> <body>   <grade id="form1" runat="server">     <div>       <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>         <asp:Button ID="Button1" runat="server"          OnClick="Button1_Click" Text="Click me" />     </div>     <hour />     <h1><asp:Label ID="Msg" runat="server" Text=""></asp:Characterization></h1>   </grade> </body> </html>                          

The .aspx page contains iii server controls: a textbox to capture data, a Submit button to first a postal service functioning, and a label to display read-merely data. On top of the .aspx file, the Page directive defines some global attributes for the individual page. Let'due south take a expect at the near commonly used attributes of the Page directive, such every bit those that y'all saw in Figure i.

              <%@ Page Language="C#"           AutoEventWireup="true"           CodeFile="Test.aspx.cs"           Inherits="Examination"  %>                          

Near of the Page directive attributes have limited consequence on the folio markup, the HTML lawmaking that the browser receives with the HTTP response. Rather, most Folio attributes affect the lawmaking of the dynamically generated folio that the system builds on meridian of the .aspx markup and code-behind class. The Language attribute designates the linguistic communication used to author the code-backside in Visual Studio. The system volition utilise the same language to generate the dynamic page grade to serve the browser request for the .aspx resource. The CodeFile attribute indicates the source file where the code-backside form is stored. The Inherits attribute indicates the name of the lawmaking-behind class in the lawmaking file that should be used as the parent of the dynamically generated page grade. Finally, the AutoEventWireup attribute indicates whether a default naming convention should be used to map handling code to Folio events. When AutoEventWireup is set to true, you lot can add a Page_Load method to the code file to handle the page Load event, and information technology will automatically exist registered with the Folio's Load upshot. The implicit naming convention dictates that the event handler will take the form of Page_Thirty, where XXX can be the name of any public events defined on the Page grade. If AutoEventWireup is set to simulated, you must explicitly demark the Page class event with its handler. You can do that in a fabricated-to-measure course constructor:

              public partial grade Exam : Arrangement.Spider web.UI.Page {   public Test()   {     this.Load += new EventHandler(Page_Load);   }   ... }                          

When the Spider web server receives an HTTP request for a given .aspx resource, it frontwards the request to the ASP.Internet worker process. The procedure hosts the CLR, inside of which a runtime environs is created to procedure ASP.Cyberspace requests. The ultimate goal of the ASP.Internet HTTP runtime surroundings is serving the request-that is, obtaining the markup (HTML, WML, XHTML, and whatever else the app is supposed to return) which volition be embedded in the HTTP response. In charge of returning the markup for the request is a special organisation component known every bit the HTTP handler.

The HTTP handler is an instance of a course that implements the IHttpHandler interface. The ASP.Cyberspace framework comes with a few predefined HTTP handlers to serve particular situations or to act as a base form for other and more specialized requests. The System.Spider web.UI.Page class is ane of the well-nigh circuitous and sophisticated built-in HTTP handlers in ASP.NET.

Each ASP.NET asking is mapped to an HTTP handler. Suppose that a client browser places a request for a folio named test.aspx. The request is passed to ASP.Cyberspace and processed by the HTTP runtime. The runtime determines the HTTP handler course to serve the request through a page handler factory. If is the correct handler is not yet available in the AppDomain, it is created dynamically and stored in the ASP.Internet temporary binder on the Spider web server auto. For a page named test.aspx, the HTTP handler is created as a class named ASP.text_aspx.

The dynamic creation of the HTTP handler course for a given asking is a process that takes place just in one case per page, the starting time time that folio is requested in the application lifetime (although when batch compilation is used, the handler can be generated on the start asking for any page in the application). The dynamically created assembly is invalidated and replaced if the awarding is restarted or if the page source is modified on the Spider web server. Figure 2 shows the hierarchy of page classes from the base Page class downwardly to the dynamically generated form to serve the user request.

Figure 2 Hierarchy of Page Classes

Figure 2** Hierarchy of Page Classes **(Click the image for a larger view)

The ASP.NET runtime creates the Visual Basic or C# source code of the dynamic page class by parsing the source code of the corresponding .aspx file. Each tag with runat="server" is mapped to a server command instance. Whatever other text is mapped to a literal control and emitted verbatim. The Register directive, if any, helps to resolve tags pointing to non-standard controls. The markup returned to the client browser is composed by accumulating the markup that each server control in the page emits. Note that each page generally emits markup, usually HTML markup. Even so, this is not a requirement, and an ASP.Cyberspace page can output whatever information it wants.

Analysis of the HTML Client Code

Figure 3 shows the HTML output for the sample page in Figure ane. In the HTML at that place's no clue that a Page directive existed in the server-side .aspx page. Instead, the !DOCTYPE directive is copied verbatim. The first runat="server" block in Figure 1 is the <course> tag. This means that any text in between Page and <form> is emitted verbatim. In the source code of the dynamically created page course on the server, this text is converted into a single instance of the LiteralControl class. The <course> tag is emitted like this:

              <form name="form1" method="mail" activity="Test.aspx" id="form1">                          

Effigy three HTML Markup for a Exam Page

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="https://www.w3.org/1999/xhtml" > <caput><title>Test folio</title></head> <torso>   <form name="form1" method="mail" action="Exam.aspx" id="form1">     <div>       <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"          value="/wEPDw ... eeY=" />     </div>     <div>       <input proper name="TextBox1" blazon="text" id="TextBox1" />         <input type="submit" name="Button1"          value="Click me" id="Button1" />     </div>     <60 minutes />     <h1><span id="Msg"></span></h1>     <div>       <input type="subconscious" proper noun="__EVENTVALIDATION" id="__       EVENTVALIDATION"          value="/we ... u7" />     </div>   </form> </body> </html>                          

The <grade runat="server" ...> tag is rendered through an instance of the HtmlForm class. The control class has no property to let you fix the activity attribute on the output markup. The action attribute is hardcoded to the URL of the electric current folio. This behavior is at the foundation of the ASP.NET platform. Note that the ID aspect is partnered with an identical name attribute.

The <asp:textbox> tag is rendered in HTML through an <input type="text"> element. In this example, a name aspect is added to match the original ID attribute. Note that if you omit the ID attribute you may receive a alert from Visual Studio 2005, but ASP.Cyberspace volition still compile the page successfully. If the ID attribute is missing, a random string is generated and bound to the name attribute. The <asp:Button> tag is rendered through an <input blazon="submit"> button. An <asp:Label> tag will render the HTML <bridge> tag to the client browser.

In most cases (though not in all), each tag decorated with the runat="server" attribute generates a respective block of HTML markup. The ID string guarantees a persistent match between the ii blocks-ane on the customer side and one on the server side. Every bit you tin run across in Figure iii, a couple of hidden fields complete the HTML markup: __VIEWSTATE and __EVENTVALIDATION.

The View Country Field

The contents of the __VIEWSTATE field represent the state of the page when it was concluding processed on the server. Although sent to the client, the view country doesn't comprise any information that should exist consumed past the client. The information stored in view state is pertinent only to the server page and some of its kid controls and is exclusively read, consumed, and modified by the server.

Implemented in this mode, the view state doesn't consume any critical server resources and is fast to remember and use. On the other mitt, just because the view country is packed with the page, it inevitably increases the size of the HTTP request and response by a few kilobytes. Annotation that a realistic page padded with a filigree of data tin easily accomplish a view state size of 20KB. This extra stuff is uploaded and downloaded each and every time. The view country is one of the most important features of ASP.NET considering it enables stateful programming over a stateless protocol such as HTTP. Used without strict criteria, though, the view state tin can hands get a burden for pages.

Past overriding a couple of methods on the code file form, you tin can go out the contents of the view country field on the server, stored in a database, in the Cache or in the Session object. However, note that leaving the view country data on the server is non the obvious workaround information technology showtime appears. It'south not by chance, in fact, that the ASP.NET team opted for a page-based view country. A server-based view land is fine equally long as user navigates from one page to the adjacent post-obit the links in the awarding. Recall that ASP.NET applications work by posting repeatedly over the same page. Merely what if the user clicks the Back push button? To be safe, you should maintain view state on a per-request basis rather than on a per-page basis. And the chain of tracked requests should exist every bit long every bit the requests the user can accomplish through the Dorsum and Forward buttons. View state stored on the client may non exist perfect, but neither is view state stored on the server. The one that's preferable for your awarding depends on the expectations you take for it.

In ASP.NET 2.0, the __VIEWSTATE hidden field contains ii types of information-view state and command state. Developers can disable view state altogether and operate their applications in a pure stateless way. This is not an issue every bit long as yous use built-in controls and controls that you wrote yourself, or at least controls for which y'all accept admission to the source code. What if yous utilise a custom control that assumes an enabled view state? Some controls-typically, rich third-party and custom controls-need to persist private information across postbacks. This data is not public and non designed to be exposed to the application level-for example, the complanate/expanded condition of a dropdown panel. This information tin only be persisted to the view state. If the view land is disabled, the control may inadvertently fail.

To alleviate this issue, ASP.Cyberspace 2.0 introduces the notion of the control state. Each server control can pack whatsoever critical properties to a collection and store it to the page's control state. The control country is saved to the __VIEWSTATE field but, unlike the traditional view state, can't exist disabled and is always available. Developers manage the control state through a pair of new overridable methods on the Page course: LoadControlState and SaveControlState. Speaking of the view country in ASP.Net two.0, though, information technology is also worth noticing that a new and more effective serialization algorithm is employed to streamline the state of individual controls to a hidden field. Equally a result, the overall size of the __VIEWSTATE hidden field in most cases is as small as half the size of the corresponding field in ASP.Internet i.x.

As mentioned, the view state is stored in a hidden field to associate it unambiguously with a detail page request. When whatsoever of the HTML elements in a given page example post back, the dynamically generated page grade starts working on the server and uses the data stored in the view state to recreate the last known adept country for the controls in the page. What if the view state is tampered with on the customer? Is that ever possible? Past default, the view state is encoded using the Base64 schema and hashed, and the resulting hash value is besides stored with the view state. The hash value is calculated from the contents of the view state plus a server primal. Whenever the page posts back, the code in the page class separates the contents and hash value of the view state. Side by side, it recalculates the hash value based on the retrieved view country contents and server cardinal. If the two hash values don't lucifer, a security exception is thrown (come across Figure 4).

Figure 4 Page View Can't Be Altered on the Client

Figure iv** Page View Tin can't Be Altered on the Client **(Click the prototype for a larger view)

What if a malicious user attempts to post a fake request with a modified view land? The malicious user would need to know the server cardinal in order to generate a hash value on the modified view state contents that can be matched on the server. The server key, though, is made of server-only data and is not included in the view state field. The tweakviewstate.aspx page in the companion code contains script code to modify the view state and do with the exception shown in Figure 4.

Although the view state tin can inappreciably be used to plan an attack, it doesn't guarantee data confidentiality unless encryption is used. The contents of the view state, in fact, can be decoded and examined on the client, but not successfully modified to serve an contradistinct page state to the server environment.

The __EVENTVALIDATION subconscious field is a security measure new to ASP.Net two.0. The characteristic prevents unauthorized requests sent by potentially malicious users from the client. To ensure that each and every postback and callback event originates from the expected user interface elements, the page adds an actress layer of validation on events. The page basically matches the contents of the asking with the information in the __EVENTVALIDATION field to verify that no extra input field has been added on the client and that value is selected on a list that was already known on the server. The page generates the event validation field during rendering-that is at the concluding possible moment when the information is available. Like the view land, the event validation field contains a hash value to preclude client-side tampering.

Controls use the RegisterEventForValidation method on the ClientScriptManager object to store their ain information for safe postbacks. At a very minimum, each control registers its own unique ID. Listing controls also store all the values in the list. Server controls that back up effect validation typically call the ValidateEvent method in their implementation of the IPostBackDataHandler interface. If the validation fails, a security exception would be thrown.

You lot can enable and disable upshot validation on a per-page basis; each command course enables issue validation through the SupportsEventValidation attribute. Currently, there's no way to enable or disable event validation on a detail command instance.

Result validation is a defence force barrier aimed at limiting input to a known set of values. It simply raises the security bar higher and doesn't terminate script injection attacks by itself.

Event validation may pose issues if used in the context of AJAX-enabled applications. In such applications, some client work can create new input elements on the wing, thus making the next postback neglect considering of unknown elements. The all-time workaround is to render whatever user interface on the server whenever possible, and hide it on the client using the cascading manner sheets brandish attribute. In this way, any user interface you're going to employ is registered with the event validation field. If you write custom controls, you should decorate it with the SupportsEventValidation attribute to enable this feature.

The PostBack Mechanism

The ASP.NET page in Figure 1 posts back as the user clicks the button. This is because the <asp:Button> tag renders as an HTML submit <input> chemical element. When a submit input field is clicked, the browser fires the onsubmit HTML client event and then prepares the new request to the server based on the contents of the submitted class. The HTTP asking beingness sent includes an additional piece of information that evaluates to the ID of the button.

The page class scans the body of the HTTP request to run across if whatever of the posted fields matches the ID of a button control in the ASP.Cyberspace page. If the match is found, that push button control is called to run any code associated with its Click event. More than precisely, the page grade checks to see if the matching button control implements the IPostBackEventHandler interface. If so, it invokes the RaisePostbackEvent method on the interface. For a button control, the method raises the server-side Click event.

So far, and then good. But what if the folio contains a LinkButton control instead? Effigy v shows the markup for an ASP.NET page that is identical to the page in Figure i except that a LinkButton is used instead of the Submit button. As you lot can see, the markup includes two more than hidden fields, __EVENTTARGET and __EVENTARGUMENT, and a bit of JavaScript code. The href target of the link push button is bound to the __doPostback script function pregnant that the function will be invoked whenever a client click on the chemical element is detected. The __doPostback function is emitted in the page past the rendering code of the LinkButton control. Information technology populates the __EVENTTARGET and __EVENTARGUMENT fields with proper information and then triggers the postback via script. In this case, the trunk of the HTTP postback asking merely contains the input fields in the page and no posted data references the Submit push button.

Figure v HTML Markup Using a LinkButton Command

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML one.0 Transitional//EN"   "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="https://world wide web.w3.org/1999/xhtml" > <head><title>Test page</title></head> <body>   <form proper noun="form1" method="post" action="LinkBtn.aspx" id="form1">     <div>       <input blazon="hidden" proper noun="__EVENTTARGET"          id="__EVENTTARGET" value="" />       <input type="hidden" name="__EVENTARGUMENT"          id="__EVENTARGUMENT" value="" />       <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"          value="/wEP ... Eag==" />     </div>      <script type="text/javascript">     <!--       var theForm = certificate.forms['form1'];       if (!theForm) {         theForm = certificate.form1;       }       function __doPostBack(eventTarget, eventArgument) {         if (!theForm.onsubmit || (theForm.onsubmit() != false)) {           theForm.__EVENTTARGET.value = eventTarget;           theForm.__EVENTARGUMENT.value = eventArgument;           theForm.submit();         }       }     // -->     </script>      <div>       <input name="TextBox1" blazon="text" value="" id="TextBox1" />        <a id="LinkButton1"          href="https://javascript:__doPostBack('LinkButton1','')">Click me</a>        <hr />       <h1></h1>     </div>      <div>       <input type="hidden" proper name="__EVENTVALIDATION" id=          "__EVENTVALIDATION"          value="/wEW ... JbJ" />     </div>   </form> </body> </html>                          

How does ASP.Cyberspace recognize the control responsible for handling the postback? When no controls referenced in the request body implement the IPostBackEventHandler interface, the page class looks for the __EVENTTARGET hidden field, if any. The contents of the field is causeless to be the ID of the control that caused the postback. If this control implements the IPostBackEventHandler interface, the RaisePostbackEvent method is invoked. For a LinkButton command, this results in the invocation of the Click server event.

Analysis of Class Code

The .aspx markup defines the layout of an ASP.Internet folio and determines size, style and position of constituent controls. It contains no logic, however, except possibly for some client script code and any Visual Basic or C# inline code you may take. Initialization lawmaking, consequence handlers, and any helper routines typically go in a divide companion file, known equally the code-behind file:

              public partial grade Test : Organisation.Spider web.UI.Page {   protected void Page_Load(object sender, EventArgs east)   {     ...   }   protected void Button1_Click(object sender, EventArgs e)   {     ...   } }                          

The grade in the lawmaking file inherits, directly or indirectly, from Organisation.Web.UI.Folio. The code file and markup represent required but distinct pieces of information. To fully represent the ASP.Net page, they must be combined to grade a page course that incorporates the logic of the lawmaking file and the layout data of the markup file. The lawmaking file grade is already a page grade, but information technology lacks two fundamental pieces of information: the listing of kid server controls to populate the user interface and the declaration of form members that place the diverse server controls.

In ASP.Cyberspace 1.ten, each time the page author drops a control onto the Web Form, Visual Studio .Internet 2003 automatically adds a new line to the code file to create a grade member that handles the just dropped server command. This does a pretty good job of keeping everything in sync, but often developers meet compile errors due to the lack of a form member or existence of useless form members.

In ASP.NET 2.0 the upshot is fixed in an elegant way. Enter partial classes, a source-level, assembly-express, non-object-oriented manner to extend the beliefs of a course. In the .NET Framework ii.0, a course definition can span over ii or more files. Each file contains a fragment of the terminal grade definition and the compiler takes care of merging the diverse fractional definitions to form a single, unified class. All fragments must accept the same signature and the final form definition must be syntactically right.

Next, a second partial class is generated dynamically to list all command members. The ii partial classes are merged at compile-time. When the .aspx markup file is parsed to create the temporary ASP.test_aspx class, this class inherits from the combined code file in its terminal version. If the ASP.Cyberspace page is non jump to a code file but contains its lawmaking inline, then the dynamic folio class inherits from System.Web.UI.Page and includes any inline code in its body.

There's a lot more to learn about the dynamic page compilation machinery, simply this provides fodder for a future column.

Send your questions and comments for Dino to cut@microsoft.com.

Dino Esposito is a mentor at Solid Quality Learning and the writer of Programming Microsoft ASP.Internet ii.0 (Microsoft Printing, 2005). Based in Italy, Dino is a frequent speaker at industry events worldwide. Get in impact with Dino at cut@microsoft.com or join the blog at weblogs.asp.cyberspace/despos.