Getting Started with Entity Framework 4.0 Database First and ASP.NET 4 Web Forms - Part 8

by Tom Dykstra

The Contoso University sample web application demonstrates how to create ASP.NET Web Forms applications using the Entity Framework 4.0 and Visual Studio 2010. For information about the tutorial series, see the first tutorial in the series

Using Dynamic Data Functionality to Format and Validate Data

In the previous tutorial you implemented stored procedures. This tutorial will show you how Dynamic Data functionality can provide the following benefits:

  • Fields are automatically formatted for display based on their data type.
  • Fields are automatically validated based on their data type.
  • You can add metadata to the data model to customize formatting and validation behavior. When you do this, you can add the formatting and validation rules in just one place, and they're automatically applied everywhere you access the fields using Dynamic Data controls.

To see how this works, you'll change the controls you use to display and edit fields in the existing Students.aspx page, and you'll add formatting and validation metadata to the name and date fields of the Student entity type.

Image01

Using DynamicField and DynamicControl Controls

Open the Students.aspx page and in the StudentsGridView control replace the Name and Enrollment Date TemplateField elements with the following markup:

<asp:TemplateField HeaderText="Name" SortExpression="LastName">
                <EditItemTemplate>
                    <asp:DynamicControl ID="LastNameTextBox" runat="server" DataField="LastName" Mode="Edit" />
                    <asp:DynamicControl ID="FirstNameTextBox" runat="server" DataField="FirstMidName" Mode="Edit" />
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:DynamicControl ID="LastNameLabel" runat="server" DataField="LastName" Mode="ReadOnly" />,
                    <asp:DynamicControl ID="FirstNameLabel" runat="server" DataField="FirstMidName" Mode="ReadOnly" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:DynamicField DataField="EnrollmentDate" HeaderText="Enrollment Date" SortExpression="EnrollmentDate" />

This markup uses DynamicControl controls in place of TextBox and Label controls in the student name template field, and it uses a DynamicField control for the enrollment date. No format strings are specified.

Add a ValidationSummary control after the StudentsGridView control.

<asp:ValidationSummary ID="StudentsValidationSummary" runat="server" ShowSummary="true"
        DisplayMode="BulletList" Style="color: Red" />

In the SearchGridView control replace the markup for the Name and Enrollment Date columns as you did in the StudentsGridView control, except omit the EditItemTemplate element. The Columns element of the SearchGridView control now contains the following markup:

<asp:TemplateField HeaderText="Name" SortExpression="LastName">
                <ItemTemplate>
                    <asp:DynamicControl ID="LastNameLabel" runat="server" DataField="LastName" Mode="ReadOnly" />,
                    <asp:DynamicControl ID="FirstNameLabel" runat="server" DataField="FirstMidName" Mode="ReadOnly" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:DynamicField DataField="EnrollmentDate" HeaderText="Enrollment Date" SortExpression="EnrollmentDate" />

Open Students.aspx.cs and add the following using statement:

using ContosoUniversity.DAL;

Add a handler for the page's Init event:

protected void Page_Init(object sender, EventArgs e)
{
    StudentsGridView.EnableDynamicData(typeof(Student));
    SearchGridView.EnableDynamicData(typeof(Student));
}

This code specifies that Dynamic Data will provide formatting and validation in these data-bound controls for fields of the Student entity. If you get an error message like the following example when you run the page, it typically means you've forgotten to call the EnableDynamicData method in Page_Init:

Could not determine a MetaTable. A MetaTable could not be determined for the data source 'StudentsEntityDataSource' and one could not be inferred from the request URL.

Run the page.

Image03

In the Enrollment Date column, the time is displayed along with the date because the property type is DateTime. You'll fix that later.

For now, notice that Dynamic Data automatically provides basic data validation. For example, click Edit, clear the date field, click Update, and you see that Dynamic Data automatically makes this a required field because the value is not nullable in the data model. The page displays an asterisk after the field and an error message in the ValidationSummary control:

Image05

You could omit the ValidationSummary control, because you can also hold the mouse pointer over the asterisk to see the error message:

Image06

Dynamic Data will also validate that data entered in the Enrollment Date field is a valid date:

Image04

As you can see, this is a generic error message. In the next section you'll see how to customize messages as well as validation and formatting rules.

Adding Metadata to the Data Model

Typically, you want to customize the functionality provided by Dynamic Data. For example, you might change how data is displayed and the content of error messages. You typically also customize data validation rules to provide more functionality than what Dynamic Data provides automatically based on data types. To do this, you create partial classes that correspond to entity types.

In Solution Explorer, right-click the ContosoUniversity project, select Add Reference, and add a reference to System.ComponentModel.DataAnnotations.

Image11

In the DAL folder, create a new class file, name it Student.cs, and replace the template code in it with the following code.

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.DAL
{
    [MetadataType(typeof(StudentMetadata))]
    public partial class Student
    {
    }

    public class StudentMetadata
    {
        [DisplayFormat(DataFormatString="{0:d}", ApplyFormatInEditMode=true)]
        public DateTime EnrollmentDate { get; set; }

        [StringLength(25, ErrorMessage = "First name must be 25 characters or less in length.")]
        [Required(ErrorMessage="First name is required.")]
        public String FirstMidName { get; set; }

        [StringLength(25, ErrorMessage = "Last name must be 25 characters or less in length.")]
        [Required(ErrorMessage = "Last name is required.")]
        public String LastName { get; set; }
    }
}

This code creates a partial class for the Student entity. The MetadataType attribute applied to this partial class identifies the class that you're using to specify metadata. The metadata class can have any name, but using the entity name plus "Metadata" is a common practice.

The attributes applied to properties in the metadata class specify formatting, validation, rules, and error messages. The attributes shown here will have the following results:

  • EnrollmentDate will display as a date (without a time).
  • Both name fields must be 25 characters or less in length, and a custom error message is provided.
  • Both name fields are required, and a custom error message is provided.

Run the Students.aspx page again, and you see that the dates are now displayed without times:

Image08

Edit a row and try to clear the values in the name fields. The asterisks indicating field errors appear as soon as you leave a field, before you click Update. When you click Update, the page displays the error message text you specified.

Image10

Try to enter names that are longer than 25 characters, click Update, and the page displays the error message text you specified.

Image09

Now that you've set up these formatting and validation rules in the data model metadata, the rules will automatically be applied on every page that displays or allows changes to these fields, so long as you use DynamicControl or DynamicField controls. This reduces the amount of redundant code you have to write, which makes programming and testing easier, and it ensures that data formatting and validation are consistent throughout an application.

More Information

This concludes this series of tutorials on Getting Started with the Entity Framework. For more resources to help you learn how to use the Entity Framework, continue with the first tutorial in the next Entity Framework tutorial series or visit the following sites: