Coding Issues


Chapter 1 looked at some of the main disadvantages of existing ASP applications, discussed why a new version was needed, and how ASP.NET solves some of those problems. The new ASP.NET coding model will seem familiar to those who have programmed in event-driven languages such as Visual Basic. It may at first seem a little alien to programmers who have only coded in script languages such as VBScript. However, it's extremely simple, provides many advantages, and leads to much more structured code. The code is no longer intermixed with the HTML, and its event- driven nature makes it easily structured for better readability and maintainability.

The first chapter showed how this worked for an OnClick event on a server control, and how the code to be run was broken into a separate event procedure. The corresponding example showed a list of states in a DropDownList server control. Using lists like this is extremely common, and often the list of items is generated from a data store.

To understand the difference between the pre-.NET ASP architecture and the new event-driven ASP.NET architecture, let's look at a sample page and compare the old and the new.

Coding the Old Way

To produce a list of items from a data store in ASP, you have to loop through the list of items, manually creating the HTML. When the item is selected, the form is posted back to the server. It looks something like the following ( OldAsp.asp ):

  <html>     <form action="OldAsp.asp" method="post">     Please select your delivery method:   <select id="ShipMethod" Name="ShipMethod" size="1">   <%   Dim rsShip   Dim SQL   Dim ConnStr   Dim ItemField     Set rsShip = Server.CreateObject("ADODB.Recordset")     SQL = "SELECT * FROM Shippers"   ConnStr = "Driver={SQL Server}; Server=localhost; " & _   "Database=Northwind; UID=sa"     rsShip.Open SQL, ConnStr     While Not rsShip.EOF   Response.Write "<option value='" & _   rsShip("ShipperID") & "'>" & _   rsShip("CompanyName") & "</option>" & vbCrLf   rsShip.MoveNext   Wend     rsShip.Close   Set rsShip = Nothing   %>   </select>   <br>   <input type="submit" value="Place Order">   </form>     <%   If Len(Request.Form("ShipMethod")) > 0 Then   Response.write "<br>Your order will be delivered via " & _   Request.Form("ShipMethod")   End If   %>   </html>  

This code is fairly simple “ it loops through a recordset building a SELECT list, allows the user to select a value, and submits that back to the server. In many situations, you'd probably build a database query or update based upon the selected value, but this example prints out the selected value.

Notice that only the value is available in the submitted page, and not the text value selected “ that's the way SELECT lists work. This is fine if you are going to use the value in a data query, but not if it needs to be displayed again. Let's see how this happens by looking at the generated HTML:

  <html>   <form action="OldAsp.asp" method="post">   Please select your delivery method:   <select id="ShipMethod" Name="ShipMethod" size="1">   <option value='1'>Speedy Express</option>   <option value='2'>United Package</option>   <option value='3'>Federal Shipping</option>   </select>   <br>   <input type="submit" value="Place Order">   </form>   <br>Your order will be delivered via 1   </html>  

The option elements have their value attribute as the ID of the shipping method, and it's the numeric value that's accessible from server-side ASP code.

Coding in ASP.NET Pages

As ASP.NET is event-based , you need to understand the order of events, so that you can see where the equivalent code would go. Code within these events is processed sequentially, but the events are processed only when they are raised. The event order is shown in Figure 4-1:

click to expand
Figure 4-1:

These events are:

Event

Description

Page_Init

Fired when the page is initialized

Page_Load

Fired when the page is loaded

Control Event

Fired if a control (such as a button) triggered the page to be reloaded

Page_Unload

Fired when the page is unloaded from memory

The difference between Page_Init and Page_Load is that the controls are only guaranteed to be fully loaded in the Page_Load . The controls are accessible in the Page_Init event, but the ViewState is not loaded, so controls will have their default values, rather than any values set during the postback.

For example, rewriting the original ASP page in ASP.NET yields the following ( NewAspNet.aspx ):

  <%@ Import Namespace="System.Data" %>   <%@ Import Namespace="System.Data.SqlClient" %>     <html>   <head>     <script language="VB" runat="server">     Sub Page_Load(Source As Object, E As EventArgs)     Dim myConnection As SqlConnection   Dim myCommand As SqlCommand   Dim myReader  As SqlDataReader   Dim SQL       As String   Dim ConnStr   As String     SQL = "SELECT * FROM Shippers"   ConnStr = "server=localhost;uid=sa;pwd=;database=Northwind"     myConnection = New SqlConnection(ConnStr)   myConnection.Open()   myCommand = New SqlCommand(SQL, myConnection)     myReader = myCommand.ExecuteReader()     ShipMethod.DataSource = myReader   ShipMethod.DataBind()     End Sub     Sub PlaceOrder_Click(Source As Object, E As EventArgs)   YouSelected.Text = "Your order will be delivered via " & _   ShipMethod.SelectedItem.Text     End Sub   </script>     <form runat="server">     Please select your delivery method:     <asp:DropDownList id="ShipMethod"   DataTextField="CompanyName" DataValueField="ShipperID"   runat="server"/>     <br/>     <asp:button id="PlaceOrder" Text="Place Order"   onClick="PlaceOrder_Click"   runat="server"/>     <br/>     <asp:Label id="YouSelected" runat="server"/>   </form>   </html>  

