Walkthrough: Enabling Dynamic Data in ASP.NET Data-Bound Controls

This walkthrough shows how to integrate Dynamic Data features in a data-bound control without using scaffolding or any partial scaffolding elements. This approach is useful if you have an existing Web site and you want to add dynamic behavior to data-bound controls.

You can use a ObjectDataSource control to access the database and still take advantage of Dynamic Data features. (This is instead of using controls such as the LinqDataSource control and EntityDataSource control that are used with Data Dynamic Web sites that rely on scaffolding.) In this walkthrough, you will create a custom business class that the ObjectDataSource control interacts with in order to expose data from a particular table in the AdventureWorks sample database.

This topic describes the following tasks:

  • Enable Dynamic Data in a GridView data-bound control.

  • Interact with the underlying database by using a ObjectDataSource control.

  • Display a specified table in the GridView control and enable users to update rows in the table.

This topic contains the following sections:

  • Prerequisites

  • Creating an ASP.NET Web Application and Adding a Data Model

  • Creating Custom Logic to Access a Specified Table

  • Enabling Dynamic Data for a Data-Bound Control

  • Testing Dynamic Data Features

  • Adding Custom Data Information

  • Testing Custom Dynamic Data Validation

  • Next Steps

Prerequisites

In order to complete the example in this topic, you need the following:

See a video that shows this feature: Watch Enabling Dynamic Data.

A Visual Studio project with source code is available to accompany this topic: Enabling Dynamic Data.

Creating an ASP.NET Web Application and Adding a Data Model

To start, you will create an ASP.NET Web site that is not specifically an Dynamic Data Web application.

To create an ASP.NET Web application

  1. Start Visual Studio.

  2. In the File menu, click New, and then click Project.

    The New Project dialog box is displayed.

  3. Under Installed Templates, in the left pane, select Visual Basic or Visual C#, and then select Web.

  4. Under Installed Templates, select ASP.NET Web Application.

  5. 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:\WebApplications\EnableDynamicData.

  6. Click OK.

The next step is to add a database.

To add the database to the Web application

  1. In Solution Explorer, right-click the App_Data folder, and then click Add Existing Item.

  2. 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: 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. However, you could use an ADO.NET Entity Framework data model instead. (You could also create these classes manually without using any data modeling tool, although that is not shown in this walkthrough.)

To create the data model

  1. In Solution Explorer, right-click the project name and then click Add.

  2. Select-click New Item.

  3. Under Installed Templates, in the left pane, select Data.

  4. In the central pane click LINQ to SQL Classes.

  5. In the Name box, enter the name AdventureWorksLT.dbml for the database model.

  6. Click Add.

    The Object Relational Designer is displayed. For more information, see Object Relational Designer (O/R Designer).

  7. In the Object Relational Designer, click the Server Explorer link.

  8. In Server Explorer, under Data Connections, expand the AdventureWorksLT_Data.mdf node and then expand the Tables node.

  9. Select all the tables and drag them into the O/R Designer window.

  10. In the displayed diagram, select all the columns of the SalesOrdersDetail table.

  11. In the related Properties window set the Update Check property to Never.

  12. Close the Server Explorer.

  13. Save and close the AdventureWorksLT.dbml file.

    You have created the data model that represents the AdventureWorksLT database.

Creating Custom Logic to Access a Specified Table

The next step is to create code that enables your application to access and handle the database information. (In a Dynamic Data Web application, this logic would be generated automatically. However, this walkthrough shows you how to create this code to use with the ObjectDataSource control.) For this walkthrough, the custom logic consists of methods to list and modify the data fields that are contained in the SalesOrderDetail table.

To create custom logic to access a specified table

  1. In Solution Explorer, right-click the project name then click Add.

  2. Select-click New Item.

  3. Under Installed Templates, in the left pane, click Code.

  4. In the center pane, click Code File.

  5. In the Name box, enter ProcessingOrderDetails.vb or ProcessingOrderDetails.cs and then click Add.

  6. Copy the following code into the new class, replacing any code that is already in the file.

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Web
    
    Namespace EnableDynamicData
      Public Class ProcessingOrderDetails
        Public Function GetSalesOrderDetails() As IEnumerable( _
          Of SalesOrderDetail)
          Using db As New AdventureWorksLTDataContext()
            Return db.SalesOrderDetails.ToList()
          End Using
        End Function
    
        Public Sub Update(ByVal p As SalesOrderDetail)
          Using db As New AdventureWorksLTDataContext()
            db.SalesOrderDetails.Attach(p, True)
            db.SubmitChanges()
          End Using
        End Sub
      End Class
    End Namespace
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace EnableDynamicData
    {
      public class ProcessingOrderDetails
      {
        public IEnumerable<SalesOrderDetail> GetSalesOrderDetails()
        {
          using (AdventureWorksLTDataContext db = 
             new AdventureWorksLTDataContext())
          {
            return db.SalesOrderDetails.ToList();
           }
        }
    
        public void Update(SalesOrderDetail p)
        {
          using (AdventureWorksLTDataContext db = 
            new AdventureWorksLTDataContext())
            {
              db.SalesOrderDetails.Attach(p, true);
              db.SubmitChanges();
            }
        }
      }
    }
    

    The class contains the following methods:

    • GetSalesOrderDetails. This method returns the data rows from the SalesOrderDetail table. This method instantiates the database context object and then uses the SalesOrderDetails class to get the collection of rows.

    • Update. This method changes a column value in the SalesOrderDetail table. The method instantiates the database context object and then submits the changes made in the SalesOrderDetail table to the database.

  7. Save and close the file.

  8. From the Build menu, click Build EnableDynamicData (or the name that used for the Web application) in order to build the solution.

    This makes the business object available for the next procedure.

