Fundamentals


We'll begin with a brief review of the fundamentals of ASP.NET, leading directly to a discussion of some of the new features in ASP.NET 2.0. This section presents the evolution of generating dynamic content, beginning with traditional classic ASP techniques and culminating in the new declarative data-binding model introduced in ASP.NET 2.0.

Dynamic Content

Writing a page to process a request in ASP.NET 2.0 is very much the same as it has been for the last few years with ASP.NET 1.1, and in fact for simple pages, it's very much the same as its earlier predecessor ASP. The same in-line evaluation syntax is still supported, as are server-side script blocks so that someone with a background only in building classic ASP pages should find this release of ASP.NET very approachable. Listing 1-1 shows a simple page that uses a server-side script block to define a helper method (GetDisplayItem) and then uses interspersed script to dynamically render elements in an unordered list. It also uses the server-side evaluation syntax (<%= %>) to intersperse dynamic content among static contentall common techniques dating back to building pages with ASP. The result of accessing the page through a browser is shown in Figure 1-1.

Figure 1-1. Rendering of SimplePage.aspx


Listing 1-1. SimplePage.aspxA simple .aspx file with dynamic content

<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> const int _itemCount = 10; string GetDisplayItem(int n) {     return "Item #" + n.ToString(); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head>     <title>Simple page</title> </head> <body>     <h1>Test ASP.NET 2.0 Page</h1>     <ul>     <% for (int i=0; i<_itemCount; i++) { %>     <li><%=GetDisplayItem(i)%></li>     <% } %>     </ul>     <%     Response.Write("<h2>Total number of items = " +                    _itemCount.ToString() + "</h2>");     %> </body> </html> 

The difference between this page and a classic ASP page is that in ASP.NET the entire file's contents is parsed into a class definition and then compiled into an assembly. Server-side script blocks are added directly to the class definition. Interspersed script is merged into a Render method of the class, which when called writes all of the static and dynamic content to the response. The class itself inherits from System.Web.UI.Page, which in turn implements the IHttpHandler interface to become an endpoint in the request-processing architecture of ASP.NET. This was the primary shift in the transition from classic ASP to ASP.NET: Instead of using script on your pages to interact with classes, your page becomes a class, and the interaction with other classes is identical to what it would be from any other class. Listing 1-2 shows a slightly simplified version of what the page in Listing 1-1 turns into after ASP.NET parses it into a class definition.

Listing 1-2. Parsed class generated by ASP.NET (simplified)[1]

namespace ASP {   public class simplepage_aspx : Page   {     const int _itemCount = 10;     string GetDisplayItem(int n)     {         return "Item #" + n.ToString();     }     protected override void Render(HtmlTextWriter writer)     {       writer.Write("<!DOCTYPE html PUBLIC \"-//W3C//DTD " +                    "XHTML 1.0 Transitional//EN\" \"http://www.w3"  +                    ".org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");       writer.Write("\r\n\r\n<html xmlns=\"http://www.w3.org/" +                 "1999/xhtml\" >\r\n<head>\r\n<title>Simple page<" +                 "/title>\r\n</head>\r\n<body>\r\n"                +                 "<h1>Test ASP.NET 2.0 Page</h1>\r\n    "          +                 "<ul>\r\n    ");       for (int i = 0; i < _itemCount; i++)       {         writer.Write("\r\n<li> ");         writer.Write(GetDisplayItem(i));         writer.Write("</li>\r\n    ");       }       writer.Write("\r\n</ul>\r\n");       Response.Write("<h2>Total number of items = " +                      _itemCount.ToString() + "</h2>");       writer.Write("\r\n</body>\r\n</html>\r\n");       base.Render(writer);     }   } } 

[1] The page shown in this listing is similar to the code that ASP.NET will generate when it parses your page. Steps have been taken to simplify some of the details for the purpose of presentation, but conceptually it is identical to the code generated by ASP.NET. If you would like to view the actual code that ASP.NET produces for any given page, do the following:

  1. Add Debug="true" to your @Page directive.

  2. Place <%= GetType().Assembly.Location %> somewhere on your page.

This will print the location of the assembly generated for your page. If you go to that directory, you will also see source code files (*.cs or *.vb) that contain the class definitions.

Server-Side Controls

Of course, most ASP.NET pages do not use interspersed script to inject dynamic content at all. Instead, they rely on the server-side control architecture introduced with ASP.NET. Server-side controls look much like the rest of the HTML elements in an .aspx page, but are marked with the runat="server" attribute and are typically prefixed with the "asp" namespace. When ASP.NET parses the page, these controls are added to the generated class definition not as methods or code, but as member variables representing the specific element (or collection of elements) they are designed to render. As an example, Listing 1-3 shows the same page we've been using rewritten to use server-side controls instead of interspersed script to render the list and H2 elements.

Listing 1-3. SimplePageWithControls.aspxA simple .aspx file using server-side controls

<%@ Page Language="C#" Debug="true" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> const int _itemCount = 10; string GetDisplayItem(int n) {   return "Item #" + n.ToString(); } protected override void OnLoad(EventArgs e) {   // Clear out items populated by static declaration   _displayList.Items.Clear();   for (int i=0; i<_itemCount; i++)     _displayList.Items.Add(new ListItem(GetDisplayItem(i)));   _messageH2.InnerText = "Total number of items = " +                          _itemCount.ToString();   base.OnLoad(e); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head>   <title>Simple page with controls</title> </head> <body>   <form runat="server"  >   <h1>Test ASP.NET 2.0 Page with controls</h1>   <asp:BulletedList runat="server" >       <asp:ListItem>Sample Item 1</asp:ListItem>       <asp:ListItem>Sample Item 2 ...</asp:ListItem>   </asp:BulletedList>   <h2 runat="server" >Total number of items = xx</h2>   </form> </body> </html> 

One of the primary advantages of using server-side controls is the complete separation of layout from programmatic logic. Note that instead of adding script elements to generate the dynamic portions of the page, we used the object model of the BulletedList control and the HtmlGenericControl (representing the H2 element) to populate their contents. This example also uses the fairly common technique of populating the static declarations of the server-side controls with sample content so that it is somewhat representative of what it will look like at runtime and will display properly in the designer for layout purposes.

The code generated by ASP.NET is actually a bit cleaner as well. No longer does the runtime have to create a special Render method to inter-weave interspersed script with static HTML strings. Instead, all static content on the page is represented using LiteralControls, which act like placeholders in the rendering process and return their associated strings when requested to render. Listing 1-4 shows the parsed class definition created by ASP.NET for the page shown in Listing 1-3 (the code has been simplified somewhat for clarity).

Listing 1-4. Parsed class generated by ASP.NET with server-side controls (simplified)

namespace ASP {   class SimplePageWithControls_aspx : Page   {     const int _itemCount = 10;     // Control declarations     protected BulletedList       _displayList;     protected HtmlGenericControl _messageH2;     protected HtmlForm           _form;     string GetDisplayItem(int n)     {       return "Item #" + n.ToString();     }     protected override void OnLoad(EventArgs e)     {       // Clear out items populated by control initialization       _displayList.Items.Clear();       for (int i = 0; i < _itemCount; i++)         _displayList.Items.Add(new ListItem(GetDisplayItem(i)));       _messageH2.InnerText = "Total number of items = " +                              _itemCount.ToString();       base.OnLoad(e);     }     protected override void  FrameworkInitialize()     {       Controls.Add(new LiteralControl("<!DOCTYPE html " +                 "PUBLIC \"-//W3C//DTD " +                 "XHTML 1.0 Transitional//EN\" \"http://www.w3" +                 ".org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> "));       Controls.Add(new LiteralControl("<html xmlns=\"http://" +                 "www.w3.org/1999/xhtml\" >" +                 "\r\n<head>\r\n    <title>Simple page " +                 "with controls</title>\r\n</head>\r\n<body>\r\n"));       _form = new HtmlForm();       _form.Controls.Add(new LiteralControl("<h1>Test ASP.NET 2.0 " +                                    "Page with controls</h1>\r\n    "));       _displayList = new BulletedList();       _displayList.ID = "_displayList";       _displayList.Items.Add(new ListItem("Sample Item 1"));       _displayList.Items.Add(new ListItem("Sample Item 2"));       _displayList.Items.Add(new ListItem("Sample Item 3"));       _form.Controls.Add(_displayList);       _messageH2 = new HtmlGenericControl("h2");       _messageH2.ID = "_messageH2";       _messageH2.Controls.Add(new LiteralControl("Total number " +                                                  "of items = xx"));       _form.Controls.Add(_messageH2);       Controls.Add(_form);       Controls.Add(             new LiteralControl("\r\n\r\n</body>\r\n</html>\r\n"));       base.OnPreInit(e);     }   } } 

Data Binding

Most of the time you won't even have to go through the trouble of programmatically populating the elements of a list control like we did in Listing 1-3, as all list controls (as well as others) in ASP.NET support data binding. We will cover the details of data binding in Chapter 3, but suffice it to say that you can take any enumerable collection of items and bind it to a server-side control (like the BulletedList control) and it will autocreate the items for you at runtime. Listing 1-5 shows an example of binding an array of strings to the BulletedList control. The process of binding a collection of data to a control consists of setting the DataSource property to an enumerable collection (like the array in our case or, in general, any type that implements the IEnumerable interface). You can also set up data binding completely declaratively, as we will discuss in Chapter 3.

Listing 1-5. SimplePageWithDataBinding.aspx

<%@ Page Language="C#" Debug="true" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> string[] _displayItemData = {"Item #1", "Item #2", "Item #3", "Item #4",     "Item #5", "Item #6", "Item #7", "Item #8", "Item #9", "Item #10"}; protected override void OnLoad(EventArgs e) {     _messageH2.InnerText = "Total number of items = " +                            _displayItemData.Length.ToString();     _displayItems.DataSource = _displayItemData;     _displayItems.DataBind();     base.OnLoad(e); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head>     <title>Simple page with controls</title> </head> <body>     <form runat="server" >         <h1>Test ASP.NET 2.0 Page with data binding</h1>         <asp:BulletedList runat="server" >             <asp:ListItem>Sample item 1</asp:ListItem>             <asp:ListItem>Sample item 2 ...</asp:ListItem>         </asp:BulletedList>         <h2 runat="server" >             Total number of items = xx</h2>     </form> </body> </html> 

The trio of parsing pages into class declarations, server-side controls, and a generic data-binding architecture are really the three pillars of Web development with ASP.NET. With these three core features and the .NET runtime environment to build on, developers have created many well-designed, scalable Web applications that are in use today. ASP.NET 2.0 builds on these pillars to give developers a more productive set of tools to work from, as we will see over the next several chapters.




Essential ASP. NET 2.0
Essential ASP.NET 2.0
ISBN: 0321237706
EAN: 2147483647
Year: 2006
Pages: 104

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net