Walkthrough: Using the Domain Service in ASP.NET Applications

[WCF RIA Services Version 1 Service Pack 2 is compatible with either .NET framework 4 or .NET Framework 4.5, and with either Silverlight 4 or Silverlight 5.]

ASP.NET provides a DomainSourceControl control that can be used by data-bound controls, such as the GridView control, to access the database and enable the user to perform creates, read, update and delete (CRUD) operations.

It is important to notice that the domain service enables you to detach your application from the specific database model. This gives you the advantage of focusing on the business logic and on creating code that is easily portable to a different model.

The WCF RIA Services domain service provides a pattern to write application logic that runs on the server and controls access to data for queries, changes, and custom operations. It also provides end-to-end support for common tasks such as data validation, authentication and roles by integrating Silverlight client and ASP.NET server applications.

This walkthrough shows how to access a database from an ASP.NET Web page by using the RIA Services domain service. Even though this walkthrough describes the domain service in ASP.NET, the use of the service is not limited to ASP.NET applications. This walkthrough does not address the integration of ASP.NET server with Silverlight client applications.

This walkthrough contains the following procedures:

  • Creating an ASP.NET Web Application

  • Using the Domain Service

  • Testing the Domain Service

Prerequisites

This and the other walkthroughs presented in the RIA Services documentation require several prerequisite programs, such as Visual Studio 2010 and the Silverlight Developer Runtime and SDK, be installed and configured properly, in addition to WCF RIA Services and the WCF RIA Services Toolkit. They also require installing and configuring SQL Server 2008 R2 Express with Advanced Services and installing the AdventureWorks OLTP and LT database.

Detailed instructions for the satisfaction of each of these prerequisites are provided by the topics within the Prerequisites for WCF RIA Services node. Follow the instructions provided there before proceeding with this walkthrough to ensure that you encounter as few problems as possible when working through this RIA Services walkthroughs.

Creating an ASP.NET Web Application

To use the domain service, you must create an ASP.NET Web application capable of interacting with a database. The following are the steps you must perform:

  • Creating a Web application. This provides the environment for the use of the domain service.

  • Adding a database to the application. This enables you to choose the database for your Web application.

  • Creating the database model. You create the model that contains the database entities as CLR types. These are the types used by the domain service to interact with the database. You can use the ADO.NET Entity Framework or LINQ to SQL data model.

The following procedure shows how to create an ASP.NET Web application.

To create an ASP.NET Web application

  1. In Visual Studio 2010, click the File menu, click New, and then click Project.

    The New Project dialog box is displayed.

  2. Under Installed Templates, expand Visual C# or Visual Basic, and then select Web.

  3. In the list of templates, select ASP.NET Empty Web Application.

  4. Name the project UsingDomainService, specify a location, and then click OK.

  5. Build the application.

The following procedure shows how to add a database to the application. This database contains the table that will be accessed for display and editing.

To add the database to the Web application

  1. In Solution Explorer, right-click the project name, click Add, click Add ASP.NET Folder, and then click App_Data.

    This adds the App_Data folder to the project.

  2. Right-click the App_Data folder, click Add, and then click Existing Item.

    The Add Existing Item dialog box is displayed.

  3. Specify the location for the AdventureWorksLT database file (AdventureWorksLT_Data.mdf).

    The following illustration shows the Add Existing Item dialog box.

    ASP.NET Domain Service Client: Add Existing Item D

  4. 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.

The following procedure shows how to create the data model that contains the classes that represent the database tables. In this walkthrough, you will use an ADO.NET Entity Framework data model. However, you could use a LINQ to SQL data model instead.

To create the data model

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

    The Add New Item dialog box is displayed.

  2. Under Installed Templates, select Data.

  3. In the list of templates, select ADO.NET Entity Data Model.

  4. Name the database model AdventureWorksLT.edmx and then click Add.

    The Entity Data Model Wizard is displayed.

  5. On the Choose Model Contents screen, select Generate from database.

    The following illustration shows the Choose Model Contents dialog box.

    ASP.NET Domain Service Client: Choose Model Conten

  6. Click Next.

  7. On the Choose Your Data Connection screen, under Which data connection should your application use to connect to the database?, select AdventureWorksLT_Data.mdf from the drop-down list.

  8. Make sure that the Save entity connection settings in Web.config as: check box is selected. You can leave the default connection string name.

    The following illustration shows the Choose Your Data Connection dialog box.

    ASP.NET Domain Service Client: Choose Data Connect

  9. Click Next.

    The wizard displays a page where you can specify what database objects you want to include in your model.

  10. On the Choose Your Database Objects screen, select the Tables node to select all tables from the database.

    The following illustration shows the Choose Your Database Objects dialog box.

    ASP.NET Domain Service Client: Choose Your Databas

  11. Make sure that the Include foreign key columns in the model check box is selected. You can leave the default model namespace.

  12. Click Finish.

    The ADO.NET Entity Data Model Designer is displayed. You have created the data model that represents the AdventureWorksLT database.

  13. Close the designer.

  14. Build the application.

    Building makes the AdventureWorksLT_DataEntities context class available to the domain service in the next procedure.

Using the Domain Service

This procedure describes the steps that you must perform to use the domain service in an ASP.NET application. These steps include the following:

  • Adding a domain service class to the project. This creates the class that enables your application to perform CRUD database operations and, very importantly, it enables you to include your business logic. This class operates on the server or middle tier.

  • Creating the business logic. You include your code (business logic) in the domain service class.

  • Declaring the DomainDataSource control. You do this in a page markup so that the user can interact with the database. This control operates on the client or presentation tier.

The following procedure shows how to add the domain data service to the project.

To add the domain service class to the project

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

  2. Under Installed Templates, select Web.

  3. In the list of templates, select Domain Service Class.

  4. Name the file AdventureWorksDomainService.cs or AdventureWorksDomainService.vb and then click Add.

    The Add New Domain Service Class dialog box is displayed. The Domain service class name: box contains the name that you specified.

  5. Select the Enable client access check box.

  6. In the Available DataContexts/ObjectContexts: drop-down list, select AdventureWorksLT_DataEntities (Entity Framework). If the drop-down list is empty, you did not build the application. Exit the Add New Domain Service Class dialog box, build the application, and repeat the previous steps. 

  7. In the Entities list, select the Product table.

  8. For the Product table, select the Enable editing check box.

  9. Select the Generated associated classes for metadata check box.

    The following illustration shows the Add New Domain Service Class dialog box.

    ASP.NET Domain Service Client: Add New Domain Serv

  10. Click OK.

    The AdventureWorksDomainService class and the related metadata file are created. The class contains the methods to allow for database CRUD operations. You can modify both the class and the metadata files to include your business logic. The next procedure will show a simple example. Notice that the project references have been updated to contain the required assemblies and the Web.config file has been updated to contain all the needed configuration elements.

  11. On the File menu, click Save All.

The following procedure shows how to customize the AdventureWorksDomainService class and the related metadata file to include your business logic. The customization is very simple, but gives you an idea of the modifications you can make.

To create the business logic

  1. In Solution Explorer, open the AdventureWorksDomainService.cs or AdventureWorksDomainService.vb file.

  2. Modify the UpdateProduct method to include validation logic of the ListPrice field, as shown in the following code. Also, update the ModifiedDate field using the current date.

    public void UpdateProduct(Product currentProduct)
    {
      if ((currentProduct.EntityState == EntityState.Detached))
      {
        // Custom logic: set a lower limit for the price.
        if (currentProduct.ListPrice < 5)
          throw new ValidationException("The list price must be >= 5.");
        this.ObjectContext.Products.AttachAsModified(currentProduct,
           this.ChangeSet.GetOriginal(currentProduct));
        // Custom logic: set the date to the current value.
        currentProduct.ModifiedDate = DateTime.Today;
      }
    }
    
    Public Sub UpdateProduct(ByVal currentProduct As Product)
      If (currentProduct.EntityState = EntityState.Detached) Then
        ' Custom logic: set a lower limit for the price.
        If currentProduct.ListPrice < 5 Then
          Throw New ValidationException("The list price must be >= 5.")
        End If
        Me.ObjectContext.Products.AttachAsModified(currentProduct, _
          Me.ChangeSet.GetOriginal(currentProduct))
        ' Custom logic: set the date to the current value.
        currentProduct.ModifiedDate = DateTime.Today
      End If
    End Sub
    

    When the validation fails, an exception is raised and an error message is sent to the page to be displayed to the user.

  3. Modify the GetProducts method to set the ordering logic for the Entity Framework to function correctly, as shown in the following code.

    public IQueryable<Product> GetProducts()
    {
      return this.ObjectContext.Products.OrderBy(p => p.ProductID);
    } 
    
    Public Function GetProducts() As IQueryable(Of Product)
      Return Me.ObjectContext.Products.OrderBy(Function(p) p.ProductID)
    End Function
    
  4. Save and close the file.

  5. In Solution Explorer, open the AdventureWorksDomainService.metadata.cs or AdventureWorksDomainService.metadata.vb file.

  6. Add the Required attribute to the Color data field entity, as shown in the following code.

    With this attribute, you force the data field not to be empty as allowed by the database. If the user enters an empty string an error is issued.

    [Required(AllowEmptyStrings=false, 
      ErrorMessage="Color is required")]
    public string Color{ get; set; }
    
    <Required(AllowEmptyStrings:=False, ErrorMessage:="Color is required")> _
    Public Property Color As String
    
  7. Save and close the metadata file.

  8. Build the application.

The following procedure shows how to declare the DomainDataSource control in a page markup so that the user can interact with the database.