Enabling Dynamic Data for a Data-Bound Control

This section shows how to configure a data-bound control so that it can use features such as page templates and validation that is inferred from the database schema or from custom metadata. Your application can use these features by simply enabling Dynamic Data. The control is used to display and change the values that are contained in the SalesOrderDetail table.

The first step is to configure a data source control to interact with the database.

To add a Web page and a data source control

  1. In Solution Explorer, right-click the project name then click Add.

  2. Click New Item.

  3. Under Installed Templates, in the left pane, click Web.

  4. In the center pane, click Web Form.

  5. In the Name box enter EnableDynamicData.aspx, and then click Add.

  6. Switch to Design view.

  7. From the Data group of the Toolbox, add a ObjectDataSource control to the page.

  8. On the ObjectDataSource Tasks menu, click Configure Data Source.

    The Choose a Business Object dialog box is displayed.

  9. In the Choose your Business Object list, select the ProcessingOrderDetails class that you created in the previous procedure.

  10. Click Next.

    The Define Data Methods dialog box is displayed.

  11. In the Choose a method list in the Select tab pane, select the GetSalesOrderDetails method.

  12. Click the Update tab.

  13. From the Choose a method list in the Update tab pane, select the Update method.

  14. Click Finish.

    You have configured the data source control to use the ProcessingOrderDetails class that interacts with the database through the data model.

The next step is to create a data-bound control and enable Dynamic Data for it. The control can then rely on Dynamic Data features to create the UI for displaying and editing data.

To configure the data-bound control to use enable Dynamic Data features

  1. From the Data group of the Toolbox, add a GridView control to the page.

  2. In the GridView Tasks menu, from the Choose Data Source list, select ObjectDataSource1.

    This is the ID of the ObjectDataSource control that you created in a previous procedure.

  3. Enable paging, editing, and selection.

  4. Switch to Source view.

  5. In the GridView control, in the Columns element, delete all the DataBoundField controls that were generated automatically. (Leave the CommandField element.)

  6. Enable auto-generation of columns by setting the AutoGenerateColumns attribute to true, as shown in the following example:

    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" 
      DataSourceID="ObjectDataSource1" AutoGenerateColumns="True" >
        <Columns>
          <asp:CommandField 
            ShowEditButton="True" ShowSelectButton="True" /> 
        </Columns>
    </asp:GridView>
    
  7. Save and close the EnableDynamicData.aspx file.

  8. Open the EnableDynamicData.aspx.vb or EnableDynamicData.aspx.cs class file.

  9. Add the reference to the System.Web.DynamicData namespaces as shown in the following example:

    Imports System.Web.DynamicData
    
    using System.Web.DynamicData
    
  10. In the Page_Init method, enable Dynamic Data for the GridView control as shown in the following example:

    Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        GridView1.EnableDynamicData(GetType(SalesOrderDetail))
    End Sub
    
    protected void Page_Init()
      {
        GridView1.EnableDynamicData(typeof(SalesOrderDetail));
      }
    
  11. Save and close the file.

  12. Rebuild the application.

Testing Dynamic Data Features

This section shows how to test that the Dynamic Data features have been integrated in the GridView control by verifying the following:

  • The custom business logic interacts properly with the database.

  • 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 metadata.

To test Dynamic Data features

  1. In Solution Explorer, right-click the EnableDynamicData.aspx page and then click View in Browser.

    The browser shows a page that displays the SalesOrderDetail table.

  2. Verify that the correct SalesOrderDetails data fields are displayed.

  3. On any row, click Edit and for the UnitPrice column enter a non-numeric value.

  4. On the same row, click Update.

    Dynamic Data displays an error message that warns you that the UnitPrice field must be a decimal value. Notice that the UI used for editing is based on the Dynamic Data default template.

  5. On the same row, click Cancel.

  6. On any row, click Edit and then change the OrderQty column to a value that is less than or equal to the maximum integer value (32767) allowed by the database.

  7. On the same row, click Update.

    Dynamic Data updates the database. Because you entered a valid value, the data passes Dynamic Data validation.

  8. On any row, click Edit and then change the OrderQty column to a value that is greater than the maximum integer value (32767) allowed by the database.

  9. On the same row, click Update.

    Dynamic Data displays an error message that states that you entered an invalid value.

  10. On the same row, click Cancel.

    This shows that Dynamic Data features have been integrated with the GridView control and it uses the metadata information obtained from the database schema. The validation is part of the features your application inherited from Dynamic Data.

  11. Close the browser.

Adding Custom Data Information

In this section of the walkthrough, you add custom information (metadata) to the database schema. Dynamic Data uses this metadata when it processes data fields. For example, you can define a value range for a data field different from the one allowed by the database. In this walkthrough, you will add custom information to require a UnitPrice value (which is not a required field in the database) and to set a range for the OrderQty value.

To provide custom metadata

  1. In Solution Explorer, right-click the project name then select-click Add Reference.

    The Add Reference dialog box is displayed.

  2. Click the .NET tab.

  3. In the list, select System.ComponentModel.DataAnnotations.

  4. Click OK.

  5. Open the EnableDynamicData.aspx.vb or EnableDynamicData.aspx.cs file.

  6. Copy the following code into it, replacing any code that is already in the file.

    Imports System.ComponentModel.DataAnnotations
    
    Namespace EnableDynamicData
      <MetadataType(GetType(SalesOrderDetailMetadata))> _
      Partial Public Class SalesOrderDetail
        Public Class SalesOrderDetailMetadata
          Private privateUnitPrice As String
          <Required()> _
          Public Property UnitPrice() As String
            Get
              Return privateUnitPrice
            End Get
            Set(ByVal value As String)
              privateUnitPrice = value
            End Set
          End Property
    
          Private privateOrderQty As Decimal
            <Range(0, 100)> _
            Public Property OrderQty() As Decimal
              Get
                Return privateOrderQty
              End Get
              Set(ByVal value As Decimal)
                privateOrderQty = value
              End Set
            End Property
        End Class
      End Class
    
    End Namespace
    
    using System.ComponentModel.DataAnnotations;
    
    namespace EnableDynamicData
    {
      [MetadataType(typeof(SalesOrderDetailMetadata))]
      public partial class SalesOrderDetail
      {
        public class SalesOrderDetailMetadata
        {
          [Required]
          public string UnitPrice { get; set; }
    
          [Range(0, 100)]
          public decimal OrderQty { get; set; }
    
        }
      }
    
    
    }
    

    This code creates two classes: a partial class named SalesOrderDetail, and a class inside that named SalesOrderDetailMetadata.

    These classes extend the data model and let you to perform the following tasks:

    • Add metadata to the UnitPrice data field to prohibit null values. (The AdventureWorks database allows null values for the UnitPrice data field.) Dynamic Data will issue an error message when the user tries to enter a null value.

    • Add metadata to the OrderQty data field to set an allowed range. The AdventureWorks database does not have any range limits for the OrderQty data field. Dynamic Data will issue an error message when the user tries to enter a value outside the allowed range.

    Using partial classes in this way provides a flexible way to modify the behavior of the data model without directly changing the data model.

  7. Save and close the file.

Testing Custom Dynamic Data Validation

This section shows how to test that Dynamic Data performs validation based on the metadata that you provided. You will test the following:

  • Dynamic Data performs correct validation of the changes that were made to the data fields based on the custom metadata.

  • Dynamic Data generates errors messages based on the information that it infers from the from custom metadata information.

To test custom Dynamic Data validation

  1. In Solution Explorer, right-click the EnableDynamicData.aspx page and select View in Browser.

    The browser shows a page that displays the SalesOrderDetails table.

  2. On any row, click Edit and clear the UnitPrice column value.

  3. On the same row, click Update.

    Dynamic Data displays an error message that warns you that the UnitPrice field is required. This shows that Dynamic Data validation has been integrated with the GridView control and it uses the custom metadata information that you provided.

  4. On the same row, click Cancel.

  5. On any row, click Edit and then change the OrderQty column to a value in the allowed range, such as 25.

  6. On the same row, click Update.

    Dynamic Data updates the database. Because you entered a valid value, the data passes the validation.

  7. On any row, click Edit and for the OrderQty column a value outside the allowed range, such as 250.

  8. On the same row, click Update.

    Dynamic Data displays an error message that states that the data field value must be between 0 and 100. This shows that Dynamic Data validation has been integrated with the GridView control by using the custom metadata information.

  9. On the same row, click Cancel.

Next Steps

This walkthrough has illustrated the basic principles of adding Dynamic Data features to ASP.NET data-bound controls. You might want to experiment with additional features. Suggestions for additional exploration include the following:

For general information, you might want to do the following:

See Also

Concepts

ASP.NET Dynamic Data Overview

Using Dynamic Data in ASP.NET Applications

ASP.NET Dynamic Data Scaffolding

Customizing ASP.NET Dynamic Data