January 19, 2021
Hot Topics:

Create Quick Database Interfaces with ASP.NET Dynamic Data

  • By Jani Järvinen
  • Send Email »
  • More Articles »

Customizing using attributes

So far, you have briefly seen how ASP.NET Dynamic Data applications work. After you have seen how the different features of the application, you should next learn how you can control how data is displayed in the application.

Earlier, when looking at the Global.asax.cs file, the ScaffoldAllTables property was set to true. This property value means that every table in the model became active in the application for editing and deleting. But maybe you would like to better control which tables are active. To do this, you need to use attributes. In the data model, the classes that represent the tables are defined as partial classes. This means that you can effectively continue adding features to these classes, including specifying attributes. To write the necessary code, you need to add a new file to your project.

The easiest way to add this file is to right-click your project in Visual Studio's Solution Explorer and then choose the Add/Class command. Visual Studio will then ask you for a class name; choose any name you want, for instance "MetadataControl". Once the file has been created, you can start editing it.

Assuming for example, that you want to hide the employees table, you would add a partial class definition for the Employee class, originally defined in the ADO.NET entity model file NorthwindModel.Designer.cs (if you followed the naming convention suggested earlier). Replacing the skeleton public class definition written by Visual Studio, add the following code:

  public partial class Employees

With this definition, the Employees class defined in the original entity model gets extended, and the ScaffoldTable attribute is added. This attribute is one of the key ones in ASP.NET Dynamic Data. Many of the most important attributes are defined in the System.ComponentModel.DataAnnotations namespace. Other often-needed attributes include ScaffoldColumn (of which you will soon see an example), DisplayName, DisplayFormat, Range and UIHint.

With the above ScaffoldTable attribute (and the value of false) in place, you should now run the application to see how it behaves. In the initial screen showing the names of tables in the data model, you should see that the Employees table link is missing. And, if you take a look for example at the Orders table, you can see that the hyperlinks to the table are also gone.

Notice how there are two ways to show and hide tables. You can make all tables visible using the ScaffoldAllTables property in the Global.asax.cs file, and then hide them one by one using attributes. The other option is to go the other way around: leave ScaffoldAllTables to false, and then allow individual tables to become visible using the ScaffoldTable(true) attribute.

Next, let's see how you can control individual fields using attributes. Previously, you used partial classes to help in specifying the ScaffoldTable attribute, but if you wanted to have attributes associated with individual columns, you would need another kind of solution. Since you cannot have partial property definitions, you must use an additional class to define properties that are associated with database fields.

To do this, you start with a similar partial class like with the ScaffoldTable attribute, but you use the MetadataType attribute to associate another class with the original. Then, this additional class, called the metadata class, allows you to define public properties for each field in the data model which you want to control. The following example shows how this is done:

  public partial class Employees
  class EmployeesMetadata
    [DisplayName("Person's title")]
    public object Title { get; set; }

Here, the partial class Employees is defined as before, but also the MetadataType attribute is applied to the class. The constructor of this attribute accepts a type as a parameter, which in turn points to the metadata class called EmployeesMetadata. This class is then free to define new properties and associated field- level attributes to them. For instance, here the DisplayName attribute (in the System.ComponentModel namespace) is associated with the column Title to specify a new, more descriptive title for the field. Of course, the property names must match those in the database for this to work.

Modifying user interfaces

While understanding how attributes are applied in ASP.NET Dynamic Data applications is key to your success, you must also understand how you can customize the web page templates that together create the user interface for your application. As briefly mentioned before, ASP.NET Dynamic Data applications by default utilize an ASP.NET template file. This file is named Site.master, and can be found from the root folder of the project.

If you wanted to change the user interface, then editing the Site.master file would be a good place to start. It utilizes XHTML code and defines a single content placeholder into which the actual pages are embedded at runtime. Furthermore, the master file uses CSS styles, which are in turn defined in the file Site.css. To do application-wide font and color changes, editing this style sheet file would give you a head start.

In addition to the template and style sheet files, you do of course have the actual .aspx pages that implement the four basic operations. This can be found inside the DynamicData\PageTemplates folder in your solution. For instance, you might wish to change how the listing pages operate. For this need, you would edit List.aspx.

Another option for customizations is the DynamicData\FieldTemplates folder. This folder contains the user controls that ASP.NET Dynamic Data uses to render different database field types. For instance, a Boolean field is shown as a checkbox to the user. If you wanted to change this, you could simply go and edit the files Boolean.ascx and Boolean_Edit.ascx. There usually are two controls defined for each data type: one for viewing and another for editing. Often, the viewer control is simply a read-only version of the edit control.

It is also possible to define your own user controls to work with your data. For instance, you might wish to change the control that is used to display dates. By default, the DateTime.ascx control uses a textbox control for this, but you could easily change this to, say, a calendar control. If you wanted to make this an application-wide change, then you could simply edit DateTime.ascx, and all date fields would change. You can also change the control on a field by field basis. This is done using attributes, just like with the previously shown ScaffoldTable and ScaffoldColumn attributes. Assume that you had implemented a calendar user control DataTimeCalendar.ascx like this:

  <%@ Control Language="C#" AutoEventWireup="true"
  FieldTemplates.DateTimeCalendar" %>
  <asp:Calendar ID="Calendar1" runat="server">

This declaration mirrors any other user control definition. However, for a user control to be suitable for ASP.NET Dynamic Data use, you need to tweak the code-behind file a bit. First, you need to change the inheritance chain from the regular System.Web.UI.UserControl to System.Web.DynamicData.FieldTemplateUserControl.

Of course, you are not limited to controls that are available in ASP.NET. For instance if you have purchased a nice, feature-rich third-party control or created one on your own, you are free to use them in your ASP.NET Dynamic Data applications. Specifying which user control should be used when ASP.NET Dynamic Data renders the database views can be controlled using the UIHint attribute. This attribute is applied to metadata classes just like the ScaffoldColumn attribute. With the previous DateTimeCalendar user control declaration in place, you could use the UIHint attribute as follows:

  public partial class Employees
  class EmployeesMetadata
    public object HireDate { get; set; }

Here, the HireDate field of the Employees table is assigned the UIHint attribute with the value of "DateTimeCalendar". When ASP.NET Dynamic Data shows the table, the regular text label is replaced with the calendar control (Figure 7). Note that you also need to write a couple of lines of code to the user control's code behind file so that you can set the calendar to show the correct hire date:

  protected override void OnDataBinding(EventArgs e)
    object val = FieldValue;
    if (val != null)
      Calendar1.SelectedDate = (DateTime)val;
      Calendar1.VisibleDate = Calendar1.SelectedDate;

Click here for larger image

Figure 7. A custom calendar showing employee hire dates.

Other than this kind of code, it is quite easy to customize your pages with custom controls. As you can see, the row listings and editing pages need not solely rely on labels and text boxes.

Page 3 of 4

This article was originally published on June 8, 2009

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date