When you create ASP.NET web applications using Visual Studio 2005, you have the option ofgenerating a new virtual directory for the current website.. To illustrate some HTML basics, open
Trang 1' Update Inventory Table with new row.
Dim newCar As DataRow = dsCarInventory.Tables("Inventory").NewRow()newCar("CarID") = newCarID
newCar("Make") = newCarMakenewCar("Color") = newCarColornewCar("PetName") = newCarPetNamedsCarInventory.Tables("Inventory").Rows.Add(newCar)Try
dAdpater.Update(dsCarInventory.Tables("Inventory"))Catch
Console.WriteLine("Sorry! Error! Canceling request")End Try
End Sub
Once you have created your command object, you plug it into the adapter via the InsertCommandproperty Next, you add a new row to the Inventory DataTable maintained by the dsCarInventoryobject Once you have added this DataRow back into the DataTable, the adapter will execute the SQLfound within the InsertCommand property, given that the RowState of this new row is DataRowState.Added
Setting the UpdateCommand Property
The modification of the UpdateCarPetName() method is more or less identical Simply build a newcommand object and plug it into the UpdateCommand property
Private Sub UpdateCarPetName(ByVal dAdpater As SqlDataAdapter)
Dim carToUpdate As Integer = 0
Dim newPetName As String = ""
Console.Write("Enter CarID of car to modify: ")
Try
carToUpdate = Integer.Parse(Console.ReadLine())Catch ex As FormatException
Console.WriteLine(ex.Message)Return
carRowToUpdate(0)("PetName") = newPetName
Try
dAdpater.Update(dsCarInventory.Tables("Inventory"))Catch
Console.WriteLine("Sorry! Error! Canceling request")End Try
End Sub
In this case, when you select a specific row (via the Select() method), the RowState value ofsaid row is automatically set to DataRowState.Modified The only other point of interest here is thatthe Select() method returns an array of DataRow objects; therefore, you must specify the exact rowyou wish to modify
Trang 2Setting the DeleteCommand Property
Last but not least, you have the following update to the DeleteCar() method:
Private Sub DeleteCar(ByVal dAdpater As SqlDataAdapter)
' Get ID of car to delete, then do so.
carRowToDelete(0).Delete()
Try
dAdpater.Update(dsCarInventory.Tables("Inventory"))Catch
Console.WriteLine("Sorry! Error! Canceling request")End Try
End Sub
In this case, you find the row you wish to delete (again using the Select() method) and then setthe RowState property to DataRowState.Deleted by calling Delete()
■ Source Code The CarsInvertoryUpdaterDS project is included under the Chapter 24 subdirectory
Autogenerating SQL Commands Using
CommandBuilder Types
You might agree that working with data adapters can entail a fair amount of code, given the need
to build each of the four command objects and the associated connection string (or
DbConnection-derived object) To help simplify matters, each of the ADO.NET data providers that ships with NET 2.0
provides a command builder type Using this type, you are able to automatically obtain command
objects that contain the correct Insert, Delete, and Update command types based on the initial
a data adapter, the related command builder will read the database’s schema data to autogenerate
the underlying insert, delete, and update command objects
Consider the following example, which deletes a row in a DataSet using the autogenerated SQLstatements
Trang 3' Autogenerate INSERT, UPDATE, and DELETE commands
' based on exiting SELECT command.
Dim da As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Inventory", cn)
Dim invBuilder As SqlCommandBuilder = New SqlCommandBuilder(da)
' Fill data set.
Catch e As Exception
Console.WriteLine(e.Message)End Try
' Refill and reprint Inventory table.
theCarsInventory = New DataSet()
Now, while you may love the idea of getting something for nothing, do understand that mand builders come with some critical restrictions Specifically, a command builder is only able toautogenerate SQL commands for use by a data adapter if all of the following conditions are true:
com-• The Select command interacts with only a single table (e.g., no joins)
• The single table has been attributed with a primary key
• The column(s) representing the primary key is accounted for in your SQL Select statement
If these restrictions are unacceptable, rest assured that much of the ADO.NET “grunge” codewill be autogenerated by the Visual Studio 2005 Windows Forms and ASP.NET designer surfaces andintegrated wizards You’ll see the Windows Forms ADO.NET wizards in action at the conclusion ofthis chapter (and their ASP.NET counterparts in Part 7)
■ Source Code The MySqlCommandBuilder project is found under the Chapter 24 subdirectory
Multitabled DataSets and DataRelation Objects
Currently, all of this chapter’s examples involved DataSets that contained a single DataTable object.However, the power of the disconnected layer really comes to light when a DataSet object containsnumerous interrelated DataTables In this case, you are able to insert any number of DataRelationobjects into the DataSet’s DataRelation collection to account for the interdependencies of the tables.Using these objects, the client tier is able to navigate between the table data without incurringnetwork round-trips
Trang 4Figure 24-17. Viewing related DataTables
To illustrate the use of data relation objects, create a new Windows Forms project called tabledDataSet The GUI is simple enough In Figure 24-17 you can see three DataGridView widgets
Multi-that hold the data retrieved from the Inventory, Orders, and Customers tables of the Cars database
In addition, the single Button pushes any and all changes back to the data store
To keep things simple, the MainForm will make use of command builders to autogenerate theSQL commands for each of the three SqlDataAdapters (one for each table) Here is the initial update
to the Form-derived type:
Public Class MainForm
' Formwide DataSet.
Private carsDS As DataSet = New DataSet("CarsDataSet")
' Make use of command builders to simplify data adapter configuration.
Private sqlCBInventory As SqlCommandBuilder
Private sqlCBCustomers As SqlCommandBuilder
Private sqlCBOrders As SqlCommandBuilder
' Our data adapters (for each table).
Private invTableAdapter As SqlDataAdapter
Private custTableAdapter As SqlDataAdapter
Private ordersTableAdapter As SqlDataAdapter
' Formwide connection object.
Private cn As SqlConnection = _
New SqlConnection("server=(local);uid=sa;pwd=;database=Cars")
End Class
Trang 5The Form’s constructor does the grunge work of creating your data-centric member variables andfilling the DataSet Also note that there is a call to a private helper function, BuildTableRelationship(),
invTableAdapter = New SqlDataAdapter("Select * from Inventory", cn)
custTableAdapter = New SqlDataAdapter("Select * from Customers", cn)
ordersTableAdapter = New SqlDataAdapter("Select * from Orders", cn)
' Autogenerate commands.
sqlCBInventory = New SqlCommandBuilder(invTableAdapter)
sqlCBOrders = New SqlCommandBuilder(ordersTableAdapter)
sqlCBCustomers = New SqlCommandBuilder(custTableAdapter)
Private Sub BuildTableRelationship()
' Create CustomerOrder data relation object.
Dim dr As DataRelation = New DataRelation("CustomerOrder", _
carsDS.Tables("Customers").Columns("CustID"), _carsDS.Tables("Orders").Columns("CustID")) _carsDS.Relations.Add(dr)
' Create InventoryOrder data relation object.
dr = New DataRelation("InventoryOrder", _
carsDS.Tables("Inventory").Columns("CarID"), _carsDS.Tables("Orders").Columns("CarID")) _carsDS.Relations.Add(dr)
End Sub
Now that the DataSet has been filled and disconnected from the data source, you can manipulateeach table locally To do so, simply insert, update, or delete values from any of the three DataGridViews.When you are ready to submit the data back for processing, click the Form’s Update button Thecode behind the Click event should be clear at this point:
Private Sub btnUpdate_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnUpdate.Click
Trang 6invTableAdapter.Update(carsDS, "Inventory")custTableAdapter.Update(carsDS, "Customers")ordersTableAdapter.Update(carsDS, "Orders")Catch ex As Exception
MessageBox.Show(ex.Message)End Try
End Sub
Once you update, you will find that each table in the Cars database has been correctly altered
Navigating Between Related Tables
To illustrate how a DataRelation allows you to move between related tables programmatically,
extend your GUI to include a new Button type and a related TextBox The end user is able to enter
the ID of a customer and obtain all the information about that customer’s order, which is placed in
a simple message box The Button’s Click event handler is implemented as follows:
Private Sub btnGetInfo_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGetInfo.Click
Dim strInfo As String = ""
Dim drCust As DataRow = Nothing
Dim drsOrder As DataRow() = Nothing
' Get the specified CustID from the TextBox.
Dim theCust As Integer = Integer.Parse(Me.txtCustID.Text)
' Now based on CustID, get the correct row in Customers table.
drCust = carsDS.Tables("Customers").Rows(theCust)
strInfo &= "Cust #" & drCust("CustID").ToString() & "" & Chr(10) & ""
' Navigate from customer table to order table.
drsOrder = drCust.GetChildRows(carsDS.Relations("CustomerOrder"))
' Get order number.
For Each r As DataRow In drsOrder
strInfo &= "Order Number: " & r("OrderID").ToString() & "" & Chr(10) & ""
Next
' Now navigate from order table to inventory table.
Dim drsInv As DataRow() = _
drsOrder(0).GetParentRows(carsDS.Relations("InventoryOrder"))
' Get Car info.
For Each r As DataRow In drsInv
strInfo &= "Make: " & r("Make").ToString() & "" & Chr(10) & ""
strInfo &= "Color: " & r("Color").ToString() & "" & Chr(10) & ""
strInfo &= "Pet Name: " & r("PetName").ToString() & "" & Chr(10) & ""
Next
MessageBox.Show(strInfo, "Info based on cust ID")
End Sub
As you can see, the key to moving between data tables is to use a handful of methods defined
by the DataRow type Let’s break this code down step by step First, you obtain the correct customer
ID from the text box and use it to grab the correct row in the Customers table (using the Rows property,
of course) Next, you navigate from the Customers table to the Orders table, using the CustomerOrder
data relation Notice that the DataRow.GetChildRows() method allows you to grab rows from your child
table Once you do, you can read information out of the table
Your final step is to navigate from the Orders table to its parent table (Inventory) using theGetParentRows()method At this point, you can read information from the Inventory table using the
Make, PetName, and Color columns Figure 24-18 shows one possible output
Trang 7Hopefully, this last example has you convinced of the usefulness of the DataSet type Given that
a DataSet is completely disconnected from the underlying data source, you can work with an memory copy of data and navigate around each table to make any necessary updates, deletes, orinserts Once you’ve finished, you can then submit your changes to the data store for processing
in-■ Source Code The MultitabledDataSetApp project is included under the Chapter 24 subdirectory
We’re Off to See the (Data) Wizard
At this point in the chapter, you have seen numerous ways to interact with the types of ADO.NET in
a “wizard-free” manner While it is (most definitely) true that understanding the ins and outs of ing with your data provider is quite important, it is also true that this can lead to hand cramps fromtyping the large amount of boilerplate code To wrap things up, therefore, I’d like to point out a fewdata-centric wizards you may wish to make use of when building Windows Forms applications
work-Be aware that space does not allow me to comment on all of the UI-centric data wizards
pro-vided by Visual Studio 2005, but to illustrate the basics, let’s examine some additional configurationoptions of the DataGridView widget Assume you have created a new Windows Forms application(named EasyDataAccessForm) that has a single Form containing a DataGridView control namedinventoryDataGridView Using the designer, activate the inline editor for this widget, and from theChoose Data Source drop-down listbox, click the Add Project Data Source link (see Figure 24-19).This will launch the Data Source Configuration Wizard On the first step, simply select theDatabase icon and click Next On the second step, click New Connection and establish a connection
to the Cars database (using the same set of steps described earlier in this chapter within the ing to the Cars Database from Visual Studio 2005” section) The third step allows you to inform thewizard to store the connection string within an external app.config file (which is generally a goodidea) within a properly configured <connectionStrings> element As the final step, you are able toselect which database objects you wish to account for within the generated DataSet, which for yourpurposes here will simply be the Inventory table, as shown in Figure 24-20
“Connect-Figure 24-18. Navigating data relations
Trang 8Once you complete the wizard, you will notice that the DataGridView automatically displays thecolumn names within the designer In fact, if you run your application as is, you will find the contents
of the Inventory table displayed within the grid’s UI!
As you might be suspecting, this wizard updated your Form with numerous lines of code;
however, if you examine the code behind the Forms designer, you find little else than the following
implementation of the Form’s Load event:
Figure 24-19. Adding a data source
Figure 24-20. Selecting the Inventory table
Trang 9Public Class MainForm
Private Sub MainForm_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'CarsDataSet.Inventory' table.
'You can move, or remove it, as needed.
Strongly Typed DataSets
Strongly typed DataSets (as the name implies) allow you to interact with a DataSet’s internal tables
using database-specific properties, methods, and events, rather than via the generalized Tablesproperty If you activate the View ➤ Class View menu option of Visual Studio 2005, you will find thatthe wizard has created a new type deriving from DataSet named CarsDataSet As you can see inFigure 24-21, this class type defines a number of members that allow you to select, modify, andupdate its contents
Figure 24-21. The strongly typed DataSet
Once the wizard completes its task, it places a member variable of type CarDataSet within yourForm’s *.Designer.vb file (which is the same member variable manipulated in the Load event ofyour Form):
Partial Class MainForm
Inherits System.Windows.Forms.Form
Friend WithEvents CarsDataSet As EasyDataAccessForm.CarsDataSet
End Class
Trang 10The Autogenerated Data Component
In addition to the strongly typed DataSet, the wizard generated a data component (named
InventoryTableAdapterin this example) that encapsulates the underlying data connection, data
adapter, and command objects used to interact with the Inventory table, as you see in Figure 24-22
Figure 24-22. The autogenerated table adapter data component
As well, this component defines custom Fill() and Update() methods that are tailor-made tooperate on your CarsDataSet, in addition to a set of members used to insert, update, or delete row
data from the internal Inventory table I’ll leave it up to interested readers to dive into the
implemen-tation details of each member The good news is that after all your work in this chapter, the code
behind each member should look quite familiar
■ Source Code The EasyDataAccessForm project is included under the Chapter 24 subdirectory
■ Note If you are interested in taking a deeper look at the ADO.NET object model, including the numerous Visual
Studio 2005 designers, check out Pro ADO.NET 2.0 by Sahil Malik (Apress, 2005)
Summary
ADO.NET is a new data access technology developed with the disconnected n-tier application
firmly in mind The System.Data namespace contains most of the core types you need to
program-matically interact with rows, columns, tables, and views As you have seen, the NET platform ships
with numerous data providers that allow you to leverage the connected and disconnected layers of
ADO.NET
Trang 11Using connection objects, command objects, and data reader objects of the connected layer,you are able to select, update, insert, and delete records As you have seen, command objects support
an internal parameter collection, which can be used to add some type safety to your SQL queriesand is quite helpful when triggering stored procedures
The centerpiece of the disconnected layer is the DataSet This type is an in-memory representation
of any number of tables and any number of optional interrelationships, constraints, and expressions.The beauty of establishing relations on your local tables is that you are able to programmaticallynavigate between them while disconnected from the remote data store
You also examined the role of the data adapter in this chapter Using this type (and the relatedSelectCommand, InsertCommand, UpdateCommand, and DeleteCommand properties), the adapter canresolve changes in the DataSet with the original data store Also, you learned about the connectedlayer of ADO.NET and came to understand the role of data reader types
Trang 12Web Applications and XML Web Services
P A R T 7
■ ■ ■
Trang 14C H A P T E R 2 5
■ ■ ■
Building ASP.NET 2.0 Web Pages
Until now, all of the example applications in this text have focused on console-based and Windows
Forms front ends In the next three chapters, you’ll explore how the NET platform facilitates the
construction of browser-based presentation layers using a technology named ASP.NET To begin, you’ll
quickly review a number of key web-centric concepts (HTTP, HTML, client-side, and server-side script)
and examine the role of the Microsoft’s commercial web server (IIS) as well as the ASP.NET 2.0
devel-opment server, WebDev.WebServer.exe
With this web primer out of the way, the remainder of this chapter concentrates on the structure
of ASP.NET web pages (including the single-page and enhanced code-behind model) as well as the
composition of a Page type This chapter will also define the role of the web.config file, which will be
used throughout the remainder of this text Do be aware that the information presented here will
serve as a foundation for the next two chapters, when we examine web controls, themes, master pages,
and numerous state management techniques
The Role of HTTP
Web applications are very different animals from traditional desktop applications (to say the least)
The first obvious difference is that a production-level web application will always involve at least two
networked machines (of course, during development it is entirely possible to have a single machine
play the role of both client and server) Given this fact, the machines in question must agree upon
a particular wire protocol to determine how to send and receive data The wire protocol that connects
the computers in question is the Hypertext Transfer Protocol (HTTP).
When a client machine launches a web browser (such as Netscape Navigator, Mozilla Firefox, orMicrosoft Internet Explorer), an HTTP request is made to access a particular resource (such as an *.aspx
or *.htm file) on the remote server machine HTTP is a text-based protocol that is built upon a standard
request/response paradigm For example, if you navigate to http://www.IntertechTraining.com, the
browser software leverages a web technology termed Domain Name Service (DNS) that converts the
reg-istered URL into a four-part, 32-bit numerical value, termed an IP address At this point, the browser
opens a socket connection (typically via port 80) and sends the HTTP request for the default page at the
http://www.IntertechTraining.comwebsite, at which point the browser displays the site’s default page
Once the user posts back to the web server, it is then able to process the incoming HTTP requestand may scrape out any client-supplied input values (such as values within a text box) in order to
format a proper HTTP response Web programmers may leverage any number of technologies (CGI,
ASP, ASP.NET, Java servlets, etc.) to dynamically generate the content to be emitted into the HTTP
response At this point, the client-side browser renders the HTML sent from the web server Figure 25-1
illustrates the basic HTTP request/response cycle
Trang 15Another aspect of web development that is markedly different from traditional desktop
program-ming is the fact that HTTP is an essentially stateless wire protocol As soon as the web server emits
a response to the client, everything about the previous interaction is forgotten Therefore, as a webdeveloper, it is up to you take specific steps to “remember” information (such as items in a shoppingcart) about the users who are currently logged on to your site As you will see in Chapter 27, ASP.NETprovides numerous ways to handle state, many of which are commonplace to any web platform (ses-sion variables, cookies, and application variables) as well as some new techniques such as view state,the cache object, and the ASP.NET 2.0 profile management API
Understanding Web Applications and Web Servers
A web application can be understood as a collection of files (*.htm, *.asp, *.aspx, image files, etc.)
and related components (such as a NET code library or legacy COM server) stored within a lar set of directories on a given web server As shown in Chapter 27, ASP.NET web applications have
particu-a specific life cycle particu-and provide numerous events (such particu-as initiparticu-al stparticu-artup or finparticu-al shutdown) thparticu-at youcan hook into to perform specialized processing
A web server is a software product in charge of hosting your web applications, and it typically
provides a number of related services such as integrated security, File Transfer Protocol (FTP) support,mail exchange services, and so forth Internet Information Server (IIS) is Microsoft’s enterprise-levelweb server product, and as you would guess, it has intrinsic support for classic ASP as well as ASP.NETweb applications
When you build ASP.NET web applications, you will often need to interact with IIS Be aware,
however, that IIS is not automatically selected when you install the Windows Server 2003 or Windows
XP Professional Edition Sadly, you can’t install IIS on the Home editions of the Windows operatingsystem, but hang tight! ASP.NET does provide an alternative server for testing and development,which I’ll comment on shortly
Depending on the configuration of your development machine, you may be required to manuallyinstall IIS before proceeding through this chapter To do so, simply access the Add/Remove Programapplet from the Control Panel folder and select Add/Remove Windows Components
■ Note Ideally, your development machine will have IIS installed before you install the NET Framework If youinstall IIS after you install the NET Framework, none of your ASP.NET web applications will execute correctly (youwill simply get back a blank page) Luckily, you can reconfigure IIS to host NET applications by running theaspnet_regiis.execommand-line tool and specifying the /ioption
Figure 25-1. The HTTP request-and-response cycle
Trang 16Assuming you have IIS properly installed on your workstation, you can interact with IIS fromthe Administrative Tools folder (located in the Control Panel folder) by double-clicking the Internet
Information Services applet For the purposes of this chapter, you are concerned only with the
Default Web Site node (see Figure 25-2)
Working with IIS Virtual Directories
A single IIS installation is able to host numerous web applications, each of which resides in a virtual
directory Each virtual directory is mapped to a physical directory on the local hard drive Therefore,
if you create a new virtual directory named CarsRUs, the outside world can navigate to this site
using a URL such as http://www.CarsRUs.com (assuming your site’s IP address has been registered
with the world at large) Under the hood, the virtual directory maps to a physical root directory such
as C:\inetpub\wwwroot\AspNetCarsSite, which contains the content of the web application
When you create ASP.NET web applications using Visual Studio 2005, you have the option ofgenerating a new virtual directory for the current website However, you are also able to manually
create a virtual directory by hand For the sake of illustration, assume you wish to create a simple
web application named Cars The first step is to create a new folder on your machine to hold the
collection of files that constitute this new site (which I will assume during this example is C:\CodeTests\
CarsWebSite)
Next, you need to create a new virtual directory to host the Cars site Simply right-click theDefault Web Site node of IIS and select New ➤ Virtual Directory from the context menu This menu
selection launches an integrated wizard Skip past the welcome screen and give your website a name
(Cars) Next, you are asked to specify the physical folder on your hard drive that contains the various
files and images that represent this site (in this case, C:\CodeTests\CarsWebSite)
The final step of the wizard prompts you for some basic traits about your new virtual directory(such as read/write access to the files it contains, the ability to view these files from a web browser,
the ability to launch executables [e.g., CGI applications], etc.) For this example, the default selections
are just fine (be aware that you can always modify your selections after running this tool using various
right-click-activated Property dialog boxes integrated within IIS) When you are finished, you will
see that your new virtual directory has been registered with IIS (see Figure 25-3)
Figure 25-2. The IIS applet
Trang 17We’ll add some web content to this virtual directory in just a moment; however, before we do,allow me to introduce a new web server, which is the programmer’s alternative to IIS.
The ASP.NET 2.0 Development Server
Prior to NET 2.0, ASP.NET developers were required to make use of IIS virtual directories during thedevelopment and testing of their web content In many cases, this tight dependency to IIS made teamdevelopment more complex than necessary (not to mention that many IT professionals frownedupon installing IIS on every developer’s machine) Thankfully, as of ASP.NET 2.0, we are providedwith a lightweight web server named WebDev.WebServer.exe This utility allows developers to host
an ASP.NET 2.0 web application outside the bounds of IIS Using this tool, you can build and testyour web pages from any directory on your machine (which is quite helpful for team developmentscenarios and for building ASP.NET 2.0 web programs on Windows XP Home Edition, which doesnot support IIS installations)
■ Note WebDev.WebServer.execannot be used to test or host classic (COM-based) ASP web applications Thisweb server can only host ASP.NET web applications and/or NET-based XML web services
When building a website with Visual Studio 2005, you have the option of using WebDev.WebServer.exeto host your pages (as you will see a bit later in this chapter) However, you are alsoable to manually interact with this tool from a NET command prompt If you enter the followingcommand:
WebDev.WebServer.exe -?
you will be presented with a message box that describes the valid command-line options In a nutshell,you will need to specify an unused port (via the /port: option), the root directory of the web appli-cation (via the /path: option), and an optional virtual path using the /vpath: option (if you do notsupply a /vpath: option, the default is simply /) Consider the following usage:
WebDev.WebServer.exe /port:12345 /path:"C:\CodeTests\CarsWebSite"
Once you have entered this command, you can launch your web browser of choice to request pages.Thus, if the CarsWebSite folder had a file named Default.aspx, you could enter the following URL:http://localhost:12345/CarsWebSite/Default.aspx
Figure 25-3. The Cars virtual directory
Trang 18Many of the examples in this chapter and the next will make use of WebDev.WebServer.exe viaVisual Studio 2005, rather than manually constructing a virtual directory under IIS While this approach
can simplify the development of your web application, do be very aware that this web server is not
intended to host production-level web applications It is purely intended for development and
test-ing purposes Once a web application is ready for prime time, your site will need to be copied to an
IIS virtual directory
■ Note As yet another alternative web server, be aware that the Mono project (see Chapter 1) provides a free ASP.NET
plug-in for the Apache web server This makes it possible to build and host ASP.NET web applications on operating
sys-tems other than MS Windows If you are interested, check out http://www.mono-project.com/ASP.NETfor details
The Role of HTML
Now that you have configured a directory to host your web application, and have chosen a web server
to serve as the host, you need to create the content itself Recall that web application is simply the
term given to the set of files that constitute the functionality of the site To be sure, a vast number of
these files will contain syntactic tokens defined by the Hypertext Markup Language (HTML) HTML
is a standard markup language used to describe how literal text, images, external links, and various
HTML-based UI widgets are to be rendered within the client-side browser
This particular aspect of web development is one of the major reasons why many programmersdislike building web-based programs While it is true that modern IDEs (including Visual Studio 2005)
and web development platforms (such as ASP.NET) generate much of the HTML automatically, you
will do well to have a working knowledge of HTML as you work with ASP.NET
While this section will most certainly not cover all aspects of HTML (by any means), let’s checkout some basics and build a simple web application using HTML, classic (COM-based) ASP, and IIS
This will serve as a roadmap for those of you who are coming to ASP.NET from a traditional desktop
application development background
■ Note If you are already comfortable with the overall process of web development, feel free to skip ahead to the
section “Problems with Classic ASP.”
HTML Document Structure
An HTML file consists of a set of tags that describe the look and feel of a given web page As you would
expect, the basic structure of an HTML document tends to remain the same For example, *.htm files
(or, alternatively, *.html files) open and close with <html> and </html> tags, typically define a <body>
section, and so forth Keep in mind that HTML is not case sensitive Therefore, in the eyes of the
host-ing browser, <HTML>, <html>, and <Html> are identical
To illustrate some HTML basics, open Visual Studio 2005, insert an empty HTML file using theFile ➤ New ➤ File menu selection, and save this file under your C:\CodeTests\CarsWebSite directory
as default.htm As you can see, the initial markup is rather uneventful:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
Trang 19</html>
First of all, notice that this HTML file opens with a DOCTYPE processing instruction (at leastwhen you use Visual Studio 2005) This informs the IDE that the contained HTML tags should bevalidated against the XHTML standard As you may know, traditional HTML was very “loose” in itssyntax For example, it was permissible to define an opening element (such as <br>, for a line break)that did not have a corresponding closing break (</br> in this case) The XHTML standard is a W3Cspecification that adds some much needed rigor to the HTML markup language
■ Note By default, Visual Studio 2005 validates all HTML documents against the XHTML 1.0 Transitional validationscheme Simply put, HTML validation schemes are used to ensure the markup is in sync with specific standards Ifyou wish to specify an alternative validation scheme, activate the Tools ➤ Options dialog box, then select theValidation node under HTML If you would rather not see validation errors, simply uncheck the Show Errors checkbox (which I will assume you have done during the remainder of this chapter)
The <html> and </html> tags are used to mark the beginning and end of your document Noticethat the opening <html> tag is further qualified with an xmlns (XML namespace) attribute that quali-fies the various tags that may appear within this document (again, by default these tags are based
on the XHTML standard) Web browsers use these particular tags to understand where to beginapplying the rendering formats specified in the body of the document The <body> scope is wherethe vast majority of the actual content is defined To spruce things up just a bit, update the title ofyour page as follows:
The real meat of an *.htm file occurs within the scope of the <form> elements An HTML form is
simply a named group of related UI elements used to gather user input, which is then transmitted
to the web application via HTTP Do not confuse an HTML form with the entire display area shown
by a given browser In reality, an HTML form is more of a logical grouping of widgets placed in the
<form>and </form> tag set:
Trang 20tag in just a bit For the time being, let’s look at the sorts of items that can be placed in an HTML
form (in addition to simple literal text) Visual Studio 2005 provides an HTML tab on the Toolbox
that allows you to select each HTML-based UI widget, as shown in Figure 25-4
Building an HTML-based User Interface
Before you add the HTML widgets to the HTML <form>, it is worth pointing out that Visual Studio
2005 allows you to edit the overall look and feel of the *.htm file itself using the integrated HTML
designer and the Properties window If you select DOCUMENT from the Properties window, as
shown in Figure 25-5, you are able to configure various aspects of the HTML page, such as the
back-ground color
Figure 25-4. The HTML tab of the Toolbox
Figure 25-5. Editing an HTML document via the VS 2005 Properties window
Trang 21Update the <body> of the default.htm file to display some literal text that prompts the user toenter a user name and password, and choose a background color of your liking (be aware that youcan enter and format textual content by typing directly on the HTML designer):
<! Prompt for user input >
<h1 align="center"> The Cars Login Page</h1>
The UI you will build here will contain two text fields (one of which is a Password widget) andtwo button types (one to submit the form data and the other to reset the form data to the defaultvalues):
<! Build a form to get user info >
<input name="btnSubmit" type="submit" value="Submit" id="btnSubmit">
<input name="btnReset" type="reset" value="Reset" id="btnReset">
</p>
</form>
Notice that you have assigned relevant names and IDs to each widget (txtUserName, txtPassword,btnSubmit, and btnReset) Of greater importance, note that each input item has an extra attributenamed type that marks these buttons as UI items that automatically clear all fields to their initialvalues (type = "reset"), mask the input as a password (type="password"), or send the form data tothe recipient (type = "submit") Figure 25-6 displays the page thus far
Trang 22The Role of Client-side Scripting
In addition to HTML UI elements, a given *.htm file may contain blocks of script code that will be
emitted into the response stream and processed by the requesting browser There are two major
reasons why client-side scripting is used:
• To validate user input before posting back to the web server
• To interact with the Document Object Model (DOM) of the target browserRegarding the first point, understand that the inherent evil of a web application is the need to
make frequent round-trips (termed postbacks) to the server machine to update the HTML rendered
into the browser While postbacks are unavoidable, you should always be mindful of ways to
mini-mize travel across the wire One technique that saves round-trips is to use client-side scripting to
validate user input before submitting the form data to the web server If an error is found (such as
not supplying data within a required field), you can prompt the user of the error without incurring
the cost of posting back to the web server (after all, nothing is more annoying to users than posting
back on a slow connection, only to receive instructions to address input errors!)
In addition to validating user input, client-side scripts can also be used to interact with theunderlying object model (the DOM) of the web browser itself Most commercial browsers expose
a set of objects that can be leveraged to control how the browser should behave One major annoyance
is the fact that different browsers tend to expose similar, but not identical, object models Thus, if
you emit a block of client-side script code that interacts with the DOM, it may not work identically
on all browsers
■ Note ASP.NET provides the HttpRequest.Browserproperty, which allows you to determine at runtime the
capacities of the browser that sent the current request
There are many scripting languages that can be used to author client-side script code Two ofthe more popular are VBScript and JavaScript VBScript is a subset of the Visual Basic 6.0 programminglanguage Be aware that Microsoft Internet Explorer (IE) is the only web browser that has built-in
support for client-side VBScript support (other browsers may or may not provide optional plug-ins)
Thus, if you wish your HTML pages to work correctly in any commercial web browser, do not use
VBScript for your client-side scripting logic
Figure 25-6. The initial crack at the default.htm page
Trang 23The other popular scripting language is JavaScript Be very aware that JavaScript is in no way,shape, or form a subset of the Java language While JavaScript and Java have a somewhat similarsyntax, JavaScript is not a full-fledged OOP language, and thus is far less powerful than Java Thegood news is that all modern-day web browsers support JavaScript, which makes it a natural candi-date for client-side scripting logic.
■ Note To further confuse the issue, recall that JScript NET is a managed language that can be used to buildvalid NET assemblies using a scripting-like syntax
A Client-side Scripting Example
To illustrate the role of client-side scripting, let’s first examine how to intercept events sent fromclient-side HTML GUI widgets Assume you have added an additional HTML button (btnHelp) toyour default.htm page that allows the user to view help information To capture the Click event forthis button, activate the HTML view and select your button from the left drop-down list Using theright drop-down list, select the onclick event This will add an onclick attribute to the definition ofthe new Button type:
<input id="btnHelp" type="button" value="Help" language="javascript"
onclick="return btnHelp_onclick()" />
Visual Studio 2005 will also create an empty JavaScript function that will be called when theuser clicks the button Within this stub, simply make use of the alert() method to display a client-side message box:
<script language="javascript" type="text/javascript">
rea-Validating the default.htm Form Data
Now, let’s update the default.htm page to support some client-side validation logic The goal is toensure that when the user clicks the Submit button, you call a JavaScript function that checks eachtext box for empty values If this is the case, you pop up an alert that instructs the user to enter therequired data First, handle an onclick event for the Submit button:
<input name="btnSubmit" type="submit" value="Submit" id="btnSubmit"
language="javascript" onclick="return btnSubmit_onclick()">
Implement this handler like so:
function btnSubmit_onclick(){
// If they forget either item, pop up a message box
if((defaultPage.txtUserName.value == "") ||
(defaultPage.txtPassword.value == "")){
Trang 24alert("You must supply a user name and password!");
Submitting the Form Data (GET and POST)
Now that you have a simple HTML page, you need to examine how to transmit the form data back
to the web server for processing When you build an HTML form, you typically supply an action
attribute on the opening <form> tag to specify the recipient of the incoming form data Possible
receivers include mail servers, other HTML files, an Active Server Page file, and so forth For this
example, you’ll use a classic ASP file named ClassicAspPage.asp Update your default.htm file by
specifying the following attribute in the opening <form> tag:
<form name="defaultPage" id="defaultPage"
action="http://localhost/Cars/ClassicAspPage.asp" method = "GET">
</form>
These extra attributes ensure that when the Submit button for this form is clicked, the formdata will be sent to the ClassicAspPage.asp at the specified URL When you specify method = "GET"
as the mode of transmission, the form data is appended to the query string as a set of name/value
pairs separated by ampersands:
http://localhost/Cars/ClassicAspPage.asp?txtUserName=
Andrew&txtPassword=Foo$&btnSubmit=Submit
The other method of transmitting form data to the web server is to specify method = "POST":
<form name="defaultPage" id="defaultPage"
action="http://localhost/Cars/ClassicAspPage.asp" method = "POST">
</form>
In this case, the form data is not appended to the query string, but instead is written to a rate line within the HTTP header Using POST, the form data is not directly visible to the outside
sepa-world More important, POST data does not have a character-length limitation (many browsers
have a limit for GET queries) For the time being, make use of HTTP GET to send the form data to
the receiving *.asp page
Building a Classic ASP Page
A classic ASP page is a hodgepodge of HTML and server-side script code If you have never worked
with classic ASP, understand that the goal of ASP is to dynamically build HTML on the fly using
server-side script and a small set of COM objects For example, you may have a server-side VBScript
(or JavaScript) block that reads a table from a data source using classic ADO and returns the rows as
a generic HTML table
Trang 25For this example, the ASP page uses the intrinsic ASP Request COM object to read the values ofthe incoming form data (appended to the query string) and echo them back to the caller (not terri-bly exciting, but it illustrates the point of the request/response cycle) The server-side script logic willmake use of VBScript (as denoted by the language directive).
To do so, create a new HTML file using Visual Studio 2005 and save this file under the nameClassicAspPage.aspinto the folder to which your virtual directory has been mapped (e.g., C:\CodeTests\CarsWebSite) Implement this page as follows:
<h1 align="center">Here is what you sent me:</h1>
<P align="center"> <b>User Name: </b>
a shorthand way of saying, “Insert the following directly into the outbound HTTP response.” To gain
a finer level of flexibility, you could interact with the ASP Response COM object within a full side script block (denoted by the <%, %> notation) You have no need to do so here; however, thefollowing is a simple example:
■ Note Under ASP.NET, these COM objects are officially dead However, you will see that the System.Web.UI.Pagebase class defines identically named properties that expose objects with similar functionality
To test the ASP logic, simply load the default.htm page from a browser and submit the formdata Once the script is processed on the web server, you are returned a brand new (dynamicallygenerated) HTML display, as you see in Figure 25-7
Trang 26Responding to POST Submissions
Currently, your default.htm file specifies HTTP GET as the method of sending the form data to the
target *.asp file Using this approach, the values contained in the various GUI widgets are appended
to the end of the query string It is important to note that the ASP Request.QueryString() method is
only able to extract data submitted via the GET method.
If you would rather submit form data to the web resource using HTTP POST, you can use theRequest.Formcollection to read the values on the server, for example:
we check out how the ASP.NET web platform improves upon the current state of affairs, let’s take
a brief moment to critique classic ASP and understand its core limitations
■ Source Code The ClassicAspCars example is included under the Chapter 25 subdirectory
Problems with Classic ASP
While many successful websites have been created using classic ASP, this architecture is not without
its downsides Perhaps the biggest downfall of classic ASP is the same thing that makes it a powerful
platform: server-side scripting languages Scripting languages such as VBScript and JavaScript are
interpreted, typeless entities that do not lend themselves to robust OO programming techniques
Another problem with classic ASP is the fact that an *.asp page does not yield very modularized
code Given that ASP is a blend of HTML and script in a single page, most ASP web applications are
Figure 25-7. The dynamically generated HTML
Trang 27a confused mix of two very different programming techniques While it is true that classic ASP allowsyou to partition reusable code into distinct include files, the underlying object model does not sup-port true separation of concerns In an ideal world, a web framework would allow the presentationlogic (i.e., HTML tags) to exist independently from the business logic (i.e., functional code).
A final issue to consider here is the fact that classic ASP demands a good deal of boilerplate,redundant script code that tends to repeat between projects Almost all web applications need tovalidate user input, repopulate the state of HTML widgets before emitting the HTTP response, gen-erate an HTML table of data, and so forth
Major Benefits of ASP.NET 1.x
The first major release of ASP.NET (version 1.x ) did a fantastic job of addressing each of the
limita-tions found with classic ASP In a nutshell, the NET platform brought about the following
techniques to the web paradigm:
• ASP.NET 1.x provides a model termed code-behind, which allows you to separate presentation
logic from business logic
• ASP.NET 1.x pages are coded using NET programming languages, rather than interpreted
scripting languages The code files are compiled into valid NET assemblies (which translatesinto much faster execution)
• Web controls allow programmers to build the GUI of a web application in a manner similar
to building a Windows Forms application
• ASP.NET web controls automatically maintain their state during postbacks using a hiddenform field named VIEWSTATE
• ASP.NET web applications are completely object-oriented and make use of the CommonType System (CTS)
• ASP.NET web applications can be easily configured using standard IIS settings or using a web
application configuration file (web.config)
While ASP.NET 1.x was a major step in the right direction, ASP.NET 2.0 provides even more bells and whistles The good news is that (just about) everything you may already know about ASP.NET 1.x still applies to ASP.NET 2.0 In fact, it is perfectly fine to have a single IIS installation host NET 1.x and
.NET 2.0–based web content
Major Enhancements of ASP.NET 2.0
ASP.NET 2.0 provides a number of new namespaces, types, utilities, and technologies to the NETweb development landscape Consider this partial list:
• As you have seen, ASP.NET 2.0 no longer requires websites to be hosted under IIS during thetesting and development of your site You are now able to host your site from any directory
on the hard drive using the WebDev.WebServer.exe utility
• ASP.NET 2.0 ships with a large number of new web controls (navigation controls, security
controls, new data controls, new UI controls, etc.) that complement the existing ASP.NET 1.x
control set
• ASP.NET 2.0 supports the use of master pages, which allow you to attach a common UI frame
to a set of related pages
Trang 28• ASP.NET 2.0 supports themes, which offer a declarative manner to change the look and feel
of the entire web application
• ASP.NET 2.0 supports web parts, which can be used to allow end users to customize the look
and feel of a web page
• ASP.NET 2.0 supports a web-based configuration and management utility that maintainsyour web.config files
Given that this book is not focused exclusively on web development, be sure to consult the.NET Framework 2.0 documentation for details of topics not covered here The truth of the matter is
that if I were to truly do justice to every aspect of ASP.NET 2.0, this book would easily double in size
Rest assured that by the time you complete this text, you will have a solid ASP.NET foundation to
build upon
The ASP.NET 2.0 Namespaces
As of NET 2.0, there are no fewer than 34 web-centric namespaces in the base class libraries From
a high level, these namespaces can be grouped into four major categories:
• Core functionality (e.g., types that allow you to interact with the HTTP request and response,Web Form infrastructure, theme and profiling support, web parts, security, etc.)
• Web Form and HTML controls
• Mobile web development
• XML web servicesThis text will not examine the topic of mobile NET development (web-based or otherwise);
however, the role of XML web services will be examined in Chapter 28 Table 25-1 describes several
of the core ASP.NET 2.0 namespaces
Table 25-1. The Core ASP.NET Web-centric Namespaces
Namespaces Meaning in Life
System.Web Defines types that enable browser/web server communication
(such as request and response capabilities, cookie manipulation,and file transfer)
System.Web.Caching Defines types that facilitate caching support for a web application
System.Web.Hosting Defines types that allow you to build custom hosts for the ASP.NET
runtimeSystem.Web.Management Defines types for managing and monitoring the health of an
ASP.NET web applicationSystem.Web.Profile Defines types that are used to implement ASP.NET user profiles
System.Web.Security Defines types that allow you to programmatically secure your site
System.Web.SessionState Defines types that allow you to maintain stateful information on
a per-user basis (e.g., session state variables)System.Web.UI Define a number of types that allow you to build a GUI front end for System.Web.UI.WebControls your web application
System.Web.UI.HtmlControls
Trang 29The ASP.NET Web Page Code Model
ASP.NET web pages can be constructed using one of two approaches You are free to create a single
*.aspxfile that contains a blend of server-side code and HTML (much like classic ASP) Using the
single-file page model, server-side code is placed within a <script> scope, but the code itself is not
script code proper (e.g., VBScript/JavaScript) Rather, the code statements within a <script> blockare written in your NET language of choice (VB 2005, C#, etc.)
If you are building a page that contains very little code (but a good deal of HTML), a single-filepage model may be easier to work with, as you can see the code and the markup in one unified
*.aspxfile In addition, crunching your code and HTML into a single *.aspx file provides a fewother advantages:
• Pages written using the single-file model are slightly easier to deploy or to send to anotherdeveloper
• Because there is no dependency between files, a single-file page is easier to rename
• Managing files in a source code control system is slightly easier, as all the action is takingplace in a single file
The default approach taken by Visual Studio 2005 (when creating a new website solution) is tomake use of a technique known as code-behind, which allows you to separate your programmingcode from your HTML presentation logic using two distinct files This model works quite well whenyour pages contain significant amounts of code or when multiple developers are working on thesame website The code-behind model offers several benefits as well:
• Because code-behind pages offer a clean separation of HTML markup and code, it is ble to have designers working on the markup while programmers author the VB 2005 code
possi-• Code is not exposed to page designers or others who are working only with the page markup(as you might guess, HTML folks are not always interested in viewing reams of VB 2005 code)
• Code files can be used across multiple *.aspx files
Regardless of which approach you take, do know that there is no difference in terms of
per-formance Also be aware that the single-file *.aspx model is no longer frowned upon as it was under
.NET 1.x In fact, many ASP.NET 2.0 web applications will benefit by building sites that make use of
both approaches
Working with the Single-file Page Model
First up, let’s examine the single-file page model Our goal is to build an *.aspx file (namedDefault.aspx) that displays the Inventory table of the Cars database (created in Chapter 24) Whileyou could build this page using nothing but Notepad, Visual Studio 2005 can simplify matters viaIntelliSense, code completion, and a visual page designer To begin, open Visual Studio 2005 andcreate a new Web Form using the File ➤ New ➤ File menu option (see Figure 25-8)
Trang 30Once the page loads into the IDE, notice that the bottom area of the page designer allows you
to view the *.aspx file in two distinct manners If you select the Design button, you are shown a visual
designer surface that allows you to build the UI of your page much like you would build a Windows
Form (drag widgets to the surface, configure them via the Properties window, etc.) If you select the
Source button, you can view the HTML and <script> blocks that compose the *.aspx file itself
■ Note Unlike earlier versions of Visual Studio, the Source view of Visual Studio 2005 has full-blown IntelliSense
support for *.aspxfiles, and allows you to drag and drop UI elements directly from the Toolbox into the HTML
document!
Using the Visual Studio 2005 Toolbox, select the Standard tab and drag and drop a Button, Label,and GridView control onto the page designer (the GridView widget can be found under the Data tab
of the Toolbox) Feel free to make use of the Properties window (or the HTML IntelliSense) to set
vari-ous UI properties and give each web widget a proper name via the ID property Figure 25-9 shows
one possible design (I kept my look and feel intentionally bland to minimize the amount of generated
control markup, but feel free to use the Properties window to spruce things up to your liking)
Figure 25-8. Creating a new *.aspx file
Trang 31Now, click the Source button at the bottom of your code window and locate the <form> section
of your page Notice how each web control has been defined using an <asp:> tag Before the closing tag,you will find a series of name/value pairs that correspond to the settings you made in the Propertieswindow:
<form id="form1" runat="server">
<div>
<asp:Label ID="lblInfo" runat="server"
Text="Click on the Button to Fill the Grid">
To illustrate, handle the Click event for the Button type using either the Visual Studio Propertieswindow (via the lightning-bolt icon) or using the drop-down boxes mounted at the top of the Sourceview window Once you do, you will find your Button’s definition has been updated with an OnClickattribute that is assigned to the name of your Click event handler:
<asp:Button ID="btnFillData" runat="server"
Text="Fill Grid" OnClick="btnFillData_Click" />
Figure 25-9. The Default.aspx UI
Trang 32As well, your <script> block has been updated with a server-side Click event handler (notice thatthe incoming parameters are a dead-on match for the target of the System.EventHandler delegate):
Protected Sub btnFillData_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim sqlConn As New SqlConnection("Data Source=.;Initial Catalog=Cars;UID=sa;PWD=")
WebDev.WebServer.exemanually, open a NET command prompt and run the WebDev.WebServer.exe
utility, making sure you specify the path where you saved your Default.aspx file, for example:
webdev.webserver.exe /port:12345 /path:"C:\CodeTests\SinglePageModel"
Now, using your browser of choice, enter the following URL:
http://localhost:12345/
When the page is served, you will initially see your Label and Button types However, when youclick the button, a postback occurs to the web server, at which point the web controls render back
their corresponding HTML tags
As a shortcut, you can indirectly launch WebDev.WebServer.exe from Visual Studio 2005 Simplyright-click the page you wish to browse and select the View In Browser menu option In either case,
Figure 25-10 shows the output
Trang 33That was simple, yes? Of course, as they say, the devil is in the details, so let’s dig a bit deeper
into the composition of this *.aspx file, beginning by examining the role of the page directive.
The <%@Page%> Directive
The first thing to be aware of is that a given *.aspx file will typically open with a set of directives.ASP.NET directives are always denoted with <%@ XXX %> markers and may be qualified with variousattributes to inform the ASP.NET runtime how to process the attribute in question
Every *.aspx file must have at minimum a <%@Page%> directive that is used to define the managedlanguage used within the page (via the language attribute) Also, the <%@Page%> directive may definethe name of the related code-behind file (if any), enable tracing support, and so forth Table 25-2 doc-uments some of the more interesting <%@Page%>-centric attributes
Table 25-2. Select Attributes of the <%@Page%> Directive
Attribute Meaning in Life
CompilerOptions Allows you to define any command-line flags (represented as a single string)
passed into the compiler when this page is processedCodePage Specifies the name of the related code-behind file
EnableTheming Establishes whether the controls on the *.aspx page support ASP.NET 2.0
themesEnableViewState Indicates whether view state is maintained across page requests (more
details on this property in Chapter 27)Inherits Defines a class in the code-behind page the *.aspx file derives from, which
can be any class derived from System.Web.UI.PageMasterPageFile Sets the master page used in conjunction with the current *.aspx pageTrace Indicates whether tracing is enabled
Figure 25-10. Web-based data access
Trang 34The <%Import%> Directive
In addition to the <%@Page%> directive, a given *.aspx file may specify various <%@Import%> directives
to explicitly state the namespaces required by the current page Here, you specified you were
mak-ing use of the types within the System.Data.SqlClient namespace As you would guess, if you need
to make use of additional NET namespaces, you simply specify multiple <%@Import%> directives
■ Note The <%@Import%>directive is not necessary if you are making use of the code-behind page model
described next When you do make use of code-behind, you will specify external namespaces using the VB 2005
Importskeyword
Given your current knowledge of NET, you may wonder how this *.aspx file avoided specifyingthe System namespace in order to gain access to the System.Object and System.EventHandler types
(among others) The reason is that all *.aspx pages automatically have access to a set of key
name-spaces that are defined within the machine.config file under your installation path of the NET 2.0
platform Within this XML-based file you would find the following auto-imported namespaces:
model, the VB 2005 Imports keyword (as you have been doing throughout this text)
To be sure, ASP.NET does define a number of other directives that may appear in an *.aspx fileabove and beyond <%@Page%> and <%@Import%>; however, I’ll reserve commenting on those for the
time being
Trang 35The “Script” Block
Under the single-file page model, an *.aspx file may contain server-side scripting logic that executes
on the web server Given this, it is critical that all of your server-side code blocks are defined to execute
at the server, using the runat="server" attribute If the runat="server" attribute is not supplied, the
runtime assumes you have authored a block of client-side script to be emitted into the outgoing
examina-a System.Object examina-as the first pexamina-arexamina-ameter examina-and examina-a System.EventArgs examina-as the second
The ASP.NET Widget Declarations
The final point of interest is the declaration of the Button, Label, and GridView Web Form controls Likeclassic ASP and raw HTML, ASP.NET web widgets are scoped within <form> elements This time, how-ever, the opening <form> element is marked with the runat="server" attribute This again is critical,
as this tag informs the ASP.NET runtime that before the HTML is emitted into the response stream,the contained ASP.NET widgets have a chance to render their HTML appearance:
<form id="form1" runat="server">
</form>
ASP.NET web controls are declared with <asp> and </asp> tags, and they are also marked withthe runat="server" attribute Within the opening tag, you will specify the name of the Web Formcontrol and any number of name/value pairs that will be used at runtime to render the correct HTML
■ Source Code The SinglePageModel example is included under the Chapter 25 subdirectory
Working with the Code-behind Page Model
To illustrate the code-behind page model, let’s re-create the previous example using the Visual Studio
2005 Web Site template (Do know that Visual Studio 2005 is not required to build pages using behind; however, this is the out-of-the-box behavior for new websites.) Activate the File ➤ New ➤ WebSite menu option, and select the ASP.NET Web Site template, as shown in Figure 25-11
Trang 36code-Notice in Figure 25-11 that you are able to select the location of your new site If you selectFile System, your content files will be placed within a local directory and pages will be served via
WebDev.WebServer.exe If you select FTP or HTTP, your site will be hosted within a virtual directory
maintained by IIS For this example, it makes no difference which option you select, but for
simplic-ity I’d suggest the File System option
■ Note When you wish to open an existing website into Visual Studio 2005, select the File ➤ Open ➤ Web Site
menu option and select the folder (or IIS virtual directory) containing the web content
Once again, make use of the designer to build a UI consisting of a Label, Button, and GridView,and make use of the Properties window to build a UI of your liking Now, click the Source button at
the bottom of your code window, and you will see the expected <asp> and </asp> tags Also note that
the <%@Page%> directive has been updated with a few new attributes:
<%@ Page Language="VB" AutoEventWireup="true"
CodeFile="Default.aspx.vb" Inherits="_Default" %>
The CodeFile attribute is used to specify the related external file that contains this page’s ing logic By default, these code-behind files are named by suffixing vb to the name of the *.aspx
cod-file (Default.aspx.vb in this example) If you examine the Solution Explorer, you will see this
code-behind file is visible via a subnode on the Web Form icon (see Figure 25-12)
Figure 25-11. The Visual Studio 2005 ASP.NET Web Site template
Trang 37■ Note The ASP.NET 1.xCodebehindattribute is no longer supported within the <%@Page%>directive! However,the good news is that if you were to open an ASP.NET 1.x*.slnfile using Visual Studio 2005, the IDE will auto-matically convert your project to the ASP.NET 2.0 format and change all Codebehindattributes to CodeFile Aswell, this conversion tool will prompt you to preserve a copy of the original web application.
If you were to open your code-behind file, you would find a partial class deriving fromSystem.Web.UI.Page Notice that the name of this class (Default) is identical to the Inherits attributewithin the <%@Page%> directive:
Partial Class _Default
Inherits System.Web.UI.Page
End Class
Handle the Click event for the Button type (again, just like you would for a Windows Formsapplication) As before, the Button definition has been updated with an OnClick attribute However,the server-side event handler is no longer placed within a <script> scope of the *.aspx file, but as
a method of the _Default class type To complete this example, add an Imports statement forSystem.Data.SqlClientinside your code-behind file and implement the handler using the previousADO.NET logic:
Imports System.Data.SqlClient
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub btnFillGrid_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles btnFillGrid.ClickDim sqlConn As New _
SqlConnection("Data Source=.;Initial Catalog=Cars;UID=sa;PWD=")sqlConn.Open()
Dim cmd As New SqlCommand("Select * From Inventory", sqlConn)
Trang 38If you selected the File System option, WebDev.WebServer.exe starts up automatically when yourun your web application (if you selected IIS, this obviously does not occur) In either case, the
default browser should now display the page’s content
Debugging and Tracing ASP.NET Pages
By and large, when you are building ASP.NET web projects, you can use the same debugging techniques
as you would with any other sort of Visual Studio 2005 project type Thus, you can set breakpoints in
your code-behind file (as well as embedded “script” blocks in an *.aspx file), start a debug session
(the F5 key; by default), and step through your code
However, to debug your ASP.NET web applications, your site must contain a properly ured web.config file The conclusion of this chapter will examine various details behind web.config
config-files, but in a nutshell these XML files provide the same general purpose as an executable assembly’sapp.configfile By default, all Visual Studio 2005 web applications created with the Visual Basic 2005
programming language will automatically have a web.config file However, debugging support is
initially disabled (as this will degrade performance) When you start a debugging session, the IDE
will prompt you for permissions to enable debugging Once you have opted to do so, the
<compilation>element of the web.config file is updated like so:
<compilation debug="true" strict="false" explicit="true"/>
On a related note, you are also able to enable tracing support for an *.aspx file by setting the
Traceattribute to true within the <%@Page%> directive (it is also possible to enable tracing for your
entire site by modifying the web.config file):
<%@ Page Language="VB" AutoEventWireup="true"
CodeFile="Default.aspx.vb" Inherits="_Default" Trace="true" %>
Once you do, the emitted HTML now contains numerous details regarding the previous HTTPrequest/response (server variables, session and application variables, request/response, etc.) To insert
your own trace messages into the mix, you can use the Trace property of the System.Web.UI.Page type
Any time you wish to log a custom message (from a script block or VB 2005 source code file), simply call
the Write() method:
Protected Sub btnFillGrid_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles btnFillGrid.Click
' Emit a custom trace message.
Trace.Write("My Category", "Filling the grid!")
Trang 39■ Source Code The CodeBehindPageModel example is included under the Chapter 25 subdirectory.
Details of an ASP.NET Website Directory Structure
If you have created web applications using ASP.NET 1.x, you may be quite surprised to see that some
familiar files (such as Global.asax) are not included when creating a new website Furthermore, theWeb Site template contains a folder named App_Data and does not appear to have References folderwithin Solution Explorer
First of all, do know that *.asax files are most certainly supported under ASP.NET 2.0, but youwill need to explicitly add them to your project using the Web Site ➤ Add New Item menu option.Chapter 27 will examine the role of Global.asax, so don’t sweat the details for now Next, be aware
Figure 25-13. Logging custom trace messages
Trang 40that your websites are still able to add references to any number of external NET assemblies via
the Web Site ➤ Add Reference menu option (the end result is a bit different, however, as you will
soon see)
Another significant difference is that under Visual Studio 2005, websites may contain anynumber of specifically named subdirectories, each of which has a special meaning to the ASP.NET
runtime Table 25-3 documents these “special subdirectories.”
Table 25-3. Special ASP.NET 2.0 Subdirectories
Subfolder Meaning in Life
App_Browsers Folder for browser definition files that are used to identify individual
browsers and determine their capabilities
App_Code Folder for source code for components or classes that you want to
compile as part of your application ASP.NET compiles the code in thisfolder when pages are requested Code in the App_Code folder isautomatically accessible by your application
App_Data Folder for storing Access *.mdb files, SQL Express *.mdf files, XML files, or
other data stores
App_GlobalResources Folder for *.resx files that are accessed programmatically from
application code
App_LocalResources Folder for *.resx files that are bound to a specific page
App_Themes Folder that contains a collection of files that define the appearance of
ASP.NET web pages and controls
App_WebReferences Folder for proxy classes, schemas, and other files associated with using
a web service in your application
Bin Folder for compiled private assemblies (*.dll files) Assemblies in the
Bin folder are automatically referenced by your application
If you are interested in adding any of these known subfolders to your current web application,you may do so explicitly using the Web Site ➤ Add Folder menu option However, in many cases, the
IDE will automatically do so as you “naturally” insert related files into your site (e.g., inserting a new
VB 2005 class file into your project will automatically add an App_Code folder to your directory
structure if one does not currently exist)
Assembly References and the Bin Folder
As described in a few pages, ASP.NET web pages are eventually compiled into a NET assembly Given
this, it should come as no surprise that your websites can reference any number of private or shared
assemblies Under ASP.NET 2.0, the manner in which your site’s externally required assemblies are
recorded is quite different from ASP.NET 1.x The reason for this fundamental shift is that Visual Studio
2005 now treats websites in a projectless manner.
Although the Web Site template does generate a *.sln file to load your *.aspx files into the IDE,
there is no longer a related *.vbproj file As you may know, ASP.NET 1.x Web Application projects
recorded all external assemblies within *.vbproj This fact brings up the obvious question, Where
are the external assemblies recorded under ASP.NET 2.0?
When you reference a private assembly, Visual Studio 2005 will automatically create a Bindirectory within your directory structure to store a local copy of the binary When your code base
makes use of types within these code libraries, they are automatically loaded on demand By way of
a simple test, if you activate the Web Site ➤ Add Reference menu option and select any of the
previ-ous (non–strongly named) *.dlls you created over the course of this text, you will find a Bin folder
is displayed within Solution Explorer, as shown in Figure 25-14