|
ASP.NET Futures (2007): Using Dynamic Data Controls with ASP.NET
This walkthrough introduces the dynamic data controls for ASP.NET, a set of server
controls that work together to create data-driven Web applications without the need
for extensive configuration.
Tasks illustrated in this walkthrough include:
- Creating a Web site with dynamic data controls enabled.
- Exploring data with the
DynamicAutoData control.
- Customizing control display.
- Controlling the appearance of dynamic data pages.
- Using folders to customize table mappings.
- Adding navigation with dynamic data controls.
- Configuring dynamic data control behavior.
- Creating custom data columns.
Dynamic data controls make it easy to create data-driven Web pages. The controls
retrieve database schema information at run time, using intuitive defaults to identify
tables and views. This walkthrough shows you how to use dynamic data controls to
access tables in a Microsoft SQL Server Express database (.mdf file).
Prerequisites
To complete the walkthrough, you need the following:
This walkthrough assumes that you have a general understanding of working with ASP.NET
in Visual Studio, and a general knowledge of data binding in ASP.NET. For an introduction
to ASP.NET in Visual Studio, see
Walkthrough: Creating a Basic Page in Visual Web Developer in the MSDN Online
documentation. For an introduction to data binding in ASP.NET, see
Data-Driven Web Pages.
Creating a Web Site with Dynamic Data Controls
In this section you will create a Web site that includes dynamic data controls.
When you use the Visual Studio project template to create a new Web application,
Visual Studio creates a normal Web site folder structure with the following additional
items:
- A Bin folder that contains the assemblies required for dynamic data controls and
dynamic languages.
- A Web.config file with settings that enable dynamic data controls.
To create a Web site with dynamic data controls
- In the File menu, click New, and
then click Web Site.
- In the New Web Site dialog box, under Visual
Studio installed templates, select Dynamic Data Web Site.
- In the Location list, select File System.
- Specify a name, path, and language for the application, and then click OK.
Note You can use dynamic data controls either with statically compiled
languages or with dynamic languages. You can use statically compiled and dynamic
languages in the same Web application by creating pages and components
with different programming languages.
- Click OK to create the Web site.
The dynamic data Web site template does not include a Default.aspx page, because
by default page names map to table or view names.
Adding a Database
Next you will add the AdventureWorksLT database or your own SQL Server Express database
to the Web site.
To add a database to the project
- In Visual Studio, in Solution Explorer, right-click the App_Data folder, and then
click Add Existing Item.
The dynamic data Web site template includes an App_Data folder.
- In the Add Existing Item dialog box, locate the AdventureWorksLT_Data.mdf
file (or other .mdf file), and then click Add.
Mapping a Web Page to a Database Table
Next you will add a page with a dynamic data control and map it to the Product table
in the AdventureWorksLT database.
To add a page mapped to a database table
- In Visual Studio, in Solution Explorer, right-click the Web site and then click
Add New Item.
- In the Add New Item dialog box, click Dynamic
Data Web Form.
- In the Name box, change the default name of the form from
TableName.aspx to Product.aspx.
Dynamic data controls map pages to tables and views. By default, the name of the
page determines the name of the table that the page displays. Later in this walkthrough
you will see how to customize the mapping between pages and tables.
- Clear the Place code in separate file box.
When you work with dynamic data controls, you can place code in the page or in a
separate code file. For this walkthrough, place your code in the page.
- Click OK.
Exploring Data with the DynamicAutoData Control
By default, the template for a dynamic data Web page contains a DynamicAutoData
control. This control provides a fast way to look at data. In this part of the walkthrough
you will use the DynamicAutoData control to explore some default features
of dynamic data controls.
To use the DynamicAutoData control
- Open the Product.aspx page. The page already contains the following
DynamicAutoData
control:
<asp:DynamicAutoData id="AutoData1" runat="server" />
The control does not contain any special markup to identify the data it will display.
The page name determines which table the page will display, and schema information
for any additional pages will be read from the database when the page runs.
- Press CTRL+F5.
The page reads the database schema information and displays the Product table and
a default caption. The DynamicAutoData control automatically creates
several other dynamic data controls in order to provide a functional user interface.
These controls are listed in the DynamicAutoData documentation.
The Product table is displayed in a DynamicList control, which in turn
uses a GridView control. You can click the column titles to sort the
table, and scroll to the bottom of the page and click the page numbers to page through
the table. Because the DynamicList control uses a GridView
control, you can use themes and skins to customize the appearance of all the DynamicList
and DynamicAutoData controls in the project. In a later section of
the walkthrough, you will see other ways to customize individual GridView
controls.
- Use the drop-down lists above the table to filter the rows.
The DynamicAutoData control automatically identifies columns that contain
foreign keys to other tables in the database. It creates a drop-down list for each
key column, labels the list with the name of the column, and populates the list
with the available values.
- Notice that the ProductCategoryID and ProductModelID columns display descriptions
instead of raw key values.
ProductCategoryID and ProductModelID are foreign-key columns. The dynamic data control
framework discovers from the database schema that ProductCategoryID maps to ProductCategoryID
in the ProductCategory table. It then displays the first non-key column in that
table instead of displaying the raw key. In this case, the first non-key column
is ProductCategory.Name.
The convention of displaying descriptive columns instead of raw key values works
well in the common case where the column is a foreign key for a small table of allowed
values. It does not work in all cases; for example, the first descriptive column
might be a person's last name, which could be the same for multiple records.
- Close the browser.
- Open the Web.config file, locate the <dynamicDataControls> section,
and change the value of the
showAllTables attribute from false
to true.
<dynamicDataControls showAllTables="true"
dataLayerType="Microsoft.Web.DynamicDataControls.SqlDataLayer">
The showAllTables attribute determines whether dynamic data controls
automatically display links to other tables. This can be useful for debugging. In
this walkthrough it helps illustrate the way that dynamic data controls use schema
information at run time.
Security Note Setting the attribute to true exposes your entire database.
Setting the value to false is recommended.
- Switch to Product.aspx and press CTRL+F5 to run the page.
Notice that the ProductCategoryID and ProductModelID columns now contain links.
- In the ProductCategoryID column, click a link.
A new page opens and displays the appropriate detail record from the ProductCategory
table. Because dynamic data controls read the entire database schema, they can generate
additional pages as needed. A later section of this walkthrough shows how these
dynamically generated pages automatically use dynamic data Web pages that you create
for the corresponding tables or views.
By accessing schema information, dynamic data controls can choose appropriate formats
for displaying data. If a column contains bitmaps or other graphic formats that
the dynamic data control framework is able to display, the column values are automatically
displayed as pictures. (The Product table contains a ThumbNailPhoto column,
but the graphics in that columns are not in a supported format.)
- Press the browser's Back button to return to the Product page.
- Click Select in the first cell of the row for the Sport-100 Helmet, Red value and then scroll past the end of the
list.
Notice that the details of the selected record are displayed. (The
Sport-100 Helmet, Red row is of the few rows that has associated SalesOrderDetail
records.)
The DynamicAutoData control uses a DynamicDetails control
to display the detail information. This is an easy way to show all the fields of
a selected record when only a few columns are shown in the main list. The DynamicDetails
control was also used to display the ProductCategory record that you viewed earlier.
- At the bottom of the detail display, click View SalesOrderDetail.
A new page opens, displaying the rows in the SalesOrderDetail table for all the
orders that include the selected product. The page is generated automatically using
a DynamicAutoData control. Notice that the URL for the page contains
the name of the table (SalesOrderDetail) and that it requests the List.aspx page.
The reason for this naming convention is explained later in the walkthrough.
The View SalesOrderDetail link appears in the detail display
for the product, and as a column at the end of each row in the Product list. This
is because showAllRecords is set to true in the Web.config file.
- Scroll to the Add a new entry section at the bottom of the
SalesOrderDetail List page.
The DynamicAutoData control automatically enables users to insert new
rows by including a DynamicInsert control on the page. In this example
application, it is not a good design choice to enable users to insert new records
on a page that shows detail items from many different orders. You can suppress automatic
row insertion by using a DynamicList control instead of a DynamicAutoData
control, as shown later in this walkthrough.
In cases where insertion does make sense, you can specify your own DynamicInsert
control and customize its behavior.
Notice that the DynamicInsert control automatically populates drop-down
lists for the SalesOrderID and ProductID fields, and that they display the first
descriptive column after the key. This convention is designed to work well in the
common case where the column is a foreign key for a small table of allowed values.
The DynamicInsert control uses a DetailsView control in
insert mode.
- Scroll to the top of the page and click RSS to display the
RSS feed.
The DynamicAutoData control automatically adds the RSS feed. You can
click the links to view the transactions.
- Close the browser.
Note Leave showAllSettings set to true in the Web.config
file. Subsequent sections of the walkthrough rely on that setting.
Customizing the Columns That the DynamicAutoData Control Displays
In this section of the walkthrough you will add code to manage the columns that
the DynamicAutoData control displays, and the order that they appear
in. You can use the technique described here with other dynamic data controls as
well.
To specify which columns are displayed, and their
order
- Add the following code to the page:
public override IEnumerable GetColumns()
{
return new object[] { "Name", "Color", "ListPrice", "ProductCategoryID" };
}
C#
- Press CTRL+F5 to run the page.
The page now displays only the columns returned by the GetColumns method.
The GetColumns method overrides the GetColumns method
of the DynamicDataPage control, as you can see from the code for the
statically compiled languages. For dynamic languages, the dynamic data
control framework provides the same effect without an explicit override. By default,
a DynamicDataPage control displays all the columns in the table or
view.
The DynamicAutoData control continues to display a filter for ProductModelID,
even though the column no longer appears in the list. Later in this walkthrough
you will use the DynamicFilter control to specify exactly which filters
appear on the page.
Notice that the DynamicDetails control for the selected row (displayed
below the table) includes all the columns. So does the DynamicInsert
control at the bottom of the page, under Add a new entry.
You can customize the columns that are displayed in the DynamicDetails
control by providing a GetDetailsColumns method that returns the list
of column names. This is similar to the way that the GetColumns method specifies
which columns are displayed in the list itself. (For statically compiled languages,
this means overriding the GetDetailsColumn method of the DynamicDataPage
class.)
- Close the browser.
Writing Code to Customize the Appearance of Rows
In this section of the walkthrough you will add code to selectively change the appearance
of rows in the table.
To customize the appearance of rows
- Add the following code to the page:
public override void InitRow(GridViewRow row)
{
if (EvalS("Name").ToLower().IndexOf("r") > -1)
{
row.ControlStyle.Font.Italic = true;
}
if (double.Parse(Eval("ListPrice").ToString()) > 1000.0)
{
row.ControlStyle.Font.Bold = true;
}
}
C#
This method overrides the InitRow method of the base DynamicDataPage
class. The method is called for each row before the row is displayed.
The Eval and EvalS functions are not necessary with dynamic
languages, because dynamic languages can resolve column name identifiers at run
time.
- Press CTRL+F5 to run the page.
All the controls in the row display text in italic if the Name field contains the
letter "r" in either upper or lower case, and display text in bold if the ListPrice
field is greater than 1000.
- Close the browser.
Controlling the Appearance of Dynamic Data Pages
The DynamicAutoData control provides quick access to data, but it offers
only limited control over the appearance of pages. In this section of the walkthrough
you will use dynamic data controls directly instead of letting the DynamicAutoData
control create them for you.
Using the DynamicList Control
To begin, you will use the DynamicList control
to specify how a table is displayed.
To use the DynamicList control
- In Product.aspx, replace the
DynamicAutoData control with a DynamicList
control.
<form id="form1" runat="server">
<div>
<h3>Order List</h3>
<asp:DynamicList ID="List1" runat="server" />
</div>
</form>
- Press CTRL+F5 to run the page.
The Product table is displayed in a GridView control, this time without
the extra controls that are provided by the DynamicAutoData control.
You can still click the column titles to sort the table, and you can scroll to the bottom
of the page and click the page numbers to page through the table. All your earlier
customizations are still in effect.
The DynamicList control still enables users to update and delete rows,
which is the default behavior.
- Close the browser.
- Set the
EnableDelete and EnableUpdate properties of the
DynamicList control to false.
<asp:DynamicList id="List1" runat="server"
EnableDelete="false" EnableUpdate="false" />
By default, editing and deleting are enabled.
- Press CTRL+F5 to run the page.
The update and delete links no longer appear on the table rows. The select link
does not appear either, because there is no detail to display for the row.
- Close the browser.
- Add a
DynamicDetails control and a caption to the page.
<asp:DynamicList id="List1" runat="server"
EnableDelete="false" EnableUpdate="false" />
<h4>Details of selected row</h4>
<asp:DynamicDetails ID="Details1" runat="server" />
- Run the page.
The rows of the table now display a Select link in the first
column. When you click Select, the selected row appears
in the DynamicDetails control.
- Close the browser.
Adding Customized Filtering to the Page
Next you will add filtering to the table displayed by the Product page by using the
DynamicFilter control.
To add filtering
- Add two
DynamicFilter controls to the page, and set their ColumnID
properties to "Color" and "ProductCategoryID".
For the DynamicFilter control whoseColumnID property is "Color", set the FilterStyle property to "Radio".
<form id="form1" runat="server">
<div>
Filters:
<asp:DynamicFilter runat="server" ColumnName="Color" FilterStyle="Radio" />
<asp:DynamicFilter runat="server" ColumnName="ProductCategoryID"
ID="DynamicFilter1" />
<h3>Order List</h3>
<asp:DynamicList runat="server" />
</div>
</form>
- Press CTRL+F5 to run the page.
Notice that the ProductModelID filter does not appear, as it did when you were using
the DynamicAutoData control. When you use the DynamicList
control, only the filters that you choose to show are displayed.
Only one radio button named All is displayed for the Color
column. This is because Color is a plain-text column. The DynamicFilter
control can be used only for columns that contain a foreign key value for a table
in the database. The control does not read all the rows in the table and make a
list of the values that can appear in plain-text columns.
Note If you use radio buttons for a column that contains a large number
of values, an error can occur.
- Close the browser.
- Add a
DropDownList control to the page. Set its background color to
yellow, set its font style to italic, and give it an ID.
- Assign the ID of the
DropDownList control to the ControlID
property of the DynamicFilter control for the ProductCategoryID column.
<asp:DropDownList runat="server" ID="DropDownList1"
BackColor="Yellow" Font-Italic="true" />
<asp:DynamicFilter runat="server" ColumnName="ProductCategoryID"
ControlID="DropDownList1" />
- Run the page.
The DynamicFilter control uses the customized DropDownList
control with the background color and font style that you set instead of creating one
with default settings. You can also use ListBox and RadioButton
controls to customize the appearance of filters.
This technique can be used with other dynamic data controls. For a DynamicList
control, you can supply your own GridView control. For a DynamicDetails
or DynamicInsert control, you can supply your own DetailsView
control. For a DynamicRssLink control, you can supply your own HyperLink
control. And for a DynamicNavigator control, you can supply your own
Menu control, as shown in a later section of this walkthrough.
- Close the browser.
Using Folders to Customize Table Mappings
As you have seen, you can map a page to a database table by matching their names.
In this section of the walkthrough, you will provide more flexible mapping by putting
pages into folders that match a table or view name. Mapping folders to tables lets
you have more than one way of displaying a table or view in order to satisfy different
viewing needs.
Adding a Folder for the Product table
In this part of the walkthrough you will move the Product.aspx page to a folder
and rename it.
To add a folder for the Product table
- Add a new folder named Product. Dynamic data controls map pages to tables by name.
This name can be either a page name or a folder name. In this instance, you are
creating a folder that maps to the Product table.
- Move Product.aspx to the Product folder.
- Rename Product.aspx to List.aspx.
In a folder, the name "List" identifies a page that displays the list of records
for the table whose name matches the folder name. It is also the page that other
pages will link to in order to display a list of rows for the table.
Note You can specify a different name for this page in the Web.config
file, as described in a later section of this walkthrough.
- Press CTRL+F5 to run the page.
The Product table is displayed as it was previously when the page was in the root.
- Close the browser.
Providing List and Details Pages and Alternate Page Formats
In this part of the walkthrough you will add a folder that includes both List and
Details pages to display master/detail data. You will also add a page that shows
the associated table in an alternate format.
To add a folder for the ProductCategory table
- Add a new folder named ProductCategory.
- Add a dynamic data Web page to the folder. Name the page List.aspx.
- Replace the
DynamicAutoData control with a DynamicList
control.
- Switch to List.aspx in the Product folder and run it, and then click a product category ID.
The page displays a detail record from the ProductCategory table, using a DynamicAutoData
control with default display settings.
- Close the browser.
- Switch to the ProductCategory folder and add another dynamic data Web page. Name
the page Details.aspx.
- Replace the
DynamicAutoData control with a DynamicDetails
control.
<asp:DynamicDetails ID="Details1" runat="server" />
Like the name List.aspx, Details.aspx has special meaning for dynamic data pages
in folders. It enables other pages to navigate to the details page for a table,
and therefore gives you control over the way that the page is displayed.
- Switch to List.aspx in the Product folder and run it, and then click a product category ID.
Now the list of product categories is displayed using the Details.aspx page from
the ProductCategory folder. The URL for the page includes "ProductCategory/details.aspx".
This is an example of the convention for page names mentioned earlier in the walkthrough.
Later you will see how to specify your own conventions.
- Close the browser.
- Add another dynamic data Web page to the ProductCategory folder and name it ProductCategoryAlternate.aspx.
- Add the following code to the page.
public override IEnumerable GetColumns()
{
return new object[] { "Name", "ParentProductCategoryID" };
}
C#
- Press CTRL+F5 to run the new page.
- The new ProductCategoryAlternate page displays the specified columns using the
DynamicAutoData default settings.
By using folders, you can provide as many different pages as you need in order to
display a table or view with different formats, with different numbers of columns,
and so on. The only tables that will have special navigation properties, however,
are the tables named List.aspx and Details.aspx (or the default names that you specify,
as shown later in this walkthrough).
- Close the browser.
Mixing Named Folders and Named Pages
In this part of the walkthrough you will learn how to specify navigation to a named
page.
To add a page for the SalesOrderDetail table
- Switch to List.aspx in the Product folder and then run the page.
- Click View SalesOrderDetail on a row in the table.
A dynamically generated page for the SalesOrderDetail table is displayed. Unlike
the List.aspx page, this page has all the features provided by the DynamicAutoData
control, and it enables users to update and delete rows.
- Close the browser.
- Add another dynamic data Web page to the root of the Web site. (Do not create the
page in a subfolder.) Name the page SalesOrderDetail.aspx to match the table name.
- In the SalesOrderDetail page, change the
DynamicAutoData control to
a DynamicList control.
- Switch to List.aspx in the Product folder, and then press CTRL+F5 to run it.
- Click View SalesOrderDetail in the row for
Sport-100 Helmet, Red.
The SalesOrderDetail table is now displayed using SalesOrderDetail.aspx. The URL
shows SalesOrderDetail.aspx in the application root. Any reference to a table, even
when generated by the dynamic data controls framework, will use the appropriately
named .aspx file if it exists.
As this procedure demonstrates, you can use folders named for tables and .aspx files
named for tables in the same Web application. However, if you want to have more
than one page that displays a table, or if you want to have both detail and list
views of a table, you must use a named folder.
- Close the browser.
Adding Navigation
In this section of the walkthrough you will add a DynamicNavigator
control to facilitate navigation between pages.
To add a DynamicNavigator control to a page
- Open List.aspx in the Product folder.
- Add the following
DynamicNavigator and Menu controls to the List.aspx page.
<asp:Menu runat="server" ID="nav" BackColor="LightCyan" Orientation="Horizontal">
<StaticItemTemplate>
<%# Text %> |
</StaticItemTemplate>
</asp:Menu>
<asp:DynamicNavigator runat="server" ControlID="nav" />
<h4>Product List</h4>
<asp:DynamicList id="List1" runat="server" EnableDelete="false" EnableUpdate="false" />
Supplying a Menu control overrides the default behavior of the DynamicNavigator
control, which is to create a vertical menu.
- Run the List.aspx page.
All the tables in the database are listed, because showAllTables is
set to true in the Web.config file.
- Open the Web.config file, locate the <dynamicDataControls>
section, and change the value of the
showAllTables attribute from
true to false.
- Switch back to List.aspx and run the page.
Only three tables are displayed in the DynamicNavigator control: Product,
ProductCategory, and SalesOrderDetail. These are the tables for which you have defined
pages.
Click ProductCategory or Product
to navigate to the List.aspx pages in the respective folders. Click
SalesOrderDetail to navigate to SalesOrderDetail.aspx.
- Close the browser.
Configuring Dynamic Data Controls Behavior
In this section of the walkthrough you will examine the Web.config file for a dynamic
data Web wite and see how it can be used to customize the behavior of the site.
To examine and customize the Web.config file
- Open the Web.config file and examine the <configSections> element to
see the definition of the <dynamicDataControls> section.
<configSections>
<section name="dynamicDataControls"
type="Microsoft.Web.DynamicDataControls.DynamicDataControlsSection"/>
</configSections>
The <dynamicDataControls> section provides several ways to
customize the behavior of the Web site. You have already seen how the showAllTables
attribute determines whether all tables and views are shown by DynamicNavigator
controls, and whether dynamic links such as View SalesOrderDetail
are displayed for foreign keys.
- Remove the comment tags from the auto.axd handler in the <httpHandlers>
section of the Web.config file.
<add path="auto.axd" verb="*"
type="Microsoft.Web.DynamicDataControls.AutoHandler"/>
This handler provides a page with links to all the tables and views for which dynamic
data Web page exist if showAllTables is false, or for all tables
and views in the database if showAllTables is true.
- Press CTRL+F5 to run the project while the Web.config file is open in the editor.
This opens the browser to the root directory for the Web site.
- Add "auto.axd" to the end of the URL and then press
ENTER. For example, if your Web site is named Walkthrough, the URL might look like
the following:
http://localhost:1494/Walkthrough/auto.axd
The List of tables and views page is displayed. Optionally,
you can switch the setting of showAllTables to see the
effects.
- Close the browser and examine the comments for the <dynamicDataControls>
element.
You can add two attributes to the <dynamicDataControls> element to
change the mappings of pages in folders. The listView attribute lets
you specify a custom name for List.aspx; this is the name of the page in a mapped
folder that displays a list of rows for the mapped table. The detailsView
attribute specifies the name of the page that displays the details of a row.
For example, the following values require you to rename the pages in the Product
folder and the ProductCategory folder to MyList.aspx instead of List.aspx, and MyDetails.aspx
instead of Details.aspx.
<dynamicDataControls showAllTables="true"
dataLayerType="Microsoft.Web.DynamicDataControls.SqlDataLayer"
listView="MyList" detailsView="MyDetails" />
- The <nameMap> element enables you to add table mappings,
so that you can map a table to a page or folder with a different name.
For example, the following maps the ProductCategory table to a page or folder named
ProductCategoryTable.
<dynamicDataControls showAllTables="true"
dataLayerType="Microsoft.Web.DynamicDataControls.SqlDataLayer" >
<nameMap>
<add table="ProductCategory" pathPrefix="~/ProductCategoryTable" />
</nameMap>
</dynamicDataControls>
Creating Custom Data Columns
In this section of the walkthrough you will add a custom data column to the Product
page with content based on other columns.
To add a custom column
- Open List.aspx in the Product folder and change the
GetColumns method
as follows:
public override IEnumerable GetColumns()
{
return new object[] { "Name", "Color", "ListPrice", "ProductCategoryID",
new DynamicDataColumn(
delegate { return EvalS("Name") + " (" +
EvalS("Color") + ")"; })
};
}
C#
- Press CTRL+F5 to run the page and view the custom column.
The custom column is a concatenation of two other columns, Name and Color, with
parentheses around Color. It has the default title Custom column.
Custom columns are represented by DynamicDataColumn objects, which
must be created explicitly in statically compiled, strongly typed languages like
C#. In IronPython you can use a lambda expression, and in Managed JScript you can
use an anonymous function. In dynamic languages, the dynamic custom controls framework
creates the DynamicDataColumn object automatically.
- Close the browser.
- To supply a caption for the custom column, use the
DynamicDataColumn
constructor. This constructor takes a string and an anonymous method (in C#), anonymous
function (in Managed JScript), or lambda expression (in IronPython). For dynamic
languages, the constructor is not specified explicitly; the dynamic data control
framework supplies it.
public override IEnumerable GetColumns()
{
return new object[] { "Name", "Color", "ListPrice", "ProductCategoryID",
new DynamicDataColumn(
"Name (Color)",
delegate { return EvalS("Name") + " (" +
EvalS("Color") + ")"; })
};
}
C#
- Press CTRL+F5 to run the page and view the custom column.
- Close the browser.
See Also
Introduction to Dynamic Data Controls
|