Next , let's examine this code in detail to see what the changes are, and why they've been done, starting with the HTML form:

 <form runat="server">         Please select your delivery method:         <asp:DropDownList id="ShipMethod"      DataTextField="CompanyName" DataValueField="ShipperID"      runat="server"/>         <br/>         <asp:button id="PlaceOrder" Text="Place Order"      onClick="PlaceOrder_Click"      runat="server"/>         <br/>         <asp:Label id="YouSelected" runat="server"/> </form> 

This example has three ASP.NET server controls “ a drop-down list, a button, and a label. The next chapter discusses server controls in detail, but for the moment, let's concentrate on the event side of things. So, just remember that these are server-side controls, and can therefore be accessed from within the server-side code.

The Import directives are placed at the start of the page to tell ASP.NET which code libraries to use. The two shown in the following code snippet are for data access, and are covered in detail in Chapters 8 and 9:

 <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %>      <html> <head> 

Next, the script block is started and the Page_Load event is defined. Remember this runs every time the page is loaded:

 <script language="VB" runat="server">         Sub Page_Load(Source As Object, E As EventArgs) 

The parameters to this event are fixed, and defined by ASP.NET. The first contains a reference to the source object that raised the event, and the second contains any additional details being passed to the event. For the Page_Load event, these parameters can be ignored, but later in the book you'll see where they come in useful.

Within this event, let's query the database and build the list of shipping methods . The data access code is not examined in detail, since it's covered in Chapters 8 and 9. It's roughly equivalent to the code in the previous example, simply creating a set of records from the database:

 Dim myConnection As SqlConnection Dim myCommand As SqlCommand Dim myReader As SqlDataReader Dim SQL As String Dim ConnStr As String      SQL = "SELECT * FROM Shippers" ConnStr = "server=localhost;uid=sa;pwd=;database=Northwind"      myConnection = New SqlConnection(ConnStr) myConnection.Open()      myCommand = New SqlCommand(SQL, myConnection)      myReader = myCommand.ExecuteReader() 

Once the records are created, data binding is used to fill the list ( ShipMethod ). In the ASP example, you actually had to create the HTML option elements in the loop, but in the ASP.NET page you can use the data-binding feature that allow controls to automatically populate themselves from a set of data (data binding is covered in detail in Chapter 7). The list is declared to run server-side, so its methods and properties can be accessed server-side. This is more like the Visual Basic programming environment where you are dealing with controls.

 ShipMethod.DataSource = myReader ShipMethod.DataBind() 

At this stage the code in the Page_Load event has finished. Since this is the first time the page has been executed, there are no control-specific events.

When you select an item in the list and click the button, the postback mechanism is invoked. The button was defined as:

 <asp:button id="PlaceOrder" Text="Place Order"    onClick="PlaceOrder_Click"    runat="server"/> 

The onClick attribute identifies the name of the server-side event procedure to be run when the button is clicked. Remember that this is server-side event processing, so there is no special client-side code. When this button is clicked, the form is submitted back to itself, and the defined event handler is run (after the Page_Load event):

 Sub PlaceOrder_Click(Source As Object, E As EventArgs)         YouSelected.Text = "Your order will be delivered via " & _       ShipMethod.SelectedItem.Text      End Sub 

This sets the text of a label to the value selected as shown in Figure 4-2:

click to expand
Figure 4-2:

This shows an interesting point. Because the list control is a server control, you have access not only to the value, but also to the text of the selected item. Although this is possible with ASP, the code required isn't as neat as the ASP.NET solution. In ASP, the selected item from the list would have to be determined programmatically, and then its value read so that its text could be displayed. In ASP.NET, the control, and its ViewState , handles it automatically.

Let's review these points:

  • Server-based controls can be accessed from server code. Even though these controls emit plain HTML, and are part of a standard HTML form, the architecture of ASP.NET ensures that they are accessible from server-side event procedures.

  • The Page_Load event is run every time the page is executed. This event should be used to populate the data in controls.

  • The control event is only run when fired by a server control. This is indicated by wiring up the event property on the control to an event procedure name.

