However, the key class with which you will work is the XElement class, which provides the ability to easily create XML elements, load them from files, query against them, and write them
Trang 2xmlWriter.WriteElementString("HireDate",
XmlConvert.ToString(DateTime.Parse("1/1/2003"),
XmlDateTimeSerializationMode.Unspecified));
Trang 3
This code starts by opening the file as part of the constructor for the XmlTextWriter The
constructor also expects an encoding type Because an argument is required, passing Nothing
causes the encoding type to be UTF-8, which is the same as the value that is explicitly being
Trang 4The XmlTextWriter handles the formatting of the document by setting the Formatting and
Indentation properties.
The WriteStartDocument method writes the XML declaration to the file The WriteComment
method writes a comment to the file
When writing elements, you can use either the WriteStartElement method or the
Write-ElementString method The WriteStartElement method only writes the starting element but
keeps track of the nesting level and adds new elements inside this element The element is
completed when a call is made to the WriteEndElement method The WriteElementString
method simply writes a closed element to the file
The WriteAttribute method takes a name and value pair and writes the attribute into the
current open element
When writing is complete, the Close method must be called to avoid losing data The file is
then saved
Trang 5Reading a File Using the xmlTextReader
The XmlTextReader is used to read an XML file node by node The reader provides
forward-only, noncaching access to an XML data stream The reader is ideal for use when there is a
possibility that the information that is desired is near the top of the XML file and the file is
large If random access is required, use the XPathNavigator class or the XmlDocument class
The following code reads the XML file that was created in the previous example and displays
information about each node:
'VB
Protected Sub Button11_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button11.Click
Trang 7This code opens the EmployeeList file, and then performs a simple loop, reading one
ele-ment at a time until finished For each node that is read, a check is made on the NodeType,
and the node information is printed When a node is read, its corresponding attributes are
read as well A check is made to see if the node has attributes, and they are displayed
Modifying an XML Document
Once the XmlDocument object is loaded, you can easily add and remove nodes When
removing a node, you simply need to locate the node and delete it from its parent When
adding a node, you need to create the node, search for the appropriate location into which to
insert the node, and insert the node The following code deletes an existing node and adds a
new node:
'VB
Protected Sub Button12_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button12.Click
lbl = GetLabel(275, 20)
'Declare and load new XmlDocument
Dim xmlDoc As New XmlDocument()
'create a node and add it
Dim newElement as XmlElement = _
//Declare and load new XmlDocument
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(MapPath("XmlSample.xml"));
Trang 8or schema Earlier versions of the NET Framework used the XmlValidatingReader object to
perform validation, but this object is now obsolete Instead, this section explores XML
docu-ment validation using the XmlReader class
The XmlReader class performs forward-only reading and validation of a stream of XML The XmlReader class contains a Create method that can be passed as a string or a stream,
as well as an XmlReaderSettings object To perform validation, the XmlReaderSettings object
must be created and its properties set to perform validation In the next example, the files XmlSample.xml and XmlBadSample.xml are validated using the following code:
'VB
Protected Sub Button13_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button13.Click
Trang 9Protected Sub Button14_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button14.Click
Trang 10lbl = GetLabel(275, 20);
if (ValidateDocument(MapPath("XmlBadSample.xml"))) {
lbl.Text += "Valid Document<br />";
<!ELEMENT myRoot ANY>
<!ELEMENT myChild ANY>
<!ELEMENT myGrandChild EMPTY>
Trang 11This code simply opens the XML fi le with an XmlReader, and, while the XmlDocument is
being read, the document is being validated Because this code has an embedded DTD, the
document is validated
The DTD states that the myGrandChild element must be empty, but one of the
myGrand-Child elements of mymyGrand-Child ref-1 has a myGrandmyGrand-Child element containing the words, this is
malformed This causes an error Attempts to read from the XmlReader when valid should
always be within a Try-Catch block to catch possible validation exceptions
Quick check
1 What method can you execute to locate a single XML node by its tag name?
2 What method can you use to search for all elements that have a specifi c tag
name and retrieve the results as an xmlnodeList?
3 What object should you use to perform XPath queries on large XML documents?
Quick check answers
1 You can execute SelectSinglenode
2 You can use getelementsByTagname or Selectnodes
3 You should use xPathnavigator
Quick check
1 What method can you execute to locate a single XML node by its tag name?
2 What method can you use to search for all elements that have a specifi c tag
name and retrieve the results as an xmlnodeList?
3 What object should you use to perform XPath queries on large XML documents?
Quick check answers
1 You can execute SelectSinglenode
2 You can use getelementsByTagname or Selectnodes
3 You should use xPathnavigator xPathnavigator xPathnavigator
Trang 12Using LINQ to XML
Another way to work with XML in the NET Framework is through the LINQ to XML classes
found inside the System.Xml.Linq namespace These classes provide an easier, faster, and
richer experience when working with XML data In addition, they leverage LINQ to ensure a consistent query model when searching for data embedded in XML With LINQ to XML, you can do everything you’ve seen thus far, including loading XML from a file, serializing it to streams and files, querying against it, validating, manipulating it in memory, and much more
In fact, many of the LINQ to XML classes use the other objects discussed previously as their
internal means of working with data (such as the XmlReader class used to read XML).
The LINQ to XML Classes
The LINQ to XML classes are accessible through the System.Xml.Linq namespace There are many classes here However, the key class with which you will work is the XElement class,
which provides the ability to easily create XML elements, load them from files, query against them, and write them back out or send them across the wire Figure 7-19 shows a high-level
view of the objects that are defined inside the Xml.Linq namespace.
figure 7-19 The classes of LINQ to XML (System.Xml.Linq namespace)
The sections that follow provide an overview of working with XElement However, it is
im-portant to have an understanding of the other classes that make up LINQ to XML Table 7-6 presents the classes shown in Figure 7-19 and provides a description of each
Trang 13tabLe 7-6 The LINQ to XML Classes Inside the System.Xml.Linq Namespace
XAttribute Represents a class for working with XML attributes You can
create a new instance of this class that includes a name and
value You can use the XAttribute class to add attributes to
an XElement
The XAttribute class is also used for functional XML
pro-gramming (described later) when defining trees
XCData Represents a CDATA string section of an XML element or
document This class derives from XText.
XComment Represents a comment in an XML structure The XComment
class can be a child of an XElement or a sibling of the root node in an XDocument.
XContainer Represents the base class for XElement and XDocument
XDeclaration Represents an XML declaration including XML version and
encoding information
XDocument Represents a valid XML document This class contains the
full document Many times you only need to work with
elements of a document In this case, the XElement is the preferred class The XDocument exists for when you need to
work with an entire structure of an XML document ing elements, comments, declarations, and so on)
(includ-XDocumentType Represents an XML DTD used for validating XML trees and
supplying default attributes
XElement Represents an XML element This is the core class of LINQ to
XML You can use this class to declare, load, and work with portions of an XML structure
XName Represents names of elements and attributes
XNamespace Represents a namespace for XElement or XAttribute
Namespaces are part of XName.
XNode Represents the nodes of an XML tree This is a base class for
XText, XContainer, XComment, XProcessingInstruction, and XDocumentType.
XNodeDocumentOrder-Compare
Represents features used to compare nodes for document order
XNodeEqualityComparer Represents features used to compare nodes for equality
XObject Represents a base class used by XNode and XAttribute
Pro-vides base event functionality for these classes
Trang 14cLass descriptiOn
XObjectChange Represents the event type for events raised by classes that
use XObject.
XObjectChangeEventArgs Represents the data for the Changing and Changed events.
XProcessingInstruction Represents an XML processing instruction
XText Represents a text node in XML
Loading an XML Tree
To work with LINQ to XML, you need to get XML into memory This means loading (or
pars-ing) it from a file, string, or XmlReader You parse XML data into an XElement (or XDocument)
As an example, if you have a file that contains employee data, you can read that file by calling
the Load method of XElement The following code shows this feature Notice the call to Server.
MapPath to get the path to the Employee.xml file stored in the root of the Web site.
'VB
Dim xmlFile As String = Server.MapPath("/DataSamples") & "\employee.xml"
Dim employees As XElement = XElement.Load(xmlFile)
//C#
string xmlFile = Server.MapPath(@"/DataSamples") + @"\employee.xml";
XElement employees = XElement.Load(xmlFile);
The XElement class also contains the Parse method, which is used to load XML from a string You simply pass the string as a parameter to the static Parse method This is great if
your XML is already in a string However, if you are defining XML in your code, you should do
so functionally and not as a string, as using the functional approach is faster This is discussed
further in the section “Creating an XML Tree with XElement” later in this lesson.
Writing LINQ Queries Against XML Trees
The queries you write with LINQ to XML can be seen as similar to XPath and XQuery
Howev-er, they use the standard LINQ notation This ensures a single, consistent query model across different types of data You write LINQ to XML queries in a similar way as querying against
a DataSet This is because the XML data, like the DataSet, is an in-memory store In addition,
there is not an O/R map as in LINQ to SQL
As an example, suppose you have an XML file that contains employees The XML file might look like this:
Trang 15Suppose you need to write a query against this XML that returns all employees whose
salary is greater than 20 You would start by first loading the XML into memory as an
XEle-ment instance You could then define a LINQ query against the XEleXEle-ment to return employee
elements that contain a Salary element with a value greater than 20 The following code
demonstrates this query and writes the results out to a Web page:
'VB
Dim xmlFile As String = Server.MapPath("/DataSamples") & "\employee.xml"
Dim employees As XElement = XElement.Load(xmlFile)
Dim query As IEnumerable(Of XElement) = _
From emp In employees.<Employee> _
Where CType(emp.Element("Salary"), Integer) > 20 _
Select emp
For Each emp As XElement In query
Trang 16Response.Write(emp.Element("Salary").ToString() & "<br /><br />")
Next
//C#
string xmlFile = Server.MapPath(@"/DataSamples") + @"\employee.xml";
XElement employees = XElement.Load(xmlFile);
Creating an XML Tree with xelement
LINQ to XML also adds the ability to functionally define XML in your code This means
creat-ing an XML XElement object tree in code (and not just as a parsed strcreat-ing) This can make your
code easier to read and easier to write In fact, Visual Basic developers can actually write the XML as angle-bracketed items with intelligent coloring in the IDE C# developers, on the other hand, still have to call object constructors However, they also have an easy way to build XML trees in code
As an example, suppose you wish to define an XElement that represents a list of
employ-ees You might also want to define a few child elements that represent actual employees and
their data You could do so by simply nesting calls to the new XElement constructor, which
takes a parameter array as a value For Visual Basic developers, this is abstracted further and you can simply write XML in your code The following shows an example:
Trang 17new XElement("Employees",
new XElement("Employee",
new XElement("id", "MFS52347M"),
new XElement("FirstName", "Martin"),
new XElement("LastName", "Sommer"),
new XElement("Salary", 15)
)
);
To add further power to defining XML, you can also embed queries as one of the
param-eters to building XElements The result of these queries will get added to the XML stream
For example, consider the previous employees definition Suppose you wish to add all the
employees from the Employee.xml file to this list You could do so in the XElement definition
by adding a query at the end of the first employee definition The following code shows an
example Notice the statement from emp in empFile.Elements(); this is the call to the query
'VB
Dim xmlFile As String = Server.MapPath("/DataSamples") & "\employee.xml"
Dim empFile As XElement = XElement.Load(xmlFile)
Dim employees As XElement = _
string xmlFile = Server.MapPath(@"/DataSamples") + @"\employee.xml";
XElement empFile = XElement.Load(xmlFile);
XElement employees =
new XElement("Employees",
new XElement("Employee",
Trang 18new XElement("FirstName", "Martin"),
new XElement("LastName", "Sommer"),
Lab Working with XmL data
In this lab, you work with XML data to display a subset of an XML fi le in a GridView control, using the XmlDataSource and an XSLT fi le
If you encounter a problem completing an exercise, the completed projects are available in the samples installed from the companion CD in the Code folder
ExErcisE 1 Create the Web Site and the XML Files
In this exercise, you create the Web site and XML fi le
1 Open Visual Studio; create a new Web site called Xmldata using your preferred
<Product Id="7D67A" Department="Clothing" Name="Shirt" Price="12.00" />
<Product Id="4T21N" Department="Clothing" Name="Jacket" Price="45.00" />
<Product Id="7D67A" Department="Clothing" Name="Shirt" Price="12.00" />
<Product Id="4T21N" Department="Clothing" Name="Jacket" Price="45.00" />
</ProductList>
Trang 194 Open the Default.aspx page In Design view, drag a DetailsView control onto the page
and size it wide enough to display the car information
5 Click the smart tag in the upper right corner of the DetailsView control to display the
DetailsView Tasks window
Click the Auto Format link and select Professional
6 Click the Choose Data Source drop-down list and select New Data Source to start
the Data Source Confi guration Wizard For the data source type, select XML File and
click OK
7 On the Confi gure Data Source page, click Browse next to the Data File text box and
browse to the ProductList.xml fi le in the App_Data folder
n XML documents can be accessed using the DOM
n The XPathNavigator uses a cursor model and XPath queries to provide read-only,
ran-dom access to the data
n The XmlReader provides an object for validating against DTD, XDR, or XSD by setting
the XmlReaderSettings object properties
n LINQ to XML uses the XElement class to load XML data, write LINQ queries against it,
and write the data back if need be You can also functionally defi ne XML in your code
using LINQ to XML
Lesson Review
You can use the following questions to test your knowledge of the information in Lesson 3,
“Working with XML Data.” The questions are also available on the companion CD if you prefer
to review them in electronic form
NOTE ansWers
Answers to these questions and explanations of why each answer choice is right or wrong
are located in the “Answers” section at the end of the book
Answers to these questions and explanations of why each answer choice is right or wrong
are located in the “Answers” section at the end of the book
Trang 201 Which class can be used to create an XML document from scratch?
a. XmlConvert
b. XmlDocument
c. XmlNew
d. XmlSettings
2 Which class can be used to perform data type conversion between NET Framework
data types and XML types?
a. XmlType
b. XmlCast
c. XmlConvert
d. XmlSettings
3 You are writing a function that accepts a string as a parameter The string data will be
sent to the function in the form of XML You need to write LINQ to XML code to query this XML and process it What steps should you take? (Choose all that apply.)
a. Use the XElement.Load method to load the XML data into a new XElement.
b Use the XElement.Parse method to load the XML data into a new XElement.
c Define a query variable of type IEnumerable<> where the generic type is set to
XElement.
d Define a query variable of type IEnumerable<> where the generic type is set to the
value of the string parameter passed to the function
Trang 21chapter review
To further practice and reinforce the skills you learned in this chapter, you can perform the
following tasks:
n Review the chapter summary
n Complete the case scenarios These scenarios set up real-world situations involving the
topics of this chapter and ask you to create solutions
n Complete the suggested practices
n Take a practice test
Chapter Summary
n ADO.NET provides disconnected objects like the DataTable and DataSet that can be
used independently from a database connection In addition, LINQ to DataSet provides
a query processing engine for data represented in the disconnected objects DataSet
and DataTable.
n ADO.NET provides connected objects that are provider-specific for SQL, Oracle,
OLEDB, and ODBC In addition, LINQ to SQL provides a powerful set of features for
programming against SQL Server databases with O/R mapping
n ADO.NET provides access to XML files using the classes in the System.Xml namespace
The LINQ to XML technology allows you to work with XML data using the query
fea-tures of LINQ
Case Scenarios
In the following case scenarios, you will apply what you’ve learned in this chapter If you have
difficulty completing this work, review the material in this chapter before beginning the next
chapter You can find answers to these questions in the “Answers” section at the end of this
book
Case Scenario 1: Determining Ways to Update the Database
You are creating a new Web page that allows users to upload expense reports (as XML data)
The expense report data contains general information about the expense report, such as the
employee name and ID, the branch office number, and the week-ending date The expense
report file also contains information that describes each specific expense For mileage, this
data includes the date and the mileage amount, and the to and from locations For
ment, the data includes the location, the expense amount, and a description of the
entertain-ment expense
You need to import this data into a SQL database and are looking for options
Trang 221 What are some methods of importing this data into the SQL Server database?
Case Scenario 2: Storing a DataSet to a Binary File
Your code populates a DataSet with more than 200,000 DataRows in several related
DataT-ables You want to store this DataSet object to a file, but you want the file to be as small as
possible
QUESTIONS
1 What object would you use to store the data?
2 What settings would you set to serialize the data properly?
suggested practices
To help you successfully master the exam objectives presented in this chapter, complete the following tasks
Create a Web Page for Updating Database Data
For this task, you should complete all three practices
n practice 1 Create a Web page and add Web server controls to prompt the user for a percentage increase (or decrease) for the price of the products in your database Use
the Northwind database, which has a Products table.
n practice 2 Add code to open a connection to the database and execute a SQL query
to increase or decrease the UnitPrice of all products based on the value submitted by the user
n practice 3 Add code to perform the update of the Products table within a
SqlTransac-tion.
Create a Web Page for Editing Disconnected Data
For this task, you should complete the first practice for working with the DataTable objects The second practice helps you with LINQ to DataSet.
n practice 1 Create a Web page and add a button to create a DataTable that contains a schema for employees, a button that adds a DataRow into the employees DataTable, a button that modifies an existing DataRow, and a button that deletes a DataRow.
Trang 23n practice 2 Read the employee data from the pubs database into a DataTable object
and disconnect from the database Write a LINQ to DataSet query against the
Data-Table to show all employee records where the hire date is greater than 1991 Order the
data by hire date Bind the results to a GridView control
Create a Web Page for Editing Connected Data
For this task, you should complete both practices
n practice 1 Create a Web page and add a SqlDataSource configured to read data from
a SQL Server or SQL Server Express Edition database and display the data in a GridView
control
n practice 2 Modify the Web page to enable inserts, updates, and deletions
Create a Web Page for Working with XML Data
For this task, you should complete the first two practices for working with the standard XML
classes The third practice can be used for learning more about LINQ to XML
n practice 1 Create a Web page that uses an XmlDataSource to read data from an XML
file and display the data in a GridView control.
n practice 2 Modify the Web page to enable inserts, updates, and deletions
n practice 3 Create an XML file using one of the tables in the Pubs database as source
data You can read this data in as a DataSet and serialize it out as XML Write a Web
page to load this XML data into an XElement class Write a LINQ query against this data
and display the results on a Web page
Create a Web Page for Reading, Modifying, and Writing
XML Data
For this task, you should complete all three practices
n practice 1 Create an XML file that contains a list of products and their prices
n practice 2 Create a Web page and add Web server controls to prompt the user for a
percentage increase (or decrease) for the price of the products in your XML file
n practice 3 Add code to use the XmlReader to read the products file, modify the price,
and then use the XmlWriter to write the data to a file.
Trang 24take a practice test
The practice tests on this book’s companion CD offer many options For example, you can test yourself on just the content covered in this chapter, or you can test yourself on all the 70-562 certifi cation exam content You can set up the test so it closely simulates the experience of taking a certifi cation exam, or you can set it up in study mode so you can look at the correct answers and explanations after you answer each question
MORE INFO practice tests
For details about all the practice test options available, see the “How to Use the Practice Tests” section in this book’s Introduction
MORE INFO practice tests
For details about all the practice test options available, see the “How to Use the Practice Tests” section in this book’s Introduction.
Trang 26before you begin
To complete the lessons in this chapter, you should be familiar with developing applications with Microsoft Visual Studio using Visual Basic or C# In addition, you should be comfortable with all of the following:
n The Visual Studio 2008 Integrated Development Environment (IDE)
n A basic understanding of Hypertext Markup Language (HTML) and client-side scripting
n How to create a new Web site
n Adding Web server controls to a Web page
n Working with ADO.NET, XML, and LINQ
on solving business problems rather than building frameworks and reusable ponents Applications that can benefi t from this approach often have a common profi le: They typically have a compressed schedule, are meant as Web applications from beginning to end, and might fi ll a somewhat temporary need When optimiz- ing for these considerations, you might fi nd that building data-bound applications using the server controls in ASP.NET is faster, easier, and cheaper.
on solving business problems rather than building frameworks and reusable ponents Applications that can benefi t from this approach often have a common profi le: They typically have a compressed schedule, are meant as Web applications from beginning to end, and might fi ll a somewhat temporary need When optimiz- ing for these considerations, you might fi nd that building data-bound applications using the server controls in ASP.NET is faster, easier, and cheaper.
Trang 27com-Lesson 1: connecting to data with data source
controls
In the previous chapter, you saw how to write code that leverages the features of ADO.NET
to connect and work with data that was disconnected or stored in an XML fi le or a database
This code is useful when writing database code to build an abstracted layer such as a data
access or business object tier However, there are many scenarios in which you simply need to
build Web pages that know how to connect and work with data, without writing all the ADO
NET code For these scenarios, ASP.NET includes the data source controls
Data source controls are server controls that you can drag onto your page at design time
They do not have a direct visual component (you use data-bound controls for this, as
dis-cussed in the next lesson) Instead, they allow you to declaratively defi ne access to data found
in objects, XML, and databases This lesson examines how you can use data source controls to
make connecting to and working with data in an ASP.NET page a faster and easier
develop-ment process
After this lesson, you will be able to:
n Use the data source controls (LinqDataSource, ObjectDataSource, SqlDataSource,
AccessDataSource, XmlDataSource, and SiteMapDataSource) to select data and
bind it to a data-bound control
n Pass parameter values to data source controls to allow data fi ltering
n Enable data sorting with data source controls
n Modify data and save the changes to a data store using data source controls
Estimated lesson time: 30 minutes
Understanding the Data Source Controls
The data source controls in ASP.NET manage the tasks of selecting, updating, inserting, and
deleting data on a Web page They do so in combination with bound controls The
data-bound controls provide the user interface (UI) elements that allow a user to interact with the
data by triggering events that call the data source controls
There are multiple data source controls in ASP.NET Each is meant to provide specialized
access to a certain type of data such as direct access to a database, objects, XML, or
LINQ-based queries These controls can be found in the System.Web.UI.WebControls namespace
Figure 8-1 shows an overview of the data source controls in ASP.NET
After this lesson, you will be able to:
n Use the data source controls (LinqDataSource, ObjectDataSource, SqlDataSource,
AccessDataSource, XmlDataSource, and SiteMapDataSource) to select data and
bind it to a data-bound control
n Pass parameter values to data source controls to allow data fi ltering
n Enable data sorting with data source controls
n Modify data and save the changes to a data store using data source controls
Estimated lesson time: 30 minutes
Trang 28figure 8-1 The DataSource Web control classes
Each data source control is used in a similar manner You can drag the control onto your Web page from the Toolbox in Visual Studio You can then use the Configre Data Source Wizard to connect to your data and generate markup for the data source Connecting to data with markup (instead of code) is referred to as declarative data binding, as you are declaring your data access rather than writing ADO.NET code Figure 8-2 shows the step to select data
in this wizard
figure 8-2 The step to select data in the Configure Data Source Wizard in Visual Studio
Trang 29This wizard creates the declarative markup used to defi ne the data source connection
information This markup can contain connection information, data manipulation statements
(such as SQL), and more The following shows an example of the SqlDataSource control’s
markup for connecting to the Products table in the Northwind database
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT * FROM [Products]"></asp:SqlDataSource>
EXAM TIP
The wizard-based UI is a great tool for defi ning many of your data source declarations
However, it is important you know the markup syntax for working with these controls This
will help with both programming against the controls and taking the exam Therefore, the
rest of this lesson focuses on the markup (and not the wizard-based UI)
Each data source control is specialized for the type of data with which it is meant to work
The following sections provide an overview of what makes each of these controls unique This
includes some of the more common uses of data source controls such as binding, fi ltering,
sorting, modifying data, and more
Using Objects as Data Sources with objectDataSource
Many Web applications work with a middle tier, or business layer, for retrieving and working
with application data This middle tier encapsulates database code inside of classes Web
de-velopers can then call methods on these classes to select, insert, modify, and delete data In
this way, they do not have to write direct, ADO.NET code, as this is written by whoever wrote
the middle tier In addition, this middle tier is often reusable across different applications
You can use the ObjectDataSource control in ASP.NET to connect to and work with
middle-tier objects in a similar manner as working with the other data source objects This control can
be added to a page and confi gured to create an instance of a middle-tier object and call its
methods to retrieve, insert, update, and delete data The ObjectDataSource control is
respon-sible for the lifetime of the object It creates it and disposes of it Therefore, the business layer
code should be written in a stateless manner Alternatively, if the business layer uses static
(shared in Visual Basic) methods, the ObjectDataSource can use these methods without
creat-ing an instance of the actual business object
You confi gure an ObjectDataSource to connect to a class by setting its TypeName attribute
to a string that represents a valid type to which the Web application has access This class
might be inside your App_Code directory or inside a dll fi le to which the Web application has
a reference (it should not be in your page’s code-behind fi le) You then set the SelectMethod
attribute to a valid method name on the class The ObjectDataSource control will then call this
method when the data is requested
Trang 30As an example, imagine you need to write an interface to allow a user to manage the
ship-per table inside the Northwind database You might have a business object that knows how to
return all the shippers in the database that looks as follows:
'VB
Public Class Shipper
Private Shared _cnnString As String = _
ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ToString Public Shared Function GetAllShippers() As DataTable
Dim adp As New SqlDataAdapter( _
"SELECT * FROM shippers", _cnnString)
Dim ds As New DataSet("shippers")
{
SqlDataAdapter adp = new SqlDataAdapter(
"SELECT * FROM shippers", _cnnString);
DataSet ds = new DataSet("shippers");
Trang 31This code also binds the ObjectDataSource to a DetailsView control to display the
informa-tion to the user Figure 8-3 shows an example of the output
figure 8-3 An ObjectDataSource bound to a DetailsView control
Notice that the Shipper.GetAllShippers method returns a DataTable An ObjectDataSource
class can work with any data that implements any of the following interfaces: IEnumerable,
IListSource, IDataSource, or IHierarchicalDatasource This means as long as your business
ob-ject class returns data as a DataTable, a DataSet, or some form of a collection, you can be sure
this data can be used with an ObjectDataSource control
Passing Parameters
The business objects with which you work will undoubtedly define methods that take
param-eter values These paramparam-eters might define a filter on the data or indicate values to be used
when inserting or updating data Fortunately, you can use the ObjectDataSource to map
Trang 32vari-There are multiple sets of parameters you can define for a given ObjectDataSource These sets include Select, Insert, Update, Delete, and Filter parameters These parameters work in conjunction with the given method of the same name For example, the <SelectParameters> set works with the method defined by the SelectMethod attribute.
The source of the given parameter’s value can come from multiple places in your page or
site This includes a Cookie, Control, Session, QueryString, Form, or Profile object These
op-tions make defining and mapping a data source an easier task You can also define the source value in code
As an example, imagine you have a business object name Customer Assume this object contains the method GetCustomersByCity, which takes a city value as string The method then
returns a list of customers for the given city parameter Now imagine you need to create a
data source control to map to this class The ObjectDataSource should pass the value for city
to the method from the query string In this case, you would create a SelectParameters set that includes a QueryStringParameter definition The QueryStringParameter definition would
map between the name of the query string parameter and the name of the method’s eter The following code shows an example:
You might then attach this data source to a GridView or similar control You can then call
the page by passing in the appropriate query string value as follows:
http://localhost:5652/DataSourceSamples/CustomersObjectDs.aspx?city=London
You can use this same technique to pass multiple parameters of various types and from various sources You can also use this same technique to pass parameters meant for handling inserting, updating, and deleting, as discussed in the next section
Inserting, Updating, and Deleting
You can also use an ObjectDataSource control to define how data should be inserted,
updated, and deleted The attributes InsertMethod, UpdateMethod, and DeleteMethod can
be mapped directly to an object’s methods that are to be called when these activities are invoked You then use parameter definitions to map values to these method calls
Trang 33As an example, recall the Shipper class discussed previously Now imagine that additional
methods have been added to this object These method signatures might look as follows:
'VB
Public Shared Function GetAllShippers() As DataTable
Public Shared Sub InsertShipper(ByVal companyName As String, ByVal phone As String)
Public Shared Sub UpdateShipper(ByVal shipperId As Integer, _
ByVal companyName As String, ByVal phone As String)
Public Shared Sub DeleteShipper(ByVal shipperId As Integer)
//C#
public static DataTable GetAllShippers()
public static void InsertShipper(string companyName, string phone)
public static void UpdateShipper(int shipperId, string companyName, string phone)
public static void DeleteShipper(int shipperId)
You can map an ObjectDataSource control to each of these methods In doing so, you
need to define the parameters each method expects The following markup shows an
Trang 34Type="String" />
</InsertParameters>
</asp:ObjectDataSource>
You can then use this ObjectDataSource control with a data-bound control such as a
DetailsView The following markup is an example In this case, the fields are bound
individu-ally This allows granular control over the ShipperId field as it is an auto-generated primary key (identity) in a SQL Server database Therefore, you set the InsertVisible property to False
to make sure the DetailsView does not try to pass a value for ShipperId to the InsertMethod of the ObjectDataSource You also set the ReadOnly attribute of the same field to True to indi-
cate the value should not be available to change during an edit operation
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName" />
<asp:BoundField DataField="Phone" HeaderText="Phone" />
To define a filter for an ObjectDataSource control, you set the FilterExpression attribute to a
valid filter This filter will be applied after the data is retrieved from the database You can also
use FilterParameters to map values from the page to the filter expression by defining a filter
expression that contains parameter mappings as numbers enclosed in braces You then add the appropriate filter parameters
The following code shows an example Here, the Customer.GetAllCustomers method
is bound to an ObjectDataSource control When the data is returned, the filter expression
Trang 35city=’{0}’ is applied to the result The query string value for city is then passed as the {0}
pa-rameter to the filter expression
Sorting and Paging
The data-bound controls that work with an object data source control can be configured to
page and sort the data returned by the data source control However, it is often better to sort
and page this data when the data is requested from the database Doing so can reduce the
consumption of resources on your server
The ObjectDataSource control defines specific attributes for managing sorting and paging
You set these attributes to parameters of your SelectMethod The SelectMethod must also
define these properties and use them for sorting and paging In addition, by using these
spe-cific properties, data-bound controls such as GridView can automatically work with your data
source to provide inputs for sorting and paging
As an example, imagine you wish to provide a business object method to control how
customer data is sorted and paged as it is retrieved and not after the fact You could define a
business method as follows:
'VB
Public Shared Function GetPagedCustomersSorted( _
ByVal sortCol As String, ByVal pageStart As Integer, _
ByVal numRecords As Integer) As DataTable
If numRecords <= 0 Then numRecords = 10
Dim cnn As New SqlConnection(_cnnString)
Dim sql As String = "SELECT * FROM customers"
If sortCol <> "" Then sql = sql & " order by " & sortCol
Trang 36Dim adp As New SqlDataAdapter(cmd)
cnn.Open()
Dim ds As New DataSet("customers")
adp.Fill(ds, pageStart, numRecords, "customers")
Return ds.Tables("customers")
End Function
//C#
public static DataTable GetPagedCustomersSorted(
string sortCol, int pageStart, int numRecords)
{
if (numRecords <= 0)
numRecords = 10;
SqlConnection cnn = new SqlConnection(_cnnString);
string sql = "SELECT * FROM customers";
if (sortCol != "")
sql = sql + " order by " + sortCol;
SqlCommand cmd = new SqlCommand(sql, cnn);
SqlDataAdapter adp = new SqlDataAdapter(cmd);
DataSet ds = new DataSet("customers");
parameters when defining an ObjectDataSource You set the control’s SortParameterName
attribute to the parameter of your business object that is used for sorting data You set the
StartRowIndexParameterName to the parameter that defines the row number at which you
wish to start retrieving data You then set the MaximumRowsParameterName to the
param-eter that is used to define the number of rows you wish to include in a given data page The following markup shows an example:
<asp:ObjectDataSource
ID="ObjectDataSource1"
Trang 37When the page is run, the GridView control passes sort and paging information to the
data source However, because the paging is happening before the GridView is bound, the
GridView does not know the number of pages to display Therefore, you need to implement
your own custom paging in this scenario to advance the PageIndex property of the GridView
control on user request Once you reset this value, the GridView will pass the value on to the
ObjectDataSource.
Caching Data
You can tell ASP.NET to cache your ObjectDataSource control This will keep the data in
memory between page calls This can increase performance and scalability of your
applica-tion if the data is shared and accessed often
To indicate caching of an ObjectDataSource, you set the EnableCaching attribute to True
You then set the CacheDuration property to the number of seconds you wish to have ASP.NET
cache the data The following shows an example of these settings:
The first call to this page will call the object and return its data Subsequent calls within the
same 30 seconds (such as moving through data pages) will use the cached data (and not call
the underlying object)
Trang 38Creating a Dataobject Class
There are not too many restrictions on which objects you can use as the source of
Object-DataSource controls If you know your business object will be used as an ObjectObject-DataSource,
you can define attributes on your class that make consuming your class inside an
ObjectData-Source easier inside the designer These attributes are used to predefine which methods you
intend as Select, Insert, Update, and Delete.
To get started, you set the DataObject attribute at the top of your class This simply indicates that your class is meant to be a DataObject Again, this is not required for use with
ObjectDataSource controls, but simply makes things easier The following shows an example
of the class declaration and attribute:
public class Shipper
You then add the attribute DataObjectMethod to the top of each method you intend as
a data object method You pass a DataObjectMethodType enum value to this attribute to indicate Delete, Insert, Update, or Select The following code shows an example of the method
signature and attribute:
'VB
<System.ComponentModel.DataObjectMethod(ComponentModel.DataObjectMethodType.Select)> _ Public Shared Function GetAllShippers() As DataTable
//C#
[DataObjectMethod(DataObjectMethodType.Select)]
public static DataTable GetAllShippers()
By defining these attributes, you make the designer aware of your business object’s
inten-tions This can ease the burden of configuring an ObjectDataSource control when using large
business objects with many methods
Connecting to Relational Databases with SqlDataSource
The SqlDataSource control is used to configure access to relational databases such as SQL
Server and Oracle It can also be configured to work with Open Database Connectivity (ODBC) and Object Linking and Embedding (OLE) Db data connections You configure the control to connect to one of these database types The code inside the control will then use the appropriate provider based on your configuration settings These are the same ADO.NET provider classes discussed in Chapter 7, “Using ADO.NET, XML, and LINQ with ASP.NET,” such
as SqlClient, OracleClient, OleDb, and Odbc.
Trang 39You configure the SqlDataSource control by first setting its ID property to a unique
identi-fying string value This property is similar to any other Web control ID property However, the
value is used when referring to the data source during data binding (discussed momentarily)
You then set the ConnectionString property either to a valid connection string or to page
script that reads the connection string from the Web.config file (as shown in the next code
example)
You then set various command properties This includes commands for selecting, inserting,
updating, and deleting data The command properties you set are based on how you intend
to use the control For example, you use the SelectCommand to define a SQL statement that
can be used to retrieve data from a database In this case, you would use the
SelectCommand-Type of Text (the default) You can also set the SelectCommandSelectCommand-Type to StoredProcedure and
then provide a stored procedure name for the SelectCommand attribute.
The DataSourceMode attribute is used to define how you want the SqlDataSource control
to retrieve your data You have two options: DataSet and DataReader The former connects
to the database and returns all records as a DataSet instance It then closes the database
connection before continuing to process the page The latter, DataReader, keeps an open
connection to the database while it reads each row into the data source control
The following markup shows an example of connecting to a SQL Server Express database
by first reading the connection string from the Web.config file It uses a text-based SQL
state-ment and a DataReader It then binds the data source to a GridView control for display.
You can also work with the data source controls from code When doing so, you replace
the markup attribute settings with object property settings You first create the data source
control inside the Page_Init method You then add the data source control to the page to
ensure it is available to be bound to other controls The following code shows the preceding
markup example translated as code in a code-behind page:
'VB
Partial Class _Default
Trang 40Protected Sub Page_Init(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Init
Dim sqlDs As New SqlDataSource
sqlDs.ConnectionString = _
ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ToString sqlDs.ID = "SqlDataSource1"
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load