To declare the DomainDataSource control in a page

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

  2. Under Installed Templates, click Web.

  3. In the list of templates, select Web Form.

  4. Name the file Default.aspx and then click Add.

  5. Open Default.aspx in Design view.

  6. From the General or Data group of the Toolbox, add a DomainDataSource control to the page.

    The DomainDataSource appears with the DomainDataSource Tasks menu open.

    If the control is not listed, click the Tools menu, and then click Choose Toolbox Items. In the Choose Toolbox Items dialog box, click the .NET Framework Components tab, select the DomainDataSource check box, and then click OK.

  7. In the DomainDataSource Tasks menu, click Configure Data Source.

    The Configure Data Source wizard is displayed.

  8. On the Choose a Domain Service screen, from the Domain Service Type: list, select the class you created UsingDomainService.AdventureWorksDomainService.

    The following illustration shows the Choose a Domain Service screen.

    ASP.NET Domain Service Client: Choose Domain Servi

  9. Click Next.

  10. On the Configure Data Access screen, select the IQueryable<Product> GetProducts() method.

  11. Select the Enable inserts, Enable updates, and Enable deletes check boxes.

    The following illustration shows the Configure Data Access screen.

    ASP.NET Domain Service Client: Choose Domain Acces

  12. Click Finish.

  13. In the Toolbox, from the Data tab, add a GridView control to the page.

    The GridView appears with the GridView Tasks menu open.

  14. In the GridView Tasks menu, from the Choose Data Source list, select DomainDataSource1.

    This is the ID of the DomainDataSource control that you created in previous steps.

  15. In the GridView Tasks menu, click Edit Columns.

    The Fields dialog box is displayed.

  16. Uncheck the Auto-generate fields check box.

  17. In the Selected fields: pane delete all the fields except Name, Color, ListPrice and ModifiedDate.

  18. Click OK.

  19. Optionally, in the GridView Tasks menu, enable paging, sorting, and selection by selecting the related check boxes.

  20. Save the file and switch to Source view.

  21. Select the GridView.

  22. In the Properties window, set the DataKeyNames property to the following comma-separated list of all the columns that are not displayed: ProductID, ProductNumber, StandardCost,Size, Weight,ProductCategoryID, ProductModelID, SellStartDate, SellEndDate, DiscontinuedDate, ThumbNailPhotoFileName, rowguid.

    This is needed by the DomainDataSource control to perform the CRUD operations.

  23. Set the AutoGenerateEditButton property to True to enable editing and deleting of table rows.

  24. In Source view, replace the Columns element with the following markup.

    By using custom templates, this markup enables validation for the Color and ListPrice data field values before they are sent to the server on post-back. It also creates a delete LinkButton control that asks the user permission before a row deletion is performed.

      <Columns>
        <asp:TemplateField>
          <ItemTemplate>
            <asp:LinkButton ID="LinkButton1"  CommandName="Delete" Text="Delete"
              ForeColor="#333333"  OnClientClick='return confirm("Are you sure you want to delete this row?");'/>
          </ItemTemplate>
        </asp:TemplateField>
    
        <asp:CommandField ShowSelectButton="True" />
        <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
        <asp:TemplateField>
          <HeaderTemplate>Color</HeaderTemplate>
          <ItemTemplate>
            <%# Eval("Color") %>
          </ItemTemplate>
          <EditItemTemplate>
            <asp:TextBox ID="ColorID"  Text='<%# Bind("Color") %>'/>
            <cc1:DomainValidator ID="DomainValidator2"   DataField="Color"/>
          </EditItemTemplate>
        </asp:TemplateField>
    
        <asp:TemplateField>
          <HeaderTemplate>ListPrice</HeaderTemplate>
          <ItemTemplate>
            <%# Eval("ListPrice")%>
          </ItemTemplate>
          <EditItemTemplate>
            <asp:TextBox ID="ListPriceID"  Text='<%# Bind("ListPrice") %>'/>
            <cc1:DomainValidator ID="DomainValidator3"  DataField="ListPrice"/>
           </EditItemTemplate>
         </asp:TemplateField>
    
         <asp:BoundField DataField="ModifiedDate" HeaderText="ModifiedDate" SortExpression="ModifiedDate" />
      </Columns>
    
  25. Before the GridView control, add the following markup to enable validation errors to display:

    <asp:ValidationSummary ID="ValidationSummary1"  />
    <cc1:DomainValidator  ControlToValidate="GridView1"/>
    
  26. Save the Default.aspx file.

  27. Build the application.

Testing the Domain Service

This procedure shows how to test the domain service capabilities with the use of the GridView control. This procedure verifies the following:

  • The interaction with the database, through the custom business logic, works as expected.

  • ASP.NET performs the changes that were made by the user to the database fields.

  • ASP.NET displays the errors messages generated by the custom logic.

Testing the domain service

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

    The browser shows a page that displays the Product table.

  2. On any row, click Edit and modify the ListPrice column value by entering a value less than 5.

  3. On the same row, click Update.

    A custom error is displayed stating that the field must be greater than or equal to 5.

  4. On the same row, enter a value that is greater than 5 for the ListPrice column.

  5. On the same row, click Update.

    ASP.NET updates the ListPrice and the ModifiedDate data fields in the database.

  6. On any row, click Edit and modify the Color column value by entering an empty string.

  7. On the same row, click Update.

    ASP.NET displays a custom validation error.

  8. On the same row, enter a value that is not an empty string for the Color column.

  9. On the same row, click Update.

    ASP.NET updates the Color and the ModifiedDate data fields in the database.

See Also

Tasks

How to: Add Business Logic to the Domain Service

Concepts

Creating RIA Services Solutions