Postback Identification

There is a big flaw in the code shown in the previous section. Because the Page_Load runs every time the page loads, the code in it will run even under a postback scenario “ that is, even when a button is pressed. This means that you are executing the data query and filling the drop-down every time, so whatever the user selected would be overwritten (as well as being unnecessary).

The IsPostBack property of the Page is designed to counter this problem, by allowing you to identify whether or not the page is in a postback situation (as opposed to the first time the page is loaded). This property can be used in the Page_Load event so that the data access code is only run the first time the page is loaded:

  Sub Page_Load(Source As Object, E As EventArgs)     If Not Page.IsPostBack Then     Dim myConnection As SqlConnection   Dim myCommand As SqlCommand   Dim myReader  As SqlDataReader   Dim SQL                As String   Dim ConnStr            As String     SQL = "select * from Shippers"   ConnStr = "server=localhost;uid=sa;pwd=;database=Northwind"     myConnection = New SqlConnection(ConnStr)   myConnection.Open()     myCommand = New SqlCommand(SQL, myConnection)     myReader = myCommand.ExecuteReader()     ShipMethod.DataSource = myReader   ShipMethod.DataBind()   End If     End Sub  

This code runs only when the page is first loaded. The contents of the list won't disappear, because the contents are held within the ViewState of the drop-down list. The HTML this produces is very similar to the old ASP example:

  <html>   <head>     <form name="_ctl0" method="post" action="NewASPNet.aspx" id="_ctl0">   <input type="hidden" name="__VIEWSTATE"   value="dDw0NDY2MjMzMjt0PDtsPGk8MT47PjtsPHQ8O2w8aTwxPjtpPDU+Oz47bDx0PHQ8O3Q8aTw   zPjtAPFNwZWVkeSBFeHByZXNzO1VuaXRlZCBQYWNrYWdlO0ZlZGVyYWwgU2hpcHBpbmc7PjtAPDE7M   jszOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxZb3VyIG9yZGVyIHdpbGwgYmUgZGVsaXZlcmVkIHZ   pYSBVbml0ZWQgUGFja2FnZTs+Pjs+Ozs+Oz4+Oz4+Oz4=" />     Please select your delivery method:   <select name="ShipMethod" id="ShipMethod">   <option value="1">Speedy Express</option>   <option selected="selected" value="2">United Package</option>   <option value="3">Federal Shipping</option>   </select>     <br/>     <input type="submit" name="PlaceOrder" value="Place Order" id="PlaceOrder" />     <br/>     <span id="YouSelected">Your order will be delivered via United Package</span>   </form>   </html>  

The asp:DropDownList produces an HTML select list along with the associated option elements. The form posting is still handled in the same way as ASP. The major difference is the hidden VIEWSTATE field, containing the ViewState control. We'll look at this topic a little later in the chapter.

As mentioned in Chapter 1, the new model for ASP.NET is based around the separation of the visual portion of the web form (the HTML code) from the logic portion (the executable code). In this way, the operation of web forms is much closer to the way that Visual Basic forms have worked in the past than they are to traditional web pages.

Web Forms also help to solve a number of challenges in using a browser-based execution engine to provide a user experience that is similar to today's Windows applications. These challenges include:

  • Delivering rich user interfaces on a wide variety of platforms. Web forms can free the developers from the actual client being used, allowing them to focus on providing the necessary business logic.

  • Merging a client-server application where code is being executed in two different locations into a more traditional event-driven programming model. Web forms accomplish this by providing a single methodology for dealing with application events “ no matter if the event was fired on the client, or on the server.

  • Providing state management in an execution environment that is inherently stateless. Many different methods have been used in the past to provide for a stateful execution environment for the stateless Web world. These methods have ranged from cookies, to hidden form fields, to state information being held on the server. Yet each one of these methods presented a different programmatic interface to the developer, forcing them to choose at development time the type of state management to use. Web forms insulate developers from this by providing a standard way of maintaining state for developers, while hiding the actual implementation details.

Even though we develop the application's presentation and the logic separately, it is important to know that when they are actually executed, they come together as one unit. Even if the logic exists in one file and the presentation in another, at runtime they are compiled into a single object, which is represented by the Page class.




Professional ASP. NET 1.1
Professional ASP.NET MVC 1.0 (Wrox Programmer to Programmer)
ISBN: 0470384611
EAN: 2147483647
Year: 2006
Pages: 243

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