- •Contents at a Glance
- •Table of Contents
- •Acknowledgments
- •Introduction
- •Who This Book Is For
- •Finding Your Best Starting Point in This Book
- •Conventions and Features in This Book
- •Conventions
- •Other Features
- •System Requirements
- •Code Samples
- •Installing the Code Samples
- •Using the Code Samples
- •Support for This Book
- •Questions and Comments
- •Beginning Programming with the Visual Studio 2008 Environment
- •Writing Your First Program
- •Using Namespaces
- •Creating a Graphical Application
- •Chapter 1 Quick Reference
- •Understanding Statements
- •Identifying Keywords
- •Using Variables
- •Naming Variables
- •Declaring Variables
- •Working with Primitive Data Types
- •Displaying Primitive Data Type Values
- •Using Arithmetic Operators
- •Operators and Types
- •Examining Arithmetic Operators
- •Controlling Precedence
- •Using Associativity to Evaluate Expressions
- •Associativity and the Assignment Operator
- •Incrementing and Decrementing Variables
- •Declaring Implicitly Typed Local Variables
- •Chapter 2 Quick Reference
- •Declaring Methods
- •Specifying the Method Declaration Syntax
- •Writing return Statements
- •Calling Methods
- •Specifying the Method Call Syntax
- •Applying Scope
- •Overloading Methods
- •Writing Methods
- •Chapter 3 Quick Reference
- •Declaring Boolean Variables
- •Using Boolean Operators
- •Understanding Equality and Relational Operators
- •Understanding Conditional Logical Operators
- •Summarizing Operator Precedence and Associativity
- •Using if Statements to Make Decisions
- •Understanding if Statement Syntax
- •Using Blocks to Group Statements
- •Cascading if Statements
- •Using switch Statements
- •Understanding switch Statement Syntax
- •Following the switch Statement Rules
- •Chapter 4 Quick Reference
- •Using Compound Assignment Operators
- •Writing while Statements
- •Writing for Statements
- •Understanding for Statement Scope
- •Writing do Statements
- •Chapter 5 Quick Reference
- •Coping with Errors
- •Trying Code and Catching Exceptions
- •Handling an Exception
- •Using Multiple catch Handlers
- •Catching Multiple Exceptions
- •Using Checked and Unchecked Integer Arithmetic
- •Writing Checked Statements
- •Writing Checked Expressions
- •Throwing Exceptions
- •Chapter 6 Quick Reference
- •The Purpose of Encapsulation
- •Controlling Accessibility
- •Working with Constructors
- •Overloading Constructors
- •Understanding static Methods and Data
- •Creating a Shared Field
- •Creating a static Field by Using the const Keyword
- •Chapter 7 Quick Reference
- •Copying Value Type Variables and Classes
- •Understanding Null Values and Nullable Types
- •Using Nullable Types
- •Understanding the Properties of Nullable Types
- •Using ref and out Parameters
- •Creating ref Parameters
- •Creating out Parameters
- •How Computer Memory Is Organized
- •Using the Stack and the Heap
- •The System.Object Class
- •Boxing
- •Unboxing
- •Casting Data Safely
- •The is Operator
- •The as Operator
- •Chapter 8 Quick Reference
- •Working with Enumerations
- •Declaring an Enumeration
- •Using an Enumeration
- •Choosing Enumeration Literal Values
- •Choosing an Enumeration’s Underlying Type
- •Working with Structures
- •Declaring a Structure
- •Understanding Structure and Class Differences
- •Declaring Structure Variables
- •Understanding Structure Initialization
- •Copying Structure Variables
- •Chapter 9 Quick Reference
- •What Is an Array?
- •Declaring Array Variables
- •Creating an Array Instance
- •Initializing Array Variables
- •Creating an Implicitly Typed Array
- •Accessing an Individual Array Element
- •Iterating Through an Array
- •Copying Arrays
- •What Are Collection Classes?
- •The ArrayList Collection Class
- •The Queue Collection Class
- •The Stack Collection Class
- •The Hashtable Collection Class
- •The SortedList Collection Class
- •Using Collection Initializers
- •Comparing Arrays and Collections
- •Using Collection Classes to Play Cards
- •Chapter 10 Quick Reference
- •Using Array Arguments
- •Declaring a params Array
- •Using params object[ ]
- •Using a params Array
- •Chapter 11 Quick Reference
- •What Is Inheritance?
- •Using Inheritance
- •Base Classes and Derived Classes
- •Calling Base Class Constructors
- •Assigning Classes
- •Declaring new Methods
- •Declaring Virtual Methods
- •Declaring override Methods
- •Understanding protected Access
- •Understanding Extension Methods
- •Chapter 12 Quick Reference
- •Understanding Interfaces
- •Interface Syntax
- •Interface Restrictions
- •Implementing an Interface
- •Referencing a Class Through Its Interface
- •Working with Multiple Interfaces
- •Abstract Classes
- •Abstract Methods
- •Sealed Classes
- •Sealed Methods
- •Implementing an Extensible Framework
- •Summarizing Keyword Combinations
- •Chapter 13 Quick Reference
- •The Life and Times of an Object
- •Writing Destructors
- •Why Use the Garbage Collector?
- •How Does the Garbage Collector Work?
- •Recommendations
- •Resource Management
- •Disposal Methods
- •Exception-Safe Disposal
- •The using Statement
- •Calling the Dispose Method from a Destructor
- •Making Code Exception-Safe
- •Chapter 14 Quick Reference
- •Implementing Encapsulation by Using Methods
- •What Are Properties?
- •Using Properties
- •Read-Only Properties
- •Write-Only Properties
- •Property Accessibility
- •Understanding the Property Restrictions
- •Declaring Interface Properties
- •Using Properties in a Windows Application
- •Generating Automatic Properties
- •Initializing Objects by Using Properties
- •Chapter 15 Quick Reference
- •What Is an Indexer?
- •An Example That Doesn’t Use Indexers
- •The Same Example Using Indexers
- •Understanding Indexer Accessors
- •Comparing Indexers and Arrays
- •Indexers in Interfaces
- •Using Indexers in a Windows Application
- •Chapter 16 Quick Reference
- •Declaring and Using Delegates
- •The Automated Factory Scenario
- •Implementing the Factory Without Using Delegates
- •Implementing the Factory by Using a Delegate
- •Using Delegates
- •Lambda Expressions and Delegates
- •Creating a Method Adapter
- •Using a Lambda Expression as an Adapter
- •The Form of Lambda Expressions
- •Declaring an Event
- •Subscribing to an Event
- •Unsubscribing from an Event
- •Raising an Event
- •Understanding WPF User Interface Events
- •Using Events
- •Chapter 17 Quick Reference
- •The Problem with objects
- •The Generics Solution
- •Generics vs. Generalized Classes
- •Generics and Constraints
- •Creating a Generic Class
- •The Theory of Binary Trees
- •Building a Binary Tree Class by Using Generics
- •Creating a Generic Method
- •Chapter 18 Quick Reference
- •Enumerating the Elements in a Collection
- •Manually Implementing an Enumerator
- •Implementing the IEnumerable Interface
- •Implementing an Enumerator by Using an Iterator
- •A Simple Iterator
- •Chapter 19 Quick Reference
- •What Is Language Integrated Query (LINQ)?
- •Using LINQ in a C# Application
- •Selecting Data
- •Filtering Data
- •Ordering, Grouping, and Aggregating Data
- •Joining Data
- •Using Query Operators
- •Querying Data in Tree<TItem> Objects
- •LINQ and Deferred Evaluation
- •Chapter 20 Quick Reference
- •Understanding Operators
- •Operator Constraints
- •Overloaded Operators
- •Creating Symmetric Operators
- •Understanding Compound Assignment
- •Declaring Increment and Decrement Operators
- •Implementing an Operator
- •Understanding Conversion Operators
- •Providing Built-In Conversions
- •Creating Symmetric Operators, Revisited
- •Adding an Implicit Conversion Operator
- •Chapter 21 Quick Reference
- •Creating a WPF Application
- •Creating a Windows Presentation Foundation Application
- •Adding Controls to the Form
- •Using WPF Controls
- •Changing Properties Dynamically
- •Handling Events in a WPF Form
- •Processing Events in Windows Forms
- •Chapter 22 Quick Reference
- •Menu Guidelines and Style
- •Menus and Menu Events
- •Creating a Menu
- •Handling Menu Events
- •Shortcut Menus
- •Creating Shortcut Menus
- •Windows Common Dialog Boxes
- •Using the SaveFileDialog Class
- •Chapter 23 Quick Reference
- •Validating Data
- •Strategies for Validating User Input
- •An Example—Customer Information Maintenance
- •Performing Validation by Using Data Binding
- •Changing the Point at Which Validation Occurs
- •Chapter 24 Quick Reference
- •Querying a Database by Using ADO.NET
- •The Northwind Database
- •Creating the Database
- •Using ADO.NET to Query Order Information
- •Querying a Database by Using DLINQ
- •Creating and Running a DLINQ Query
- •Deferred and Immediate Fetching
- •Joining Tables and Creating Relationships
- •Deferred and Immediate Fetching Revisited
- •Using DLINQ to Query Order Information
- •Chapter 25 Quick Reference
- •Using Data Binding with DLINQ
- •Using DLINQ to Modify Data
- •Updating Existing Data
- •Adding and Deleting Data
- •Chapter 26 Quick Reference
- •Understanding the Internet as an Infrastructure
- •Understanding Web Server Requests and Responses
- •Managing State
- •Understanding ASP.NET
- •Creating Web Applications with ASP.NET
- •Building an ASP.NET Application
- •Understanding Server Controls
- •Creating and Using a Theme
- •Chapter 27 Quick Reference
- •Comparing Server and Client Validations
- •Validating Data at the Web Server
- •Validating Data in the Web Browser
- •Implementing Client Validation
- •Chapter 28 Quick Reference
- •Managing Security
- •Understanding Forms-Based Security
- •Implementing Forms-Based Security
- •Querying and Displaying Data
- •Understanding the Web Forms GridView Control
- •Displaying Customer and Order History Information
- •Paging Data
- •Editing Data
- •Updating Rows Through a GridView Control
- •Navigating Between Forms
- •Chapter 29 Quick Reference
- •What Is a Web Service?
- •The Role of SOAP
- •What Is the Web Services Description Language?
- •Nonfunctional Requirements of Web Services
- •The Role of Windows Communication Foundation
- •Building a Web Service
- •Creating the ProductsService Web Service
- •Web Services, Clients, and Proxies
- •Talking SOAP: The Easy Way
- •Consuming the ProductsService Web Service
- •Chapter 30 Quick Reference
614 |
Part VI Building Web Applications |
|
|
The form currently performs no validation. If you blank out the data in the Company column |
|
|
for a customer and then click Update, the LINQ data source generates a SQL exception be- |
|
|
cause this column does not allow null values in the database. The message that is displayed is |
|
|
not very user-friendly (although a developer will find it very useful). If a Web form generates |
|
|
an exception, you can arrange for a more friendly message to be displayed by redirecting the |
|
|
user to another page. Set the ErrorPage attribute to the @Page directive in the form’s source |
|
|
definition to redirect the user when errors occur: |
|
|
<%@ Page ... |
ErrorPage=”ErrorPage.aspx” %> |
You can display a more comforting message to the user on this page. Additionally, you can validate the data before sending it to the database by handling the Updating
event in the LINQ data source object. The event handler for this method takes a LinqDataSourceUpdateEventArgs parameter that contains the original values and the new
values for the row. Your code can scrutinize the new values, and if they are invalid, your code can set the Cancel property of the LinqDataSourceUpdateEventArgs parameter to false to
indicate that the data source should not attempt to update the database.
Also, notice that the database is updated as soon as the user clicks the Update button. This is the default functionality implemented by a GridView control that is bound to a LINQ data
source and is probably the most suitable mechanism for building interactive Web forms. If you want to modify the update behavior (for example, so that the GridView control will store
multiple updates locally and then submit them as a single batch), you can implement your own custom mechanism. However, the details for doing this are outside the scope of this book.
Navigating Between Forms
A key aspect of many Web Forms applications is the ability to navigate from one form to
another by clicking a hyperlink or button. In addition, you often need to pass information between forms. In the CustomerData Web form, it would be useful to be able to click a cus-
tomer and display another form showing the order history for that customer. This is what you will do in the exercises in this section.
In this section, you will create a new Web form for displaying order history information. You will use a GridView control to display the data, but you will populate the data by executing a
SQL Server stored procedure rather than querying a table. The Northwind database contains a stored procedure called CustOrderHist. This stored procedure takes a customer ID as a pa-
rameter and returns a result set containing the name and quantity of each product the cus-
tomer has ordered. When the user selects a customer in the CustomerData Web form, you must pass the value in the CustomerID column to this new form.
Chapter 29 Protecting a Web Site and Accessing Data with Web Forms |
615 |
The first step, therefore, is to modify the CustomerData Web form to enable the user to select a customer.
Modify the CustomerData Web form
1.Return to the Code and Text Editor window displaying the HTML source code for the CustomerData Web form.
2.Change the definition of the boundfield element displaying the customer ID to a HyperLinkField, as shown here in bold type:
<asp:HyperLinkField DataField=”CustomerID” ...></asp:HyperLinkField>
The data in this column in the GridView control will be displayed as a hyperlink rather than as a label. The user can click this hyperlink. The following steps set properties that specify the actions that occur when this happens.
3.Change the DataField property of the control to a DataTextField property, as shown in bold type here:
<asp:HyperLinkField DataTextField=”CustomerID” ...></asp:HyperLinkField>
The HyperLinkField control does not have a DataField property. The DataTextField specifies the property from the data source to which the hyperlink binds.
4.Remove the ReadOnly property of the control, and add the Target,
DataNavigateUrlFields, and DataNavigateUrlFormatString properties shown in bold type here:
<asp:HyperLinkField DataTextField=”CustomerID” HeaderText=”Customer ID”
Target=”_self” DataNavigateUrlFields=”CustomerID” DataNavigateUrlFormatString=”~\OrderHistory.aspx?CustomerID={0}”
SortExpression=”CustomerID”>
</asp:HyperLinkField>
The DataNavigateUrlFormatString property specifies the address to which the Web application should move when the user clicks the hyperlink. In this example, the application navigates to the OrderHistory.aspx form (which you will create in the next exercise)
and includes a query string parameter containing a customer ID. This query string currently contains a placeholder. The DataNavigateUrlFields property determines the value that should be used for this placeholder—the data in the CustomerID field for the current row in the GridView control. The Target property specifies where the OrderHistory.
aspx Web form should be displayed. The value _self causes ASP.NET to reuse the same Internet Explorer window that is currently displaying the CustomerData form.
Note ASP.NET also provides the HyperLink control in the Standard category in the Toolbox. When using this control, you can specify a URL to move to in its NavigateUrl property. In addition, you can execute the Transfer method of the Server property of a
Web form if you want to transfer control from one Web form to another programmatically.
616 Part VI Building Web Applications
The next task is to create a data source that executes the CustOrderHist stored procedure in
the database. In the final exercise in this chapter, you will see how to invoke the stored procedure by using the data source and pass the CustomerID parameter required by this stored
procedure.
Create a data source for retrieving customer order history information
1.On the Website menu, click Add New Item.
2.In the Add New Item dialog box, click the LINQ to SQL Classes template, type
OrderHistory.dbml in the Name text box, select Visual C# in the Language drop-down list, and then click Add.
3.In the Microsoft Visual Studio message box, click Yes to place the Linq to SQL file in the App_Code folder.
4.In Server Explorer (Visual Studio 2008) or Database Explorer (Visual Web Developer
2008 Express Edition), expand the data connection for the Northwind database (YourComputer\sqlexpress.Northwind.dbo or Northwind.mdf), and then expand Stored Procedures.
5.Click the CustOrderHist stored procedure, and drag it onto the Object Relational Designer window.
The stored procedure is added at the top of the right-hand pane of the Object Relational Designer window.
6.On the File menu, click Save All.
You can now construct the OrderHistory Web form that displays the order history for a customer using this data source.
Create the OrderHistory Web form
1.Display the CustomerData.aspx form in the Design View window. On the Website menu, click Add New Item.
2.In the Add New Item dialog box , ensure that the Web Form template is selected, and type OrderHistory.aspx for the name. Verify that the Language drop-down list box is set to Visual C#, the Place code in separate file box is selected, and the Select master page box is cleared, and then click Add to create the form.
Note If the Add New Item dialog box does not display the Web Form template, make sure that you have displayed the CustomerData.aspx form rather than the Object Relational Designer in the Design View window.
3. Click the Design button to display OrderHistory.aspx in the Design View window.
Chapter 29 Protecting a Web Site and Accessing Data with Web Forms |
617 |
4.In the Properties window, set the Title property of the DOCUMENT object to Northwind Traders – Orders for:.
5.From the Standard category in the Toolbox, add a Label control and a HyperLink control to the Web form.
6.Using the Properties window, set the properties for the Label and HyperLink controls to the values shown in the following table.
Control |
Property |
Value |
Label1 |
ID |
OrderLabel |
|
|
|
|
Font-Name (expand the Font |
Arial Black |
|
property and select Name) |
|
|
|
|
|
Font-Size (in the Font property, |
X-Large |
|
select Size) |
|
|
|
|
|
Text |
Order History for: |
|
|
|
HyperLink1 |
Text |
Return to Customers |
|
NavigateUrl |
~/CustomerData.aspx |
|
|
|
7.In the Data category of the Toolbox, click the GridView control and drag it onto the form. A GridView is added to the form and displays placeholder data.
8.Using the Properties window, set the (ID) property for the GridView control to
OrderGrid.
9.In the Design View window, click the OrderGrid control, and then click the smart tag to display the Common GridView Tasks menu.
10.On the Common GridView Tasks menu, click the Auto Format link.
11.In the AutoFormat dialog box, select the Classic scheme, and then click OK.
In this form, you are going to write code to bind the GridView control to the data source. You will define the columns in the GridView control manually.
12.On the Common GridView Tasks menu, click the Edit Columns link.
13.In the Fields dialog box, in the Available Fields list box, click BoundField, and then click
Add.
14.In the BoundField properties list box, set the HeaderText property to Product Name.
15.In the Available Fields list box, click BoundField, and then click Add again.
16.In the BoundField properties list box, set the HeaderText property of the new column to Total, and set the DataFormatString property to {0:N0}. (Both the 0 characters are zeros—this format displays the data as a number with no decimal places.) Expand the
618 Part VI Building Web Applications
ItemStyle property, and then set the HorizontalAlign property to Right (by convention, numeric data is displayed right-justified).
17.Clear the Auto-generate fields check box, and then click OK.
18.Click the Source button, and modify the body element to lay out the controls on the form underneath one another, with some blank lines between them, as shown in bold type here:
<body>
<form id=”form1” runat=”server”> <div>
<asp:Label ID=”OrderLabel” ...></asp:Label>
<br /> <br />
<asp:HyperLink ID=”HyperLink1” ...></asp:HyperLink>
<br /> <br />
<asp:GridView ID=”OrderGrid” ... >
...
</asp:GridView>
</div>
</form>
</body>
The final task is to write some code that displays the customer ID on the form, bind the GridView control and its columns to the OrderHistory data source, and then display the data.
Write code to bind the GridView control to the data source
1.In Solution Explorer, expand OrderHistory.aspx, and then double-click OrderHistory. aspx.cs to display the C# code for the OrderHistory form in the Code and Text Editor window.
2.In the Page_Load method, add the statement shown here in bold type:
protected void Page_Load(object sender, EventArgs e)
{
string customerId = Request.QueryString[“CustomerID”];
}
Remember that the OrderHistory form is invoked from the CustomerData form when the user clicks the hyperlink control for one of the customers displayed in the GridView
control on that form. The hyperlink control specifies a URL with a query string that
contains the selected customer ID. For example, if the user clicks the customer with the ID “ALFKI,” the hyperlink opens the OrderHistory form with the query string value pair “CustomerID=ALFKI”. The Request object of a Web form is a collection of the query
string value pairs passed in to the form. You can access the values either by number or
by name. The code you have just written retrieves the value of the pair with the name CustomerID from the Request object and stores it in a local string variable.
Chapter 29 Protecting a Web Site and Accessing Data with Web Forms |
619 |
3. Add the code shown here in bold type to the Page_Load method:
protected void Page_Load(object sender, EventArgs e)
{
string customerId = Request.QueryString[“CustomerID”]; this.OrderLabel.Text += “ “ + customerId;
this.Title += “ “ + customerId;
}
These statements append the customer ID to the text displayed on the form and in the title of the form.
4. Add the following statements to the Page_Load method:
protected void Page_Load(object sender, EventArgs e)
{
...
OrderHistoryDataContext context = new OrderHistoryDataContext(); var orderDetails = context.CustOrderHist(customerId); this.OrderGrid.DataSource = orderDetails;
}
This code creates a new DataContext object using the OrderHistoryDataContext class. The OrderHistoryDataContext class was generated by the Object Relational Designer when you created a new data source based on the CustOrderHist stored procedure. When you add a stored procedure to a DataContext type, the code generated by the Object Relational Designer exposes the stored procedure by providing a method
with the same name. The second statement in the preceding code example calls the CustOrderHist method, which in turn invokes the CustOrderHist stored procedure in the Northwind database. The customerId variable is passed in as the parameter. The result set generated by this stored procedure is used as the data source for the OrderGrid
control.
5. Append the code shown here to the end of the Page_Load method:
protected void Page_Load(object sender, EventArgs e)
{
...
BoundField productName = this.OrderGrid.Columns[0] as BoundField; productName.DataField = “ProductName”;
BoundField total = this.OrderGrid.Columns[1] as BoundField; total.DataField = “Total”;
this.OrderGrid.DataBind();
}
This block of code binds the two columns in the OrderGrid control to the correspond-
ing properties in the data source. Notice that you specify the properties by name, as a string. The DataBind method of the OrderGrid control causes the data source to run the
stored procedure and generate the result set, displaying the results in the columns in the grid.
620 |
Part VI Building Web Applications |
Test the completed application
1.Run the application, and log in as John.
2.On the CustomersData Web form, notice that the values in the Customer ID column are now displayed as hyperlinks:
3.Click the hyperlink for the first customer, ALFKI. The OrderHistory form should appear, displaying the order history for ALFKI.
