In this chapter, you’ll learn how to do the following: ◆ Use SQL to query DataSets ◆ Add calculated columns to DataTables ◆ Compute aggregates over sets of rows Working with SQL Expressi
Trang 1Chapter 24
Advanced DataSet Operations
As you know very well by now, DataSets are miniature databases that reside in the client
computer’s memory They’re made up of tables related to one another, they enforce relations,
and they’re practically as close to a client-side database as you can get without installing an actual
database management system at every client However, you can’t execute SQL statements directly
against the DataSet’s data You can’t update a DataTable by issuing an UPDATE statement, and
can’t add rows with an INSERT statement You know how to iterate through the rows of a
Data-Table and how to locate its related rows in other tables, and how to select rows from a DataData-Table
with the Select method You can iterate through the rows of a table, locate the ones that meet
certain criteria, and process their columns in any way you wish: calculate aggregates on selected
columns, update rows in other tables based on the values of certain columns, format text columns,
even create new columns and set their values And, of course, you know how to edit, add and
delete rows, and submit the DataSet to the server
You can also process the data in the DataSet at the client with LINQ Besides LINQ to SQL,
which was discussed briefly in Chapter 17, ‘‘Querying Collections and XML with LINQ,’’ there’s
another component, the LINQ to DataSet component, which enables you to query the DataSet’s
data In this chapter, I’ll focus on more-traditional querying techniques
In this chapter, you’ll learn how to do the following:
◆ Use SQL to query DataSets
◆ Add calculated columns to DataTables
◆ Compute aggregates over sets of rows
Working with SQL Expressions
Let’s consider a DataSet that contains the Orders and Order Details tables of the Northwind
database In Chapter 22, ‘‘Programming with ADO.NET,’’ you saw how to populate a DataSet
with data from one or more database tables, how to iterate through a table’s rows, and how
to traverse the related rows In this chapter, you’ll look at some more-advanced features, such
as adding custom columns to the DataSet’s DataTables and filtering a DataTable’s rows with
SQL-like expressions
You can add a new column to the Order Details DataTable of the DataSet (and not the actual
table in the database) and use this column to store each line’s total You can calculate the line’s
total by multiplying the quantity by the price and then subtracting the discount Similarly, you
can add a column to the Orders DataTable and store the order’s total there To calculate an
order’s total, you can sum the line totals in the Order Details DataTable over all the rows that
Trang 2belong to the specific order Writing VB code to accomplish these tasks is almost trivial; thesimplest approach is to write a loop that iterates through a DataTable’s rows and calculatesthe aggregate This approach, however, is neither the most elegant nor the most efficient A betterapproach is to use SQL expressions to define calculated columns, as well as use SQL expressions toselect rows.
Do we really need all this functionality at the client? We can certainly write code to retrieve therows needed at any time from the database A connected application should request data fromthe database as needed If you’re writing a disconnected or eventually connected application, youshould be able to load a DataSet with the data you’re interested in and process it at the client Evenconnected applications may benefit from the richness of the DataSet
Selecting Rows
The Select method of the DataTable object allows you to select the rows that meet certaincriteria The criteria are expressed with statements similar to the WHERE clause of a SELECTstatement There are several overloaded versions of the Select method The simplest form of themethod accepts no arguments at all and returns all the rows in the DataTable to which it’s applied
Another form accepts a string argument, which is a filter expression equivalent to the WHERE clause
of the SELECT statement, and returns the rows that match the specified criteria Another form ofthe Select method accepts the filter expression and a second string argument that determinesthe order in which the rows will be returned The last overloaded form of the method accepts thesame two arguments and a third one that determines the state of the rows you want to retrieve:
DataTable.Select(filter, ordering, DataRowState)
The Select method returns an array of DataRow objects, which are not linked to the originalrows In other words, if you edit one of the rows in the array returned by the Select method,the matching row in the DataTable will not be modified Even if the DataSet is strongly typed,the Select method returns an array of generic DataRow objects, not an array of the same type
as the rows of the DataTable to which the Select method was applied The following statementsretrieve the ‘‘expensive’’ products from the Products DataTable:
Dim expensive() As DataRow
expensive = DS.Products.Select(”UnitPrice > 100”)
After the execution of the Select method, the expensive array will hold the rows whose
UnitPricefield is more than $100 You can also combine multiple filter expressions with theusual Boolean operators To retrieve the expensive product with a stock over three units, usethe following filter expression:
”UnitPrice > 100 AND UnitsInStock > 3”
Assuming that the Orders DataTable holds the rows of the Orders table, you can retrieve theheaders of the orders placed in the first three months of 1998 via the following statements:
Dim Q1 1998() As DataRowQ1 1998 = DS.Orders.Select(
”OrderDate >= ’1/1/1998’ AND OrderDate <= ’3/31/1998’”)
Trang 3SIMPLE CALCULATED COLUMNS 887
If you want the rows sorted by shipment date, add an argument indicating the name of the
column on which the columns will be sorted and the ASC or DESC keyword:
DS.Orders.Select(
”OrderDate >= ’1/1/1998’ AND OrderDate <= ’3/31/1998’”,
”DateShipped DESC”)
You can select the rows that have been added to the DataSet by specifying the third argument
to the Select method and two empty strings in place of the first two arguments:
Dim newRows() As DataRow
newRows = DS.Orders.Select(””,””, DataRowState.Added)
Simple Calculated Columns
Sometimes you’ll need to update a column’s value based on the values of other columns For
example, you may wish to maintain a column in the Orders DataTable that has the order’s total
For this column to be meaningful, its value should be updated every time a related row in the
Order Details DataTable is modified In the actual database, you’d do this with a trigger However,
we want to avoid adding too many triggers to our tables because they slow all data-access
oper-ations, not to mention that you’ll be duplicating information If a trigger fails to execute, the line
total may not agree with the actual fields of the same row One of the most basic rules in database
design is to never duplicate information in the database Because duplication of information
some-times helps programmers in retrieving totals from the database quickly, many developers chose
to break this rule and maintain totals, even though the totals can be calculated from row data
To maintain totals in a DataSet, you can add calculated columns to its DataTables You specify
a formula for the calculated column, and every time one of the columns involved in the formula
changes, the calculated column’s value changes accordingly Note that calculated columns may
involve columns in the same table, or aggregates that involve columns in related tables As you
will see, calculated columns can simplify many complex reporting applications
To add a new DataColumn object to a DataTable, use the Add method of the table’s Columns
collection The Columns property of the DataTable object is a collection, and you can create new
columns to the table by adding the DataColumn object to this collection One of the overloaded
forms of this method allows you to specify not only the column’s name and data type, but also its
contents The following statement adds the LineTotal column to the Order Details table and sets
its value to the specified expression:
DS.Tables[”Order Details”].Columns.Add(
”LineTotal”, System.Type.GetType(”System.Decimal”),
”(UnitPrice * Quantity) * (1 - Discount)”)
The last argument of the Add method is an expression, which calculates the detail line’s
extended price This expression isn’t calculated when the DataSet is loaded; it’s calculated on-the-fly,
every time the column is requested You can change the values of the columns involved in the
expression at will, and every time you request the value of the LineTotal column, you’ll get
back the correct value You should notice that order and invoice data isn’t changed after it’s been
recorded In other words, you shouldn’t edit the contents of an order, or an invoice, after the
Trang 4receipt has been printed Because order data is static, you can include the line total in your querywith a statement like the following:
SELECT [Order Details].*,UnitPrice * Quantity * (1 - Discount) AS LineTotalFROM [Order Details]
The LineTotal column won’t change after it’s been read, even if you change the row’s
quan-tity, price, or discount If the application is going to use the DataSet for browsing only, youcan populate it with the preceding SQL statement But what if you want to run some ‘‘what if’’
scenarios? For example, you may allow users to edit the discount for selected customers and seehow it affects profit In this case, reading the line’s total from the database isn’t going to do you
any good, unless you want to update the LineTotal column from within your code If you add
the same column as a calculated column to the Order Details table, you can freely edit discounts
and the LineTotal column will be always up-to-date.
The LineTotal calculated column is as simple as it can get because it involves the values of a
few other columns in the same row Another trivial example is the concatenation of two or morecolumns, as in the following example:
DS.Employees.Columns.Add(”EmployeeName”,System.Type.GetType(”System.String”),
”LastName + ’ ’ + FirstName”)
You can also use functions in the calculated column expressions The following calculated
column has the value Out of Stock if the AvailableQuantity column is 0 or negative, and the
value Immediate Availability if the same column is positive:
Ds.Tables[”Stock”].Columns.Add(”Availability”,System.Type.GetType(”System.String”),
”IIF(AvailableQuantity > 0, ” &
”’Immediate Availability’, ’Out of Stock’)
You can use any of the functions of T-SQL in your calculated column (string functions, dateand time functions, math functions, and so on) You can also combine multiple conditions withthe AND, OR, and NOT operators Finally, you can use the IN and LIKE operators for advancedcomparisons
By the way, the calculated column we just added to our DataSet doesn’t violate any databasedesign rules, because the extra column lives in the DataSet and is used primarily for browsingpurposes We haven’t touched the database
Calculated Columns with Aggregates
In addition to the simple calculated columns you explored in the preceding section, you can createcalculated columns based on the values of multiple related rows An aggregate column based onthe values of related columns in other tables uses a slightly different syntax To use aggregates,you must learn two new functions: Child() and Parent() They both accept a relation name as anargument and retrieve the child rows or the parent row, respectively, of the current row, according
to the specified relation
Trang 5SIMPLE CALCULATED COLUMNS 889
Let’s consider again a DataSet with the Orders and Order Details tables The function Child
(Orders Order Details)returns the rows of the Order Details table that belong to the current row
of the Orders table: the child rows of the current order under the Orders Order Details relation
Likewise, the function Parent(Orders Order Details) returns the row of the Orders table, to
which the current Order Details row belongs The Child() function can be applied to the rows of
the parent table in a relation, and the Parent() function can be applied to the rows of the child table
If the table to which either function applies has a single relation to another table, you can omit the
relation’s name If the DataSet contains only the Orders and Order Details tables, you can use the
functions Child and Parent to refer the current row’s child and parent row(s) without specifying
the name of the relation
To add the Items calculated column to the Orders table and store the total number of items in
the order to this column, use the following statement:
SUM(child(Orders Order Details).Quantity))
The last statement is longer but easier to read, and the same code will work even after you
add new relations to the Orders table The Items calculated column is based on an aggregate over
selected rows in another table and it can simplify reporting applications that need to display totals
along with each order You can use a similar but slightly more complicated expression to calculate
the total of each order:
DS.Orders.Columns.Add(”OrderTotal”,
System.Type.GetType(”System.Decimal”),
SUM(child(Orders Order Details).UnitPrice *
child(Orders Order Details).Quantity *
(1 - child(Orders Order Details).Discount)”)
What if we wanted to include the freight cost in the order’s total? A calculated column can
either be a simple one or contain aggregates over related rows, but not both If you need a column
with the grand total of the order, you must add yet another calculated column to the Orders table
and set it to the sum of the OrderTotal and Freight columns
Computing Expressions
In addition to calculated columns, you can use the Compute method of the DataTable object to
perform calculations that involve the current DataTable’s rows, their child rows, and their parent
rows The following statement returns an integer value, which is the number of orders placed by
a specific customer:
DS.Orders.Compute(”COUNT(OrderID)”, ”CustomerID = ’ALFKI’”)
Trang 6Actually, the Compute method returns an object, which you must cast to the desired data type.
To store the value returned by the preceding statement to an integer variable, use the followingexpression:
Dim count As Integercount = Convert.ToInt32(DS.Orders
Compute(”COUNT(OrderID)”, ”CustomerID = ’ALFKI’”))
The Compute method returns a value; it doesn’t save the value to another column Moreover, theComputemethod allows you to limit the rows that participate in the aggregate with an expressionidentical to the WHERE clause of a SELECT statement
Consider again a DataSet with the Orders and Order Details DataTables If you need the total
of all orders for a specific customer, you must call the Calculate method, passing a restriction as
an argument, as shown in the preceding statement If the DataSet contained the Customers table
as well, you could add a calculated column to the Customers table and store there each customer’stotal for all orders This value should be identical to the one returned by the Compute method
VB 2008 at Work: The SQL Expressions Project
In this sample application, we’ll put together all the information presented so far in this chapter
to build a functional application for exploring the Northwind Corporation’s sales The tion’s main form consists of a TabControl with five tab pages, which are shown in Figures 24.1through 24.5 To use the application, you must click the Populate DataSet button at the bottom ofthe form
applica-Figure 24.1
On the Orders tab of the
SQL Expressions
appli-cation, you can select
orders based on various
user-supplier criteria
On the Orders tab, you can select orders based on various criteria Note that you can’t combinethe criteria, but it wouldn’t be too much work to take into consideration multiple criteria andcombine them with the AND operator On the Customer Orders tab, you can view the customersand select one to see that customer’s orders, as well as a summary of the selected customer’sorders The Employee Orders tab is almost identical; it displays orders according to employees Onthe Best Sellers tab, you can click the Top Products and Customers button to view the best-sellingproducts and the top customers If you click a customer name, you’ll be switched to the CustomerOrders tab, where the same customer will be selected on the list and the customer’s orders will
Trang 7VB 2008 AT WORK: THE SQL EXPRESSIONS PROJECT 891
appear in the ListView control at the bottom of the form On the Order Details tab, you see the
selected order’s details No matter where you select an order by double-clicking it, its details will
appear on this tab
Figure 24.2
On the Customer Orders
tab, you can review
cus-tomers and their orders
Figure 24.3
On the Employee Orders
tab, you can review
employees and their
orders
Figure 24.4
On the Best Sellers
tab, you can view the
best-selling products
and the customers with
the largest sales figures
Trang 8Figure 24.5
On the Order Details
tab, you can view an
First, you must create a new DataSet, the NorthwindDataSet, with the following tables: Orders,Order Details, Customers, Employees, and Products The relations between any two of these tableswill be picked up by the DataSet Designer and added to the DataSet I was interested in the sales
of the Northwind Corporation, but I’ve included the Employees, Customers, and Products tables
to display actual names (product, customer, and employee names) instead of meaningless IDs
When the form is loaded, the code adds a bunch of calculated columns to the DataSet’s tables, asshown here:
[Order Details].Subtotal A simple calculated column for storing each detail line’s total:
If NorthwindDataSet1.Order Details.Columns
(”DetailSubtotal”) Is Nothing ThenNorthwindDataSet1.Order Details.Columns.Add(”DetailSubtotal”,
Trang 9VB 2008 AT WORK: THE SQL EXPRESSIONS PROJECT 893
Customers.CustomerTotal A calculated column with aggregates for storing the customer’s
Products.ItemsSold A calculated column with aggregates for storing the number of items of
the specific product that were sold:
Employees.Employee A simple calculated column for storing the employee name as a single
string (instead of two columns):
Notice that the code checks to make sure that the column it’s attempting to add to the DataTable
doesn’t exist already In addition, the Quantity column’s type is changed from Integer to Decimal
This conversion is necessary because the Quantity column is used in aggregates later in the code,
and the result of the aggregate is the same as the column’s type Specifically, we’re going to
calcu-late the average quantity per order with the AVG(Quantity) function of T-SQL If the argument of
the function is an integer, the result will also be an integer, even though the average is rarely an
integer The following statement changes the type of a DataColumn in the DataSet:
NorthwindDataSet1.Order Details.Columns(”Quantity”).DataType =
System.Type.GetType(”System.Decimal”)
See the section ‘‘Aggregate Functions’ Return Values’’ a little later in this chapter for more on
handling the return values of aggregate T-SQL values
Trang 10Then the code clears the DataSet and loads its tables with the following statements:
NorthwindDataSet1.Clear()Me.Order DetailsTableAdapter1.Fill(NorthwindDataSet1.Order Details)Me.OrdersTableAdapter1.Fill(NorthwindDataSet1.Orders)
Me.ProductsTableAdapter1.Fill(NorthwindDataSet1.Products)Me.ShippersTableAdapter1.Fill(NorthwindDataSet1.Shippers)Me.CustomersTableAdapter1.Fill(NorthwindDataSet1.Customers)Me.EmployeesTableAdapter1.Fill(NorthwindDataSet1.Employees)
Now, on the Orders tab, we can look at the statements that perform the search operations
All the buttons on this tab pick up the appropriate values from the controls on the right side of theform and submit them to the Select method of the Orders DataTable The Search By Order Datebutton executes the Select method shown in Listing 24.1 to retrieve the orders that were placedbetween the two specified dates
Listing 24.1: Retrieving Orders by Date
Private Sub bttnSearchOrderByDate Click( )
Handles bttnSearchOrderByDate.ClickDim selectedRows() As DataRow
lblOrderSearchCount.Text = ”Search returned ” &
selectedRows.Length.ToString & ” rows”
End Sub
The first argument to the Select method is an SQL expression that selects orders by data,and the second argument determines the order in which the rows of the Orders table will bereturned When the various date values are substituted, the following Select method is exe-cuted:
Select(”OrderDate>=’1/1/1996’ AND
OrderDate <= ’8/31/1996’”, OrderDate DESC”)
The arguments passed to the Select method are identical to the WHERE and ORDER BY clauses
of a SELECT statement you’d execute against the database with the Command object The Selectmethod, however, will act on the data in the DataSet at the client; it will not contact the server
If you need live, up-to-the-minute data, you should execute your queries directly against thedatabase But for many reporting tools, you can move all the relevant information to the client andwork with it without additional trips to the server The sample application shown in this section
is a typical example of the type of applications that will benefit the most from working with adisconnected DataSet
Trang 11VB 2008 AT WORK: THE SQL EXPRESSIONS PROJECT 895
Should We Move Large Tables to the Client?
You’ll probably wonder how wise it is to load a large chunk of the database to the client In some
cases, it makes sense to move a lot of data to the client If a manager needs all this information, for
example, the data will be moved to the client, either in small pieces or as a whole
You should impose some limits to the amount of data you move to the client as always, such as
lim-iting the orders by date or the customers by geographical area, but still you’ll end up downloading a
whole lot of data to the client Think of these applications as reports: If you need to print a detailed
sales report, you’ll move all the required information to the client Besides, this type of application is
used by decision makers and is not used on a daily basis either
As long as you don’t move all the customers and products to the client every time the user must select
a client or a product to issue an invoice, your applications won’t cause network traffic problems In
other situations, you can afford to move large result sets to the client, because the application will not
connect to the server again for a long time — not to mention that you can persist the DataSet at the
client and reuse the same data in a later session
An advantage of moving large sets of data to the client is that we free the server by moving a lot of
operations that would otherwise be executed by SQL Server to the client Again, this makes sense only
if the user of the application is going to work for a while with the data and won’t be populating the
client DataSet every few minutes
You can also persist the DataSet to a disk file and allow managers to examine the sales figures of last
month, or last quarter, for as long as they wish on their workstations, even on their laptops After
the DataSet has been saved to a local file, the end user can disconnect from the database and work
with the data in a totally disconnected fashion With a powerful client, this approach is even more
efficient than executing queries against the database as needed, especially if the database server is
overwhelmed by other tasks that must be performed in a connected fashion
Selecting and Viewing an Order’s Details
Let’s continue with the other operations of the application When you double-click an order on
the Orders tab, you’ll see its details in a ListView control as usual, in the Order Details tab
The application’s code extracts the ID of the selected order and passes it as an argument to the
DisplayOrder()subroutine, which populates the controls on the Order Details tab
The code of the DisplayOrder() subroutine is a bit lengthy, so I’ll explain the basic operations
here You can open the project to see the entire listing of the subroutine The DisplayOrder()
subroutine starts by selecting the details of the specified order with the following statements:
Dim selectedRows() As DataRow
selectedRows = NorthwindDataSet1.Order Details.Select(
”OrderID=” & OrderID.ToString, ”ProductID”)
Then it populates the customer controls on the tab by calling the ShowOrderCustomer()
sub-routine, passing as an argument the order’s ID The ShowOrderCustomer() subroutine retrieves
the order’s row from the Orders table by calling the FindByOrderID method This method is
Trang 12exposed automatically by the DataSet, because typed DataSets always provide a method to findrows by their ID value Then it retrieves the customer row from the Customers table by callingthe FindByCustomerID method of the Customers table After reading the customer row, it canpopulate the appropriate controls on the tab.
Dim custOrder As NorthwindDataSet.OrdersRow =NorthwindDataSet1.Orders.FindByOrderID(OrderID)Dim customer As NorthwindDataSet.CustomersRow =NorthwindDataSet1.Customers.FindByCustomerID(custOrder.CustomerID)
Back to the DisplayOrder() subroutine: After the customer data have been displayed, theDisplayOrder()subroutine goes through the selectedRows array, which contains the order’s
detail lines: one DataRow object per element Note that the Select statement returns an array ofgeneric DataRow objects, not a specific row object such as NorthwindDataSet.Order DetailsRow
The code in the DisplayOrders() subroutine iterates through the entire array, casts each element
of the array to the specific type, and displays its fields in the lvOrderDetails ListView control
of the Order Details tab Listing 24.2 shows only the statements that retrieve the detail fields andcreate a new ListViewItem, which is then added to the ListView control
Listing 24.2: Displaying the Items of a Detail Line
Dim Product As String =NorthwindDataSet1.Products.FindByProductID(CType(selectedRows(i),NorthwindDataSet.Order DetailsRow).ProductID).ProductName
Dim Qty As Integer = CType(CType(selectedRows(i),NorthwindDataSet.Order DetailsRow).Quantity, Integer)Dim Disc As Decimal = CType(CType(selectedRows(i),
NorthwindDataSet.Order DetailsRow).Discount, Decimal)Dim Price As Decimal = CType(CType(selectedRows(i),NorthwindDataSet.Order DetailsRow).UnitPrice, Decimal)LI.Text = Product
LI.SubItems.Add(Qty.ToString(”#,###”))LI.SubItems.Add(Price.ToString(”#,###”))LI.SubItems.Add(Disc.ToString(”#,###.00”))
The Order Details table contains product IDs, which are of no interest to the user, so the first
statement extracts the ProductID field of the current detail row and passes it as an argument to
the FindByProductID method of the Products DataTable This method returns the matching row
of the Products DataTable, and the code uses it to display the product’s name The statements thatextract the other detail fields (quantity, price, and discount) are trivial
The Customer Orders and Employee Orders tabs are similar: They display a list of customersand employees, respectively, and every time the user selects a customer or employee in the appro-priate list, the code displays the selected item’s orders (the orders placed by a customer or theorders made by an employee, respectively) in a ListView control At the same time, it displays
a summary for the selected entity in a TextBox control, as you can see in the correspondingfigures The most interesting piece of code in these two pages is the statements that calculatethe summary data The statements of Listing 24.3 calculate the average order quantity, the averageorder amount, and the total order amount for the selected customer
Trang 13VB 2008 AT WORK: THE SQL EXPRESSIONS PROJECT 897
Listing 24.3: Calculating Customer Averages
avgQuantity =
CType(NorthwindDataSet1.Order Details.Compute(”AVG(Quantity)”,
”Parent(FK Order Details Orders).CustomerID=’” &
CustomerID & ”’”), Decimal)
avgOrder = CType(NorthwindDataSet1.Orders.Compute(
”AVG(OrderTotal)”, ”CustomerID=’” &
CustomerID & ”’”), Decimal)
totalQuantity = CType(NorthwindDataSet1.Order Details
Compute(”SUM(Quantity)”,
”Parent(FK Order Details Orders).CustomerID=’” &
CustomerID & ”’”), Integer)
Total = CType(NorthwindDataSet1.Orders.Compute(
”SUM(OrderTotal)”, ”CustomerID=’” &
CustomerID & ”’”), Integer)
The first statement uses the Compute method of the Order Details DataTable to compute
the average of the Quantity column over the subset of rows specified by the second argument
(the underscore was inserted by the DataSet designer, because the actual table name contains
a space) This argument limits the rows of the Order Details DataTable to the ones that belong
to the orders with CustomerID equal to the ID value of the selected customer The expression
Parent(FK Order Details Orders)returns the rows of the Orders table that are related to the
rows of the Order Details DataTable with the FK Order Details Orders relation From these
rows, we select the ones with the specified CustomerID field The result of the Compute method is
an object, which is cast to a Decimal value with the CType() function
Without the ability to evaluate SQL expressions over the client’s DataSet data, you’d have to
iterate through the rows of the Customers table, locate the child Order rows for each customer, and
then the Order Detail rows of each order, calculate the line totals, and add them This approach
takes a lot of complicated code, is not nearly as efficient, and (most important, in my view) is not
elegant In my experience, an elegant approach is usually more efficient, not to mention that it
simplifies the application’s code overall and is easier to maintain Of course, if you’re not familiar
with SQL expressions and the Compute method of the DataTable object, you’ll find the preceding
code hard to understand and even harder to apply to other situations
If you still consider the preceding statements cryptic, consider the equivalent SQL statement
you’d execute in SQL Server’s Management Studio (or Query Analyzer, for users of SQL Server
2000) and try to map its clauses to the arguments of the Compute method The following SQL
statement returns the average and total order quantities for a specific customer:
SELECT AVG(Quantity)
FROM [Order Details] INNER JOIN Orders
ON [Order Details].OrderID = Orders.OrderID
WHERE Orders.CustomerID = ’BLAUS’
In effect, the Parent() function corresponds to the INNER JOIN clause, and the AVG(Quantity)
function is the SELECT statement’s selection list The join operation in the SQL expression is
Trang 14identified by the argument to the Parent() function: The FK Order Details Orders relationassociated the rows of the Order Details DataTable with the rows of the Orders DataTable, just asthe JOIN operator does in the SQL statement.
Aggregate Functions’ Return Values
Let me digress here for a moment to explain a tricky aspect of the aggregate functions If youexecute the preceding SQL statement, the result that it will return for the specific customer is 26
The SQL Expressions application will report a slightly different (and more likely) value: 26.12
Please recall that we had to change the data type of the Quantity column in the Order Details
DataTable from Integer to Decimal to get the correct results The AVG() function returns a value
of the same type as the column specified in its argument list The Quantity column is an integer
value, and so is the average over this column This is a technicality you can easily forget and, as aresult, get the wrong results from your database Chances are that you will calculate the averagequantities for many customers and notice that all results are integers, a highly unlikely situationfor averages At any rate, one could easily think that the query worked fine because it returned aresult that’s not ‘‘unrealistically’’ incorrect To fix the previous SQL statement, you must cast thecolumn you’re averaging to the desired type, as shown here:
SELECT AVG(CAST(Quantity AS Numeric(8,2)))FROM [Order Details] INNER JOIN Orders
ON [Order Details].OrderID = Orders.OrderIDWHERE Orders.CustomerID = ’BLAUS’
This SQL statement will return the same result as the SQL Expressions application
The Top Products And Customers button on the Best Sellers tab retrieves the 10 products withthe largest sales and the 10 best customers in terms of revenue they generated for the corporation
The results are displayed in two ListView controls, lvBestProducts and lvBestCustomers Thecode behind this button is quite short and is shown in Listing 24.4
Listing 24.4: Retrieving the Best-Selling Products and Best Customers
Private Sub bttnBestSellers Click( )
Handles bttnBestSellers.ClickDim selectedRows() As DataRow
selectedRows =NorthwindDataSet1.Customers.Select(””, ”CustomerTotal DESC”)Dim i As Integer
Dim customerItems As IntegerDim LI As ListViewItemlvBestCustomers.Items.Clear()For i = 0 To 9
LI = New ListViewItemDim custRow As NorthwindDataSet.CustomersRow =CType(selectedRows(i), NorthwindDataSet.CustomersRow)LI.Tag = custRow.CustomerID
LI.Text = NorthwindDataSet1.Customers
FindByCustomerID
Trang 15VB 2008 AT WORK: THE SQL EXPRESSIONS PROJECT 899
(custRow.CustomerID)
CompanyName.ToStringDim custTotal As Decimal = Convert.ToDecimal(
NorthwindDataSet1.Customers
FindByCustomerID(
custRow.CustomerID)
Item(”CustomerTotal”))LI.SubItems.Add(custTotal.ToString(”#,###.00”))
(prodRow.ProductID).ProductName.ToStringDim itemTotal As Integer = Convert.ToInt32(
NorthwindDataSet1.Products.FindByProductID(
prodRow.ProductID).Item(”ItemsSold”))LI.SubItems.Add(itemTotal.ToString(”#,###”))
lvBestPoducts.Items.Add(LI)
Next
End Sub
The code starts by selecting the rows of the Customers DataTable sorted by the
Customer-Totalcolumn in descending order Then it iterates through the top 10 rows, casts each row to
the NorthwindDataSet.CustomersRow type (so we can work with a strongly typed object), and
displays the appropriate fields on the lvBestCustomers ListView control Next it populates the
selectedRows array again, this time with the rows of the Products table, sorted by the ItemsSold
column in descending order The top 10 rows are the best-selling products, and the code displays
the appropriate fields in the lvBestProducts ListView control.
Note how the code uses the FindByProductID method to retrieve the matching product row
and read its ItemsSold column Even though we’re working with a typed DataSet, the ItemsSold
column was added to the DataTable control and was not available when the DataSet was created,
which explains why you won’t see this member when you enter the name of the variable of the
ProductRow type followed by a period
Trang 16Open the SQL Expressions project, explore its operations, and take a closer look at its code I’veincluded many comments to explain the application’s operation and ease your way through thecode (This application has more comments than a college student’s homework!) It’s a functionalreport-style application, and you can write similar applications for your company’s data You’ll
be really hard-pressed to achieve this level of functionality with a reporting tool, not to mentionthat you can add printing capabilities to the application by using the techniques discussed inChapter 20, ‘‘Printing with VB 2008.’’
The idea is to duplicate a small section of the database in the client’s computer memory bypopulating a DataSet with the tables we want to work with (or segments of the tables) The sampleapplication uses the same data over and over again, so it makes sense to move all the required data
to the client, because this will save our application from making a trip to the server every time theuser clicks one of the items on the form (a customer/employee, an order, and so on) Tables have
a tendency to grow quickly, so you should always try to limit the number of rows you move tothe client, as well as the number of columns you select from each table For instance, you can workwith the orders of all customers from Germany, or the customers that have placed an order in thelast two months, and so on
The Bottom Line
Use SQL to query DataSets. Although DataSets resemble small databases that reside in theclient computer’s memory, you can’t manipulate them with SQL statements However, it’spossible to query their tables by using the Select method and SQL-like criteria The Selectmethod filters the rows of the table to which it’s applied and returns an array of DataRowobjects, which you can use as a data source for data-bound controls
Master It How would you select the rows of interest from a DataTable?
Add calculated columns to DataTables. Sometimes you’ll need to update a column’s valuebased on the values of other columns For example, you may wish to maintain a column in theOrders DataTable with the order’s total For this column to be meaningful, its value should
be updated every time a related row in the Order Details DataTable is modified In the actualdatabase, you’d do this with a trigger, but we want to avoid adding too many triggers to ourtables because they slow all data-access operations, not to mention that you’ll be duplicatinginformation To maintain totals in a DataSet, you can add calculated columns to its Data-Tables You specify a formula for the calculated column, and every time one of the columnsinvolved in the formula changes, the calculated column’s value changes accordingly
Master It Add a calculated column to the Customers DataTable that combines the firstand last columns
Compute aggregates over sets of rows. To calculate aggregates over sets of rows in a Table, use the Compute method, which accepts two arguments: an SQL-like aggregate functionand a filtering expression, which is similar to an SQL WHERE clause The aggregate functionisn’t limited to columns of the table to which it’s applied; you can use the Child()function toaccess the current row’s child row in a given relation, and the Parent() function to access thecurrent row’s parent row(s) in a given relation, which is passed to the method as an argument
Data-Master It Show the statement for adding a new column to the Orders table with eachorder’s total
Trang 17Chapter 25
Building Web Applications
Developing web applications in Visual Studio 2008 has many similarities to developing traditional
desktop applications You drag and drop controls onto a form and build your business logic by
using your language of choice — in our case, Visual Basic 2008
However, as you will see, there are also many differences There are underlying technologies
that you, the developer, should have a solid understanding of, additional control sets to work
with, and some fundamental differences in the way that the standard controls behave
In this chapter, you will learn how to do the following:
◆ Create a basic XHTML/HTML page
◆ Format a page with CSS
◆ Set up a master page for your website
◆ Use some of the ASP.NET intrinsic objects
Developing for the Web
In the early days of web development (not all that long ago!), a developer could earn big money
creating what were essentially online brochures by using a basic knowledge of Hypertext Markup
Language (HTML) and some simple design skills
These days we expect a great deal from our websites and web applications Entertainment sites
are now fully equipped to engage the visitor with rich user interfaces incorporating a wide range
of visual and aural experiences Members of the corporate world expect their virtual presence to
mirror their full range of business practices
In addition, web development, although still seen as a specialized area, is now part of the
cor-porate mainstream, and the developer is expected to be well versed across a range of technologies
and techniques
The modern web application combines a wide range of sophisticated technologies grafted
onto the HTTP/HTML backbone Cascading Style Sheets (CSS) are used to control the layout and
appearance of a website Data is managed with the use of Extensible Markup Language (XML)
and back-end databases such as SQL Server, while rich user interfaces are developed using XML,
JavaScript, and other technologies such as Adobe Flash AJAX, a clever implementation of existing
technologies, combines XML, JavaScript, and asynchronous technologies to enable the developer
to create online applications that exhibit traditional desktop behavior XML web services,
multi-media content, RSS feeds, and the use of microformats to assist data aggregators have all become
typical features of modern websites
In addition, the developer can now expect a website to be accessed by more than just a desktop
computer Mobile phones, PDAs, and other small form factor devices are all used to access the
Trang 18web in the 21st century Websites, to be truly ubiquitous, are increasingly expected to be able todynamically render their content into an appropriate format.
Visual Studio 2008 provides a range of tools that enable the modern developer to meet thedemands of website creation from the comfort of a Visual Basic environment Database connec-tivity is simplified from the traditional complexity of hand-coding scripted server-side pages, andsites can be developed that dynamically render to suit a wide range of devices without the need tobuild multiple versions of an individual site By compiling much of the code used to drive a site,many of the security issues that plagued scripted sites are avoided
Typically, a modern website or web application relies on code that is executed both at theclient (web browser) and server (web server) ends In addition, there may be a whole range ofother services provided by other servers on the hosting network such as media or databases, andeven services sourced from other websites Visual Studio 2008 provides the tools to tie all thistogether
This chapter gives an overview of the core technologies that drive the modern web applicationand demonstrates the basic tools available to the developer in Visual Studio 2008
I will begin with some basic concepts If you are already familiar with HTML, JavaScript, andserver technologies, you may wish to skip ahead to material that is new to you, such as the
‘‘Cascading Style Sheets’’ section
Understanding HTML and XHTML
HTML is essentially a language to describe text formatting and enable linking of documents (web
pages) delivered over the Web HTML has grown since its original inception but is still mentally limited The area where it does excel is in its ability to act as a framework in which othertechnologies such as JavaScript can be embedded
funda-Extensible HTML (XHTML) is the latest incarnation of HTML It was developed by the World
Wide Web Consortium (W3 C) to bring HTML syntax into line with other markup languages such
as XML Most of the tags from HTML 4 (the most recent update to HTML) remained the same, butmuch stricter syntax rules apply The basic changes are as follows:
◆ XHTML is case sensitive, and all tags are in lower case.
◆ All tags must be closed You can no longer get away with using multiple <p> tags out corresponding closing </p> tags This includes tags such as <img> that previously
with-had no corresponding closing tag Close these tags with a trailing backslash before the finalangle bracket For example:
<img src = ‘my picture.jpg’ alt = ‘picture’ \>
◆ All tag attributes must be enclosed in quotation marks (either single or double)
◆ All pages must include an XHTML !DOCTYPE definition and an XML version declaration
◆ JavaScript must also conform to case syntax — for example, onmouseover not
onMouseOver.The W3 C encourages developers to use XHTML over HTML However, for practical purposes,web browsers still support HTML, and you can get away with not updating older sites and contin-uing to work with HTML’s lack of strict syntax See the following sidebar if you wish to upgradeolder sites
Trang 19WORKING WITH HTML 903
Upgrading from HTML to XHTML
Converters exist for porting your HTML sites to XHTML There are also tools to assist in the process
manually W3 C provides an online validator at http://validator.w3.org
You can use the validator to initially ensure that your pages conform to the HTML 4 specification and
that they all contain a !DOCTYPE definition such as the following:
<!DOCTYPE HTML PUBLIC ”-//W3C//DTD HTML 4.01//EN”
”http://www.w3.org/TR/html4/strict.dtd”>
After your pages are validated for HTML 4, you will need to add the XML declaration to the top of
each page:
<?xml version=”1.0” encoding=”iso-8859-1”?>
Then convert the !DOCTYPE definition to the XHTML version:
<!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN”
”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
Finally, modify the<HTML> tag to read as follows:
<HTML xmlns=”http://www.w3.org/1999/xhtml”>
Assuming that you have made all the correct syntax changes, run the validator again and see how
your page performs
Working with HTML
As a Visual Studio programmer, knowledge of HTML and XHTML can prove invaluable when
sorting out the inevitable formatting and design issues that arise when developing complex web
applications In addition, understanding the technologies involved can aid in optimizing the
interactions between server and client
To keep things simple, I will dispense with some of the finer points of XHTML and focus
mainly on ‘‘straight’’ HTML This section is meant as a basic HTML primer (and is by no means
comprehensive), so feel free to skip ahead if you are already familiar with the language
More information on HTML can be found easily on the Web or in Mastering Integrated HTML
and CSS by Virginia DeBolt (Sybex, 2007) Useful websites for tutorials include www.w3schools.
comand www.htmlcodetutorial.com
You can use any standard text editor to author your HTML Notepad is fine
More-sophisticated tools that indent and highlight code, such as Notepad2 or EditPad Pro, are
avail-able on the Web EditPad Pro is a commercial application availavail-able from www.editpadpro.com
Notepad2 is freeware and available from www.flos-freeware.ch/notepad2.html
Remember to save your files with an html file extension for them to be recognized as HTML
pages
Trang 20Page Construction
HTML pages have two main sections nested between the opening and closing <html> .</html>
tags
The first section is known as the head area, and it is used to contain information not usually
displayed on the page (The main exception to this is the page title.) The head area is created by
using the <head> .</head> tags and contains meta-information about the page such as the
!DOCTYPEdefinition, author details, keywords, and the like It is also used to hold style sheetinformation and scripts that may be called later in the page
The second section of the page is the body, and it contains information that is typically displayed
on the page in a web browser The body is declared by using the <body> .</body> tags.
HTML tags are used to describe the formatting or nature of the information contained within
the opening and closing tags Tags may also contain attributes, which are used to apply further
information to the content between the opening and closing tags For example, the body tag canuse the attribute bgcolor to set the background color of the web page The syntax for setting a
page color to blue is <body bgcolor =”blue”>
A basic page may appear as shown in Listing 25.1 Some long lines are wrapped here in print,but you can leave them all on one line in your code
Listing 25.1: A Basic HTML Page
<!DOCTYPE HTML PUBLIC ”-//W3C//DTD HTML 4.01//EN”
A simple web page
run-ning in a web browser
window
Trang 21WORKING WITH HTML 905
The <title> tag enables the title of the page to appear in the title bar of Internet Explorer The
<meta>tag provides a description phrase that can be accessed by search engines The bgcolor
attribute of the <body> tag sets the background color to blue, and the <p> tag is used to denote
a simple block of text
Note that I have used the !DOCTYPE definition for HTML 4 Also note that not closing the
<title>tag correctly can cause the rest of the page to break
Text Management
There are a range of text management tags, including the previously mentioned <p> tag The
principal tags are as follows:
◆ The heading tags,<h1> .</h1>, <h2> .</h2> through to <h6> .</h6>, are used to
control the size of text <h1> is the largest format.
◆ The font tag, <font> .</font>, has a number of attributes including face for font type,
colorfor text color, and size for font size Font sizes range from 1 to 7, where 7 is the
largest An example of the tag’s usage is <font face =”verdana” color =”red” size
=”3”>Hello World</font>.
◆ The small and big tags — <small> .</small>, <big> .</big> — can be used to
quickly adjust the relative size of text
Styles can be managed with tags such as the following:
◆ Bold: <b> .</b>
◆ Underline: <u> .</u>
◆ Italic: <i> .</i>
◆ Strong: <strong> .</strong>
Another useful tag when working with text is the line break tag: <br> In HTML, this tag does
not require a closing tag
Spaces between text can be generated and controlled with more precision than simply relying
on the client browser to insert your preferred amount of white space by using the following special
character:
A number of other special characters exist to accommodate symbols such as quotes,
ques-tion marks, or copyright symbols A comprehensive list of HTML tags and their attributes can
be found at www.w3schools.com/tags/default.asp You can also refer to the W3 C
specifica-tion for HTML 4.01 at www.w3.org/TR/html401/ The XHTML 1.1 specificaspecifica-tion can be found at
www.w3.org/TR/2007/CR-xhtml-basic-20070713/
Horizontal Rules
The <hr> tag can be used to draw a line across the page Its attributes include align, noshade,
size, and width Width can be declared as a percentage or as an exact amount in pixels
In HTML 4, there is no closing tag
Images
Images can be added to web pages by using the <img> tag This tag is not typically closed under
HTML 4 Attributes for this tag include the following:
◆ The path to the image, src, which can be relative or absolute (Required.)
Trang 22◆ A text alternative to the image, alt, which is normally recommended for accessibility.
◆ align is used to align an image on a page and to wrap text around the image
◆ border is used to create a border around the image
◆ width and height are used to help the page load more quickly, and can also be used toscale an image
◆ usemap is used to create image maps
A typical use of the <img> tag might be the following:
<img src=‘images/myimage.jpg’ border=‘0’ width=‘150’
height=‘150’ align=‘left’ alt=‘Test Image’>
For use in web pages, images must be in one of the following formats: GIF, PNG, or JPG Youusually use the GIF or PNG formats for drawings or line art, and the JPG format for photographs
Links
Links can be created on web pages that link to other web pages within the site, other websites,other types of documents, e-mail, or other locations within the host page Links are created by
using the <a> .</a> tag.
Typically, the <a> tag is used with the href attribute to define the destination of the link For
Media objects such as Windows Media Player, Apple’s QuickTime, and Flash can be embedded
in a page by using the <embed> tag At its very simplest, the tag can be made to work by simply
specifying the source file for the media and the display size, and then trusting the browser to havethe required plug-in and to be able to sort it out For example:
<embed src=‘multimedia/myvideo.avi’ height=‘200’ width=‘200’></embed>
At a more sophisticated level, you can specify a range of options including the type of plug-in,the controls to display, whether it should start automatically, and loop properties
Trang 23WORKING WITH HTML 907
Scripts
The <script> .</script> tag can be used to insert non-HTML script code such as JavaScript
into your pages Scripts can be written into the header area and called from the body or used
directly in the body of the page Before support for more-recent HTML versions and before
JavaScript could be found in virtually every web browser, developers would typically comment
out the code by using <! > to prevent the code from appearing in the browser page This
is still common practice, although it is no longer usually necessary
A simple example of the script tag’s usage is as follows:
Bulleted and numbered lists can be displayed in a web page by using the list tags <ul> .</ul>
for a bulleted list or <ol> .</ol> for a numbered list Individual items within the list are
denoted by using the <li> .</li> tags An example of creating a bulleted list is as follows:
Tables are used extensively in HTML, not only to display data but also to reassemble sliced images
(a technique for minimizing the file size of large images) and to format pages However, using
tables to format pages is no longer recommended by the W3 C For accessibility reasons,
technolo-gies such as CSS are the recommended method for creating sophisticated layouts
Tables are made of rows of cells When constructing your table, you need to consider the
desired width of the table, the number of rows, and the number of columns required Other factors
that you may wish to take into account are the padding between cells, and the padding between
the border of a cell and its contents
Another important consideration is that a badly constructed table is one of the few things that
can truly break an HTML page You must ensure that all your tags are correctly closed Tables can
be nested within one another, but excessive nesting can place undue strain on the rendering engine
of the browser and cause unexpected results
A range of tags are used to create a typical table, and each has its own family of attributes:
◆ The <table> .</table> tag acts as the major framework for the table.
◆ <tr> .</tr> tags are used to create rows.
◆ Within a given row, <td> .</td> tags are used to create the individual cells The
num-ber of cells defined in the first row sets the numnum-ber of columns in the table This is
important to consider in subsequent rows if you wish to add or subtract from the number
Trang 24of cells The rowspan and colspan attributes are used to alter the number of columns androws employed at various points in the table For example: colspan = ‘2’ will force a cell
to span over two columns
◆ For headings, you can use <th> .</th> tags to create cells in the first row These offer a slightly different format than the <td> cells offer.
The following code snippet demonstrates a simple data table of three rows (one header) andthree columns The resulting table is shown in Figure 25.2
<table width=‘400’ border=‘1’>
A simple data table
The following code snippet illustrates how a table might be used to reconstruct a sliced image
Note the use of the align attribute to set horizontal alignment and the valign attribute to setvertical alignment:
<table width=‘400’ border=0 cellspacing=‘0’ cellpadding=‘0’>
<tr>
<td valign=‘bottom’ align=‘right’><img src=‘image1.gif’></td>
<td valign=‘bottom’ align=‘left’><img src=‘image2.gif’></td>
Trang 25WORKING WITH HTML 909
</tr>
<tr>
<td valign=‘top’ align=‘right’><img src=‘image3.gif’></td>
<td valign=‘top’ align=‘left’><img src=‘image4.gif’></td>
</tr>
</table>
Figure 25.3 illustrates how this image will appear in a web page (the left-hand image) and how
the table cells come together to reassemble the image (the right-hand image)
Various methods can be used to format pages in HTML They all have inherent limitations, but
the <div> tag offers the most flexibility The methods are as follows:
Flow format This relies on the browser to format the page according to the order of items in
the HTML Flow format is easy to implement, but of limited usefulness
A table This is one of the more popular methods, although it is no longer officially
recom-mended by the W3 C for accessibility reasons
Frames These effectively create the different parts of your page in separate HTML
docu-ments You would use a frameset to reassemble them as a single page in the browser
Inline frames (iFrames) These create a floating frame that can be placed within an HTML
page This is a popular method of displaying content from another website (such as a news
feed) within your web page
< div> tags These can be used to precisely locate content on your page Combined with CSS,
<div>tags offer a powerful and flexible method of organizing a page The output of ASP.NET
is largely driven by <div> tags for layout purposes.
Later, when you look at Cascading Style Sheets, you will see how <div> tags can be used to
lay out a page
Forms and Form Elements
Forms are the traditional method by which users can communicate information back to the web
server that is hosting the website being viewed Information sent back by a form can then be
processed in some way at the server, and the outcome can be dynamically incorporated into a
new page that the user can view
For example, a login page would likely use a form to collect the username and password from
the user and return this information to the server for authentication before access to the rest of the
site is granted In addition, personal preferences for the site can be applied to the returned pages
according to the stored preferences of the registered user
Trang 26A form is created by using the <form> .</form> tags The commonly used attributes include
the following:
Name Defines a unique name for the form
Action Specifies the Uniform Resource Locator (URL), or Internet address, of the resource toprocess the form’s response (Required.)
Method Either post or get (default) This specifies the HTTP method used to return theform’s data The get method sends the data as part of the URL (limited to a maximum of 100ASCII characters), and post sends the form’s content in the body of the request
Within the form, you create your HTML as usual However, information that you wish to be
processed by the form needs to be collected by using form controls The controls that are available
include the following:
Buttons Your form must have at least one button for submitting data Another button that iscommonly used clears the form’s contents Syntax for the buttons are as follows:
<input type=‘submit’ value=‘Submit data’>
<input type=‘reset’ value=‘Reset form’>
It is not necessary to include the value attribute because this sets the text that will appear inthe button, and there are default text values of Submit and Reset
You can use the following to create other buttons on your forms to run client-side scripts:
<input type=‘button’ value=‘Mybutton’ onclick=‘myscript’>
A more flexible control, however, is the <button> tag This can be used anywhere on the
HTML page to run scripts and can replace the traditional Submit and Reset buttons in yourforms It offers greater flexibility for formatting its appearance (especially when used withCSS) Its basic syntax is as follows:
<button type=‘button’ name=‘name’ onclick=‘myscript’>Click Here</button>
By using an image tag in place of Click Here, you can set an image to be the button Syntax
for using the button as a submit button is simply the following:
<button type=submit’ >Submit</button>
Text The Text control enables the user to enter a single line of text This can be set as a word field to mask the user’s entry The syntax is as follows:
pass-<input type=‘text’ name=‘identity of input data’
value=‘data to be initially displayed in field’>
The name attribute specifies the identity of the data to be processed at the server end (forexample, the username) The value attribute displays text that you may wish to appear
initially in the field (for example, Type user name here) You can also set other attributes
such as size and maxlength To create a password field, set the type attribute topassword
Trang 27CASCADING STYLE SHEETS (CSS) 911
TextArea For larger amounts of text, use the <textarea> tag Its syntax is as follows:
<textarea name=‘details’ rows=‘10’ cols=‘40’ >Type your details here</textarea>
Note that this control requires a closing tag
Lists To create lists, use the <select> tag Lists can be either single select or multiple select,
which is created by using the multiple attribute (simply typing multiple) The size attribute
specifies the number of rows to display Omitting the size attribute renders the control as a
drop-down combo box The contents of the value attribute are returned to the server
Individ-ual items are denoted by using the <option> tags By typing selected within one of the
option tags, that item is automatically highlighted in the list The syntax for the tag is as
follows:
<select name=‘items’ size=‘4’ multiple>
<option value=‘1’ selected>Chair</option>
<option value=‘2’>Couch</option>
<option value=‘3’>Arm Chair</option>
<option value=‘4’>Lounge Chair</option>
</select>
Check boxes To create a check box, you use a variation on the <input> tag and set the type
attribute to ‘checkbox’ To initially select a check box, type the attribute checked The syntax
is <input type = ‘checkbox’ name = ‘Check1’ checked>.
Radio buttons These are yet another variation on the <input> tag Set the type attribute
to ‘radio’ If you are using a set of linked radio buttons, type the same name attribute for
each radio button in the set The value attribute is used to return appropriate data when the
radio button is selected Here is the syntax:
<input type=‘radio’ name=‘radioset’ value=‘1’ checked>
<input type=‘radio’ name=‘radioset’ value=‘2’>
<input type=‘radio’ name=‘radioset’ value=‘3’>
Hidden fields Hidden fields contain information that you may want to make the round-trip
to the server, but that you do not want displayed on the client’s web page You can use this
field to help maintain state (discussed later in this chapter in the ‘‘Maintaining State’’ section).
Using this field is particularly useful when a client has disabled cookies or when the
information is too long or sensitive to incorporate into the URL For example, you may wish to
maintain information gathered in previous forms from the client ASP.NET uses hidden fields
extensively Here is the syntax:
<input type=‘hidden’ name=‘name of information’
value=‘information to be stored’>
Cascading Style Sheets (CSS)
Cascading style sheets offer a powerful method of controlling the format and layout of the pages
and content of your websites Styles can be written directly into your HTML pages or created in a
separate text document with the css extension The advantage to the developer of using separate
Trang 28CSS pages is that the format and layout of an entire site can be controlled from a single page Inlarge sites, consisting of tens or even hundreds of pages, this can be a huge time-saver as well asintroducing a much higher level of consistency and reliability.
In addition, styles are applied sequentially and can override previously set styles This enablesthe web developer to create specific styles for specific sections of the site that may modify theglobal settings You can create and apply multiple style sheets in this manner and even write indi-vidual style settings onto individual pages if necessary Styles can also be applied directly toindividual elements within a page As long as the desired settings are the last to be applied, thepage will appear as required
Syntax for CSS is quite different from syntax for HTML and is quite strict You can apply styles
directly to HTML tags (for example, you may wish to format the <h1> tag with a particular font
and color) or set them up in their own classes that can be applied when required For example,
you may wish to create your own <h8> class.
An external style sheet is included in an HTML page by using the <link> tag, which is
typ-ically placed in the head area of the web page The following example incorporates a style sheettitled mystylesheet.css from the styles directory into the web page:
<link rel=‘stylesheet’ type=‘text/css’ href=‘styles/mystylesheet.css’>
An internal style sheet can be created directly in the HTML page by using the <style> .
</style>tags Again, this is typically created in the head area of the document
If you wish to create a style locally to a particular tag, you add the style attributes inside the
tag For example, to extend the style of the <p> tag, you would use the following:
<p style=‘font-size:18pt; color:red;’>
Formatting Styles with CSS
Listing 25.2 illustrates a sample style sheet It demonstrates several simple style attributes that can
be applied to text You can use the styles directly in a web page by inserting the listing between
<style> .</style>tags or you can use it externally by saving the listing out to a separatetext document with a css file extension (for example, mystylesheet.css) Some long lines arewrapped here in print, but you can leave them all on one line in your code
Listing 25.2: A Sample Style Sheet
h1 {font-weight: bold; font-size: 24pt; color:red;
background: silver; text-align: center;}
p {font-family: arial, sans serif; font-size: 120%;}
p.quote {font-face:verdana; font-size: 10pt; font-style: italic;}
a {text-decoration:none; color:blue;}
a:visited {text-decoration:none; color:blue;}
a:hover {text-decoration:none; font-weight: bold;
font-size: 120%; color:darkblue;}a:active {text-decoration:none; color:blue;}
If you were to use Listing 25.2 as an external style sheet, you could link it to your web page by
inserting <link rel = ‘stylesheet’ type = ‘text/css’ href = ‘mystylesheet.css’>
Trang 29CASCADING STYLE SHEETS (CSS) 913
somewhere in the head area of your web page This also assumes that the style sheet is sitting in
the same directory as your web page
Points to note in Listing 25.2 include the following:
◆ The creation of a separate quote class for use with the <p> tag To employ this class in your
HTML, simply use <p class = ‘quote’> .</p>.
◆ By setting styles for the various permutations of the <a> tag, I have also created a
sim-ple rollover effect for use with links (The order in which these are applied is important for
the rollover effect to work.)
Rollovers can be created by using other methods such as JavaScript, but CSS offers a simple
way of globally controlling the effect You can also create quite sophisticated-looking buttons
around your links by using the formatting and style properties of CSS
Page Formatting with CSS
CSS also can be used to define page formatting and layout for an HTML document CSS is typically
used to define and control <div> tags for this purpose, although you can also use it to set and
control table properties
Listing 25.3 demonstrates a CSS style sheet used to control basic formatting Most of the items
should be self-explanatory (I have used named colors for the background colors for purposes of
clarity Usually it is preferable to use the hexadecimal equivalents.)
Listing 25.3: Style Sheet to Control Page Layout
Trang 30left: 180px;
right: 20px}
I have created three classes — title, menu, and content — to describe the three main areas of my
page The size of the area can be defined as well as its precise location In the case of the title class,
I haven’t specified an exact location, and the title area will appear relative to where it is writteninto the code Other properties of the areas can also be defined such as padding (distance betweenthe area’s border and its internal elements) and background color We use the margin property toset the width of the title area by defining how far it is located from adjacent elements and the pageborder
Using the margin property in this context can be a little confusing If four values are listed, theyrefer to top, right, bottom, and left, respectively However, listing just one value will apply it to allfour borders Listing two values will apply them to the top/bottom and right/left in combination
If there are three values listed, the missing values are taken from the opposite side It is sometimeseasier to refer specifically to the margin-right, margin-top, etc properties
You can either embed Listing 25.3 into an HTML page or access it by using an external stylesheet Listing 25.4 demonstrates the code embedded into an HTML page and utilized to set thelayout of the page Some long lines are wrapped here in print, but you can leave them all on oneline in your code
Listing 25.4: Using a Style Sheet to Set the Layout of a Web Page
<!DOCTYPE HTML PUBLIC ”-//W3C//DTD HTML 4.01//EN”
background:lightblue;
margin:5px 10px 10px 10px;
text-align: center;
}.menu{position: absolute;
Trang 31CASCADING STYLE SHEETS (CSS) 915
Figure 25.4 illustrates how the layout from Listing 25.4 appears in a web page Carefully look
at the code and you will see how the individual layout classes are used inside the <div> tags to
generate the layout structure of the page
Figure 25.4
Listing 25.4 running as a
web page
Trang 32This is a very brief overview of CSS For more-comprehensive coverage, please refer to
Master-ing Integrated HTML and CSS by Virginia DeBolt There are also many online tutorials available,
such as www.w3schools.com/css/
JavaScript
You can embed JavaScript into your HTML pages to create interactive and dynamic elements atthe client end JavaScript can be used to create named functions inside the script tags that can becalled later in the page You can also use JavaScript attached directly to HTML elements
Currently, 18 events specified in HTML 4 and XHTML 1 can be used as triggers to run ual scripts Table 25.1 lists these events
individ-Table 25.1: Events Available for Use in HTML
Keyboard Events (Not Valid in Base, BDO, BR, Frame, Frameset, Head, HTML, iFrame, Meta, Param, Script, Style, and Title Elements)
released
Mouse Events (Not Valid in Base, BDO, BR, Frame, Frameset, Head, HTML, iFrame, Meta, Param, Script, Style, and Title Elements)
mouse
the mouse
object
the object
Form Element Events (Valid Only in Forms)
Trang 33JAVASCRIPT 917
Table 25.1: Events Available for Use in HTML (CONTINUED)
the submit button
reset button
selected
selects the object
Window Events (Valid Only in Body and Frameset
Elements)
The following code snippet gives an example of using JavaScript to create a rollover effect on a
link:
<a href=”newpage.html” >
<font color=‘blue’ face=”verdana” onmouseover=”this.style.color = ‘lightblue’;”
onmouseout=”this.style.color = ‘blue’;” size=1>New Page</font></a>
This script sets the link color to blue Rolling the mouse over the link changes it to a light blue
Moving the mouse off the link resets it to the normal blue
Listing 25.5 demonstrates how a JavaScript function can be embedded into a web page and then
called from a button press In this example, clicking the Test button will set the background color
of the web page to blue Note that the use of bgColor in the JavaScript function is case sensitive
Some long lines are wrapped here in print, but you can leave them all on one line in your code
Listing 25.5: Demonstration of a JavaScript Function
<!DOCTYPE HTML PUBLIC ”-//W3C//DTD HTML 4.01//EN”
Trang 34<button type=‘button’ onclick=‘changecolor()’>Test</button>
</body>
</html>
We have only touched on the possibilities of JavaScript in these examples Please refer to
JavaScript Bible, Sixth Edition, by Danny Goodman and Michael Morrison (Wiley, 2007) for
more-thorough coverage There are many online tutorials also available A good starting point is
at www.w3schools.com/js/
AJAX
Asynchronous JavaScript and XML (AJAX) enables the web developer to create online applicationsthat behave more like standard desktop apps The asynchronous nature of the technology enablesyou to make an HTTP request to the server and continue to process data while waiting for theresponse Data transfers are handled by using the XMLHTTPRequest object This combines withthe Document Object Model (DOM), which combines with JavaScript to dynamically update pageelements without the need for a browser refresh
A detailed exploration of AJAX is beyond the scope of this book For our purposes, it is tant to note that AJAX has been incorporated into ASP.NET 3.5 and can be leveraged into yourweb applications from Visual Studio 2008 We will look at this in more detail in Chapter 26,
impor-‘‘ASP.NET 3.5.’’
An online AJAX tutorial is available from www.w3schools.com/ajax/default.asp
Microformats
You can use microformats to list data on your website so that it can be accessed by various
data-aggregation tools Microformats are really just specifications for formatting data such as
address book details or calendar information Thousands of microformats exist TheMicroformats.orgwebsite (http://microformats.org) is a good starting point for the variousspecifications
The hCard is an example of how microformats work The hCard specification is modeled on the vCard specification, which is widely used for address books You can use the hCard creator on
the Microformats website to automatically generate the code for use on your own site You canalso hand-roll your own code according to the specification The advantage of listing your addressdetails in the hCard format is that anyone visiting your site can automatically add your details totheir own address book according to the vCard specification
Server-Side Technologies
So far you have looked mainly at the technologies that drive the client side of a web-basedapplication This is only half of the equation The website itself is normally hosted on some form ofserver platform and managed with a web server package On a Microsoft platform, the web server
is typically Microsoft’s Internet Information Services (IIS) Requests from the client are processed by
the web server, and appropriate web pages are supplied The server can also be used to processinformation supplied by the client as part of the request to provide a more interactive
experience
Trang 35CREATING A WEB APPLICATION 919
Although the range of technologies available at the client end is fairly limited, the server-side
applications can be written in any language or form supported by the web server In the case of
IIS running an ASP.NET application, the application may be written in any of the NET-supported
languages
Prior to ASP.NET, developers working in the Microsoft platform created web applications
mainly using Active Server Pages (ASP) ASPs are scripted pages that combine a variety of
tech-nologies including HTML, JavaScript, server objects, Structured Query Language (SQL), and
Visual Basic Script (VBScript) ASPs are created as plain-text files and saved with the asp file
extension ASP is powerful and flexible, but maintaining large sites can be time-consuming, and
achieving and maintaining a decent level of security can be problematic
With the introduction of ASP.NET, Microsoft gave developers a much tidier approach to
creat-ing their web applications You can use Visual Studio to create your applications, and superficially
at least, the process of building the application is not terribly different from building standard
Windows applications Much of the plumbing for connecting to back-end databases or
sophisti-cated objects (which in ASP you would have to lovingly hand-craft) is now taken care of You also
have the option to write much of the code into code-behind, where it can be safely compiled away
from prying eyes and offer the performance enhancements integral to a compiled environment
Code-behind is the familiar coding interface normally used to develop desktop applications Code
written into code-behind is compiled into a library that is kept physically distinct from the scripted
pages of the web application At the scripted end of ASP.NET, files are plain text and saved with
the aspx file extension
However, there are differences between the desktop and web development environments, and
to really take advantage of NET and fully optimize your web applications, you need to be aware
of the differences and how they can be accommodated and exploited
My favorite example of the differences between desktop and web development in Visual Studio
is in the use of fragment caching Fragment caching can be used to cache portions of an ASPX
page that are constantly reused (such as headings) This helps create a performance boost over an
equivalent page that is completely regenerated each time it is called
Another area where I have seen developers caught out while making the transition from
desk-top to web applications is in the use of view state View state is used to maintain information about
the current property state of the various controls on a page It is stored on the client’s web page in
a hidden field and thus makes the round-trip to the server Depending on the application, it can
get very big very quickly, and even fairly plain pages can suddenly start taking long periods to
download to the client if view state is not managed correctly
For the remainder of this chapter, we will discuss how to begin creating a web application in
Visual Studio 2008 and examine the available web form and HTML controls
Creating a Web Application
Developers have two project models in Visual Studio 2008 You can use either the ASP.NET Web
Application from the New Project dialog box or the New Web Site option from the File menu It is
mainly a matter of preference In the Web Application option, project resources are defined
explic-itly, and the developer has tighter control over the project It tends to suit the VB programmer
coming into web programming The New Web Site option is more flexible and tends to suit the
web programmer migrating to Visual Studio
To create a web application, open Visual Studio and select the New Project option from the File
menu From the New Project dialog box, expand the Visual Basic tree and select the Web option
From this screen, choose ASP.NET Web Application, as shown in Figure 25.5
Trang 36Figure 25.5
Choosing an ASP.NET
web application from
the New Project dialog
box
To create a new website project, open Visual Studio and select New Web Site from the Filemenu This will open the New Web Site dialog box From here, choose ASP.NET Web Site, asshown in Figure 25.6
Figure 25.6
Choosing an ASP.NET
website from the New
Web Site dialog box
After the new project is open, the main difference between the interface for building a webapplication and that used for building a standard Windows application is that the Designer forweb applications has three views: Design, Split, and Source This enables you to alternate between
a graphical view of the page and controls, an ASPX view, and a split view showing both
The contents of the Toolbox also include HTML controls You use the Standard controls mainly
to create interactive applications, while the HTML controls are essentially client-side controls thatmimic many of the traditional HTML elements such as tables and horizontal rules
You can drag and drop controls onto the page in Design view and edit properties by using thetraditional Properties window, or you can switch to Source or Split view and directly editthe code
Trang 37CREATING A WEB APPLICATION 921
You can actually do most of your coding directly onto the ASPX page in Source view This
includes not only your design elements but also your business logic However, it makes sense to
separate your business logic from your design and use code-behind by hitting F7, by choosing
View Code from the Solution Explorer, or by double-clicking the control in question
When you view your application, it will open in your default browser You may get a message
warning Debugging Not Enabled if you have used F5 or the green arrow You can choose to either
run the project without debugging or enable debugging in the Web.config file You can
either modify Web.config manually or choose to allow Visual Studio to do it for you However,
you will need to remember to disable debugging when you go to deploy your project To manually
modify Web.config, double-click the Web.config entry in Solution Explorer Web.config should
open as a page of code Under compilation, set debug =”true” as shown in the following code
snippet:
<compilation debug=”true” strict=”false” explicit=”true”>
Figure 25.7
Enabling script
debug-ging in Internet Explorer
Trang 38The Web.config file is a text file that holds many of the global settings for your website orapplication The file is automatically generated when you create a new project and it can be editedmanually or through various Visual Studio 2008 wizards You need to be careful when editing thefile because unlike HTML, the XML in the Web.config file is case sensitive Making a mistake inWeb.configcan break your whole application.
You may also need to enable script debugging in Internet Explorer From the Tools menu,choose Internet Options and click the Advanced tab Under Browsing, deselect the Disable ScriptDebugging check box, as shown in Figure 25.7
Controls
Several sets of controls are available to the developer when creating web applications These areaccessible from the traditional Toolbox and are separated into several categories These includeStandard, Data, Validation, Navigation, Login, WebParts, AJAX Extensions, Reporting, andHTML Many of these controls exhibit behavior similar to that of their desktop counterparts
Standard Controls
The Standard controls are also known as web form controls and have intrinsic server-side
func-tionality that you can program against We will explore some of these controls in more detail inChapter 26
Table 25.2 contains a list of the Standard controls and a brief description of each
Table 25.2: Standard Controls
Standard Control Description
AdRotator Randomly inserts content (advertisements) within a specified area according
to a weighted index
BulletedList Displays a bulleted list
Button Displays a command-style button to enact code back on the server
Calendar Renders a calendar with calendar-style functionality on the target page
CheckBox Displays a single check box
CheckBoxList Renders a list with check box functionality against each item
ContentPlaceHolder Used in master pages for replaceable content
DropDownList Enables creation of a drop-down list of items from which the user can make a
selection
FileUpload Creates a text box and button combination that can be used to upload a file
from the client to the server
HiddenField Creates an<input type = ‘hidden’> element that can be programmed
with server code
Trang 39CONTROLS 923
Table 25.2: Standard Controls (CONTINUED)
Standard Control Description
HyperLink Creates links for navigating internally and externally to the site
Image Places an image on a page
ImageButton Enables a graphic to be specified as a button
ImageMap Displays an image with clickable regions
Label Standard control for rendering text on a page
LinkButton Renders a button as a link Effectively creates a link that posts back to the
server and executes whatever code has been set for it
ListBox Displays a list of items that may be selected individually or in multiples by
the user
Literal Similar to the Label control in that it is used to render text to a web page,
but does so without adding any additional HTML tags
Localize Displays text in a specific area of the page — similar to the Literal control
MultiView Contains View controls and allows you to programmatically display different
RadioButton Displays a single radio button control
RadioButtonList Renders a list with radio button functionality against each item
Substitution Contains updateable cache content
Table Enables the establishment of dynamically rendered tables at runtime Should
not be used for page layout — use the HTML version of the control
TextBox Provides a data-entry field on a web page Can be set as a password box with
the contents obscured
View A panel to display a MultiView control
Wizard Creates a multipane control for creating wizards
XML Can be used to write an XML document into a web page
Trang 40Data Controls
Table 25.3 lists the controls available for data access, display, and manipulation in ASP.NET
Table 25.3: Data Controls
Data Control Description
DataList Control for displaying and interacting with data as a list
DataPager Provides paging functionality for controls such as ListView
DetailsView Renders a single record as a table and allows the user to page through
multiple records Used for master-details forms Provides ability to create,delete, and modify records
FormView Similar to DetailsView without predefined layout
GridView Displays data as a table
ListView Displays data as a list and supports create, delete, and update
functionality
Repeater For creating customized lists out of any data available to a page List
format is specified by the developer
AccessDataSource For connecting to an Access database
LinqDataSource For connecting to a Linq data source
ObjectDataSource For connecting to a business object as a data source
SiteMapDataSource For use with site navigation Retrieves navigation information from a
site-map provider
SqlDataSource For connecting to a SQL database
XmlDataSource For connecting to an XML data source
Validation Controls
Validation controls are used to establish rules for validating data entry in web forms Table 25.4lists the Validation controls available
Table 25.4: Validation Controls
Validation Control Description
CompareValidator Compares the contents of two fields — for example, when constructing a
password-creation confirmation check