Walkthrough: Adding Dynamic Data Scaffolding to Existing ASP.NET Web Sites
This walkthrough demonstrates how to add dynamic behavior to a Web site by using Dynamic Data scaffolding elements. Additionally, it shows ways in which you can customize the Dynamic Data capabilities of the site. The Web site that is created in this walkthrough enables the user to perform create, read, update, and delete (CRUD) database operations.
For purposes of this walkthrough, you will create two Web projects. One project will act as the existing site — that is, the site that you want to add Dynamic Data behavior to. (In your production Web sites, you would typically already have a site that you wanted to add this behavior to.) The second Web project that you create will be a Dynamic Data Web site that is fully scaffolded. This makes it easy to copy some Dynamic Data functionality that you require into the existing site. (You would otherwise have to create pages and settings by hand in order to add that functionality to a site.)
This walkthrough uses a Web site project. You could use a Web application project instead. For information about the difference between these Web project types, see Web Application Projects versus Web Site Projects in Visual Studio.
This topic contains the following sections:
Prerequisites
Creating an ASP.NET Web Application
Adding the Data Model to the Web Site
Creating Routes
Creating a Second ASP.NET Web Site
Adding Dynamic Data Scaffolding Elements to the Web Site
Testing Dynamic Data Capabilities
Customizing the Dynamic Data Model
Testing Dynamic Data Customization
Next Steps
Prerequisites
In order to complete the examples in this topic, you need the following:
Visual Studio 2010 or Visual Web Developer 2010 Express.
The AdventureWorksLT sample database installed on your computer. For more information, see How to: Set Up an AdventureWorksLT Sample Database for ASP.NET Development.
A Visual Studio project with source code is available to accompany this topic: Adding Dynamic Data.
Creating an ASP.NET Web Application Project
In this section you will create an empty ASP.NET Web application project. For purposes of this walkthrough, the empty Web application project will act as your existing site. This site will have no real functionality when you create it, and will not be a Dynamic Data Web application — that is, it will not be a site that has scaffolding enabled. However, later in the walkthrough you will modify the empty site to integrate Dynamic Data features.
To create an ASP.NET Web application project
Start Visual Studio.
In the File menu, click New, and then click Project.
The New Project dialog box is displayed.
Under Installed Templates, in the left pane, select Visual Basic or Visual C#, and then select Web.
Under Installed Templates, select Empty Web Site.
In the Location box, enter the name of the folder where you want to keep the Web application. For example, enter the folder name C:\WebSites\AddingDynamicData.
Click OK.
Adding the Data Model to the Web Site
The next step is to add a database and to create a data model that represents the database. For the database, you will add a copy of the AdventureWorksLT database to your empty Web application.
To add the database to the Web application
In Solution Explorer, right-click the project name then click Add.
Click Add ASP.NET Folder, and then click App_Data
Visual Studio creates the App_Data folder.
In Solution Explorer, right-click the App_Data folder, and then click Add Existing Item.
In the Add Existing Item dialog box, enter the location where the AdventureWorksLT database file (AdventureWorksLT.mdf) is stored, and then click Add.
This creates a copy of the database file in the project. For more information, see How to: Set Up an AdventureWorksLT Sample Database for ASP.NET Development and How to: Connect to the AdventureWorksLT Database using an .MDF File.
You can now create the data model that contains the classes that represent the database tables. Dynamic Data uses these classes to interact with the database. In this walkthrough you will use a LINQ-to-SQL data model. (You could use an ADO.NET Entity Framework data model instead, but for this walkthrough, you will use LINQ to SQL.)
To create the data model
In Solution Explorer, right-click the project name then click Add.
Click Add ASP.NET Folder, and then click App_Code.
Visual Studio creates the App_Code folder.
Under Installed Templates, in the left pane, select Data.
In the center pane, click LINQ to SQL Classes.
In the Name box, enter the name AdventureWorksLT.dbml.
Click Add.
The Object Relational Designer is displayed.
In the Object Relational Designer, click the Server Explorer link.
In Server Explorer, under Data Connections, expand the AdventureWorksLT_Data.mdf node, and then expand the Tables node. If a connection does not exist, double-click the AdventureWorksLT_Data.mdf file in Server Explorer.
Select all the tables and drag them into the Object Relational Designer window.
Close Server Explorer.
In the File menu, click Save All.
Visual Studio saves the AdventureWorksLT.dbml file and adds a connection string for it to the Web.config file.
Close the AdventureWorksLT.dbml file.
You have created the data model that represents the AdventureWorksLT database.
You can now register the data model context. This enables Dynamic Data to access the database information.
To register the data model context
In Solution Explorer, right-click the project name, and then click Add New Item.
Under Visual Studio installed templates, in the center pane, select Global Application Class and then click Add.
Visual Studio adds a Global.asax file to the application.
Add @ Import directives with a Namespace attribute that reference the System.ComponentModel.DataAnnotations, System.Web.Routing, and System.Web.DynamicData namespaces, as shown in the following example:
<%@ Import Namespace="System.ComponentModel.DataAnnotations" %> <%@ Import Namespace="System.Web.Routing" %> <%@ Import Namespace="System.Web.DynamicData" %>
In the Application_Start method, add the following highlighted code:
void Application_Start(object sender, EventArgs e) {// Create an instance of the data model. MetaModel DefaultModel = new MetaModel(); // Register the data model. DefaultModel.RegisterContext(typeof(AdventureWorksLTDataContext),new ContextConfiguration() { ScaffoldAllTables = false });}
Sub Application_Start(ByVal sender As Object, _ ByVal e As EventArgs) ' Create an instance of the data modelDim DefaultModel As MetaModel DefaultModel = New MetaModel ' Register the data modelDefaultModel.RegisterContext(GetType( _AdventureWorksLTDataContext), _New ContextConfiguration() With {.ScaffoldAllTables = False}) End Sub
Save the Global.asax file, but leave it open.
Creating Routes
You can now register routes. These routes are URL patterns that enable Dynamic Data to select the page template to associate with list, detail, insert, and update operations. Every time the user clicks on a link such as "edit", "details", and so on, Dynamic Data routes the request to the proper page template.
To create routes
In the Application_Start method, add the following highlighted code:
void Application_Start(object sender, EventArgs e) {// Register the data model. DefaultModel.RegisterContext(typeof(AdventureWorksLTDataContext),new ContextConfiguration() { ScaffoldAllTables = false });// Create the routes. RouteTable.Routes.Add(new DynamicDataRoute("{table}/{action}.aspx"){Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert" }),Model = DefaultModel});}
Sub Application_Start(ByVal sender As Object, _ ByVal e As EventArgs) ' Register the data modelDefaultModel.RegisterContext(GetType( _AdventureWorksLTDataContext), _New ContextConfiguration() With {.ScaffoldAllTables = False})' Create the routes.RouteTable.Routes.Add(New DynamicDataRoute( _ "{table}/{action}.aspx") _With {.Constraints = New RouteValueDictionary( _New With {Key .Action = "List|Details|Edit|Insert"}), _.Model = DefaultModel}) End Sub
Save and close the Global.asax file.
Creating a Second ASP.NET Web Site
The easiest way to add Dynamic Data functionality to an existing site is to copy some elements from a Dynamic Data Web site that is fully scaffolded. In this section, for the purposes of this walkthrough, you will create a Web site that uses scaffolding. Later in the walkthrough, you will copy some elements from this site.
To create a Dynamic Data Web site
In Visual Studio or Visual Web Developer in the File menu, click New and then click Web Site.
The New Web Site dialog box is displayed.
Under Installed Templates, in the left pane, select Visual Basic or Visual C#.
In the center pane, select Dynamic Data LINQ to SQL Web Site.
In the Web Location box, select File System and then enter the name of the folder where you want to keep the pages of the Web site.
For example, enter the folder name C:\WebSites\ScaffoldingDynamicData.
Click OK.
Visual Studio creates the Web site.
Adding Dynamic Data Scaffolding Elements to the Web Site
Your site requires a few scaffolding elements that enable the user to perform create, read, update, and delete (CRUD) database operations. (You do not have to enable scaffolding for the entire site.) These scaffolding elements provide the necessary UI and validation controls.
This section shows how to add the scaffolding elements.
To add Dynamic Data scaffolding elements
In Windows Explorer, open the folder that contains the Dynamic Data Web site that uses scaffolding (the site that you created in the preceding procedure).
In Windows Explorer, copy the DynamicData folder.
In Solution Explorer, right-click the project name, and then click Paste.
Repeat the previous steps for the Site.css and Site.master files.
Close Windows Explorer.
Testing Dynamic Data Capabilities
The next step is to test that the Dynamic Data capabilities have been integrated in the Web site by verifying the following functionality:
Dynamic Data UI is used to interact with the database. The UI is generated by the imported Dynamic Data page templates.
Dynamic Data validation is performed on the changes that are made to the data fields.
Dynamic Data generates errors messages that are based on the information that it infers from the database schema.
To test Dynamic Data capabilities
In Solution Explorer, right-click the project name, and then click Add New Item.
Under Visual Studio installed templates, in the center pane, select Web Form.
In the Name box, enter Default.aspx.
Make sure that Place the code in separate file is selected.
Click Add.
Visual Studio adds a Default.aspx page to the Web site.
Switch to Source view.
Copy the following markup into the page by overwriting the default content:
<head id="Head1" runat="server"> <title>Adding Dynamic Data to an ASP.NET Web Site</title> <link href="~/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <h2 class="DDMainHeader">Adding Dynamic Data to an ASP.NET Web Site</h2> <form id="form1" runat="server"> <div> <a href="SalesOrderDetails/List.aspx"> Accessing SalesOrderDetails table using a GridView control and Dynamic Data</a> </div> </form> </body>
Save the Default.aspx file.
Open the Global.asax file.
Temporarily enable scaffolding by setting ScaffoldAllTables to true as shown by the highlighted code in the following example:
void Application_Start(object sender, EventArgs e) { // Register the data model. DefaultModel.RegisterContext(typeof(AdventureWorksLTDataContext),new ContextConfiguration() { ScaffoldAllTables = true }); }
Sub Application_Start(ByVal sender As Object, _ ByVal e As EventArgs) ' Register the data model DefaultModel.RegisterContext(GetType( _AdventureWorksLTDataContext), _New ContextConfiguration() With {.ScaffoldAllTables = True}) End Sub
By temporarily enabling scaffolding, you can test that Dynamic Data page templates are being used to display the data from database tables.
Save and close the Global.asax file.
In Solution Explorer, right-click Default.aspx, and then click View in Browser.
In the Default.aspx page, click the link to the SalesOrderDetails table.
The browser shows a page that displays the SalesOrderDetails table by using the Dynamic Data List.aspx page template.
In any row, click Edit and for the UnitPrice field.
In the Edit page, enter a non-numeric value.
Click Update.
Dynamic Data displays an error message that warns you that the UnitPrice field must be a decimal value. The UI used for editing is based on the Dynamic Data default template.
Click Cancel.
In any row, click Edit and then change the UnitPrice field to a value that is less than or equal to the maximum integer value (32767) allowed by the database.
Click Update.
Dynamic Data updates the database. Because you entered a valid value, the data passes Dynamic Data validation.
This shows that Dynamic Data features have been integrated in the Web site and that the site uses the metadata information obtained from the database schema. Validation is one of the features that is enabled automatically in your application by Dynamic Data.
Open the Global.asax file.
Disable scaffolding by setting ScaffoldAllTables to false.
Save and close the Global.asax file.
Customizing the Dynamic Data Model
In this section, you will add custom information (metadata) to the data model. This enables you to control how Dynamic Data process data fields. To customize the data model, you create a partial class. This class extends the data model and enables you to associate custom metadata with data fields.
To create a partial class
In Solution Explorer, right-click the App_Code folder, and then click Add New Item.
Under Installed Templates, in the left pane, select the programming language.
In the center pane, click Class.
In the Name box, enter SalesOrderDetails.cs or SalesOrderDetails.vb.
The file will contain code that specifies the data field to customize. In the class file, you will create an associated class that lets you apply attributes to data fields.
Click Add.
Visual Studio opens the new class file.
Copy the following code into it, replacing any code that is already in the file:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.DynamicData; using System.ComponentModel.DataAnnotations; // Define the enumeration to apply to the OrderQty data field. public enum QtyEnum { None = 0, Small1 = 1, Small2 = 2, Small3 = 3, Small4 = 4, Small5 = 5, Small6 = 6, Small7 = 7, Small8 = 8, Small9 = 9, Medium10 = 10, Medium11 = 11, Medium12 = 12, Medium13 = 13, Medium14 = 14, Medium15 = 15, Medium16 = 16, Medium17 = 17, Medium18 = 18, Medium19 = 19, Large21 = 21, Large22 = 22, Large23 = 23, Large24 = 24, Large25 = 25 } [MetadataType(typeof(SalesOrderDetailMetadata))] // Enable table scaffolding. This enables the table to be // displayed and enables action links to be created. [ScaffoldTable(true)] public partial class SalesOrderDetail { } public partial class SalesOrderDetailMetadata { // The following code causes Dynamic Data to create // a drop-down list that lets users filter based on the // QtyEnum enumeration. [EnumDataType(typeof(QtyEnum))] public object OrderQty { get; set; } // Apply a custom date format that does not // show the current time. [DataType(DataType.Date)] public object ModifiedDate { get; set; } }
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Web Imports System.Web.DynamicData Imports System.ComponentModel.DataAnnotations ' Define the enumeration to apply to the OrderQty data field. Public Enum QtyEnum None = 0 Small1 = 1 Small2 = 2 Small3 = 3 Small4 = 4 Small5 = 5 Small6 = 6 Small7 = 7 Small8 = 8 Small9 = 9 Medium10 = 10 Medium11 = 11 Medium12 = 12 Medium13 = 13 Medium14 = 14 Medium15 = 15 Medium16 = 16 Medium17 = 17 Medium18 = 18 Medium19 = 19 Large21 = 21 Large22 = 22 Large23 = 23 Large24 = 24 Large25 = 25 End Enum ' Enable table scaffolding. This enables ' the table to be displayed and enables ' action links to be created. <MetadataType(GetType(SalesOrderDetailMetadata)), _ ScaffoldTable(True)> _ Partial Public Class SalesOrderDetail End Class Partial Public Class SalesOrderDetailMetadata ' The following code causes Dynamic Data to create ' a drop-down list that lets users filter based on ' the QtyEnum enumeration. <EnumDataType(GetType(QtyEnum))> Public Property OrderQty() As Object ' Apply a custom date format that does not ' show the current time. <DataType(DataType.Date)> Public Property ModifiedDate() As Object End Class
This code creates two classes: a partial class named SalesOrderDetail, and inside the SalesOrderDetail class, a class named SalesOrderDetailMetadata.
Note
The class names is SalesOrderDetail (notSalesOrderDetails), because in a LINQ-to-SQL data models, table names are created using the singular.
These classes extend the data model and let you perform the following tasks:
Add metadata to the SalesOrderDetail class to enable table scaffolding. This enables the table to be displayed automatically and enables links such as "edit" and "details" to be created that point to Dynamic Data page templates.
Add metadata to the OrderQty data field to enable data filtering based on custom enumeration.
Add metadata to the ModifiedDate data field to enable a date format to be applied that does not include current time.
Partial classes provide a flexible way to modify the behavior of the data model without directly changing the data model.
Save and close the file.
Testing Dynamic Data Customization
The final step is to test that the data model customizations have been integrated in the Web site by verifying the following:
The OrderQty data field filter is part of the UI that is generated by Dynamic Data.
Table rows can be filtered by OrderQty custom enumeration.
The ModifiedDate data field displays dates without the current time.
To test data model customization
In Solution Explorer, right-click Default.aspx, and then click View in Browser.
In the Default.aspx page, click the link to the SalesOrderDetails table.
The browser shows a page that displays the SalesOrderDetails table by using the Dynamic Data List.aspx page template.
Verify that the OrderQty data field filter is displayed.
In the OrderQty drop-down list, select a value.
Verify that the SalesOrderDetails table rows are filtered according to the selected value.
On any row, click Edit, and for the ModifiedDate field, in the Edit page enter the current date.
Click Update.
Dynamic Data displays the date using the custom format that does not include the current time.
Close the browser.
Next Steps
This walkthrough has demonstrated how to add Dynamic Data features to an existing ASP.NET Web site. When you integrate Dynamic Data features into an existing ASP.NET Web site, you can do the following:
Interact with the underlying database. Dynamic Data incorporates key features for a data-driven application such as create, read, update, and delete (CRUD) operations.
Display and edit data fields, because Dynamic Data selects the appropriate field template based on the information that is inferred from the database.
You might want to experiment with other Dynamic Data features. Suggestions for additional exploration include the following:
Learn how to create a basic Web application that uses ASP.NET Dynamic Data and that requires little or no code. For more information, see Walkthrough: Creating a New Dynamic Data Web Site Using Scaffolding.
Learn more about how to customize the appearance and behavior of a data field in the data model. For more information, see Walkthrough: Customizing Data Field Appearance and Behavior in the Data Model.
Learn how to add dynamic behavior to ASP.NET data-bound controls. For more information, see How to: Add Dynamic Behavior to Data-Bound Controls.
Learn more about how to customize validation of a data field in the data model. For more information, see How to: Customize Data Field Validation in the Data Model.
For general information, you might want to do the following:
Understand LINQ-to-SQL Object-Relational mapping. For more information, see LINQ-to-SQL.
Understand ADO.NET Entity Framework entity mapping. For more information, see ADO.NET Entity Framework.