Dynamic Data Controls with Entity Framework

As part of a chapter on integrating Entity Framework with ASP.NET, this excerpt explores what Dynamic Data Controls offer, demonstrating how to generate rich data-editing interfaces by leveraging Data Annotations to further enhance the generated interface.

This article is based on Entity Framework 4 in Action by Stefano Mostarda, Marco De Sanctis, and Daniele Bochicchio, to be published December 2010. It is being reproduced here by permission from Manning Publications. Manning early access books and ebooks are sold exclusively through Manning. Visit the book's page for more information.
You can get an instant 40% discount on this MEAP edition by simply clicking on the link above, and use promo code egghead40

 

As part of a chapter on integrating Entity Framework with ASP.NET, this excerpt explores what Dynamic Data Controls offer, demonstrating how to generate rich data-editing interfaces by leveraging Data Annotations to further enhance the generated interface.

ASP.NET Dynamic Data Controls is a feature initially introduced in ASP.NET 3.5 Service Pack 1, and further enhanced in version 4. The idea behind this technology is to simplify the typical actions related to data: displaying, filtering, and altering data.

Dynamic Data Controls ships with ASP.NET, and supports both Entity Framework, and LINQ to SQL, using the aforementioned respective DataSource controls. It is based on a simple assumption: since the ObjectContext has the same features, given different mappings, its calls can be generically created. In fact, using a bit of generics and reflection, the typical operations performed by the ObjectContext can be standardized. The same principles are valid for LINQ to SQL, of course.

Dynamic Data Controls in depth

Dynamic Data Controls work with a special kind of project, which can be found near the other ASP.NET projects. You can find it highlighted in figure 1.  


 Figure 1 Dynamic Data Entities Web application is the template project to start using Dynamic Data Controls with Entity Framework. Do not choose any other template, or it will not work.

Dynamic Data Controls is composed by a set of templates and pages, under the "DynamicData" directory. In this directory, you can find the templates used to represent different kind of types, such as strings, integers, Booleans, and so on.

Register the model

To start, you only need to define the model to work against, and the magic will be performed by using the information already present in it. In fact, the model contains the list of entities, and each entity can describe itself: the result is that each set of entity can be represented, and edited, automatically. The model and routes are registered in listing 1.

Listing 1 The model and routes registration.

VB

Public Class Global_asax

Inherits System.Web.HttpApplication

Private Shared s_defaultModel As New MetaModel()

Public Shared ReadOnly Property DefaultModel() As MetaModel
Get

Return s_defaultModel
End Get

End Property

 

Public Sub Application_Start(ByVal sender as Object, ByVal e as EventArgs)
' model registration

Dim config As New ContextConfiguration()

config.ScaffoldAllTables = True #2

DefaultModel.RegisterContext(GetType(OrderITEntities), config) #1

 

' routes

RouteTable.Routes.Add(New DynamicDataRoute("{table}/{action}.aspx")
With {

.Constraints = New RouteValueDictionary(New With {

.Action = "List|Details|Edit|Insert"}),

.Model = DefaultModel})

End Sub
End Class

C#

public class Global : System.Web.HttpApplication
{

private static MetaModel s_defaultModel = new MetaModel(); public static MetaModel DefaultModel

{

get
{

return s_defaultModel;

}

}

 

void Application_Start(object sender, EventArgs e)
{

// model registration

DefaultModel.RegisterContext(typeof(OrderITEntities), #1

new ContextConfiguration() { ScaffoldAllTables = true }); #2

 

// routes

RouteTable.Routes.Add(new DynamicDataRoute("{table}/{action}.aspx")
{

Constraints = new RouteValueDictionary(new {

action = "List|Details|Edit|Insert" }),

Model = DefaultModel

});

}

}

 

#1 the ObjectContext used as model
#2 scaffolding is enabled

We are explicitly setting the scaffold feature on, so every single entity is automatically displayed in the start page. If you prefer to control this list, you must set it to off. Using the routing features from ASP.NET 4.0, the resulting URL will be similar to "/Customers/List.aspx", where "Customers" is the EntitySet to be managed, and "List" is the action. Other actions, as you can see from the above snippet, are "Details", "Edit", and "Insert", to manage the respective statuses.

Working with Data Annotations

In figure 2 you can see the default results when you display the "Customer" list from our model.

Figure 2 Dynamic Data Controls are capable to display any mapped entity. As we can see in this figure, the display can be customized.

 

By default, the display template is inferred from the type, but it can be specified too. Generally, this is accomplished by creating a new class, specifically designed for this scenario, which extends the entity using the MetadataTypeAttribute attribute. Dynamic Data Controls, in fact, work with Data Annotations, a feature introduced in .NET Framework 3.5 SP1, and further enhanced in version 4. In our example, we are using POCO entities, so the annotations are directly generated using the T4 engine. If you are using the default entity
generation engine, you can use partial class and the aforementioned MetadataTypeAttribute. More information on this topic is available from MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.metadatatypeattribute.aspx.

In our sample, we added some custom login to the default generation engine, by altering the CDSL inside the edmx, to generate the exact code used to represent these additional properties. Data Annotations, in fact, are working with attributes, as you can see in listing 2, which contains an entity generated with this mechanism.

 

Listing 2 POCO entities generated by a template with Data Annotations.

VB

Public MustInherit Partial Class Company
Implements INotifyPropertyChanged
Implements IEditableObject

<DisplayName("Company name")> #1

<Required(ErrorMessage := "Company name is required ")> #1

<DataType("MultilineText")> #1

<RegularExpression("[\w]{2,}", ErrorMessage := "At least 2 chars.")> #1

Public Overridable Property Name() As String
Get

Return _name
End Get

Set(ByVal value As String)
_name = value

NotifyPropertyChanged("Name")
End Set

End Property
End Class

C#

public abstract partial class Company : INotifyPropertyChanged, IEditableObject
{

[DisplayName("Company name")] #1

[Required(ErrorMessage = "Company name is required")] #1

[DataType("MultilineText")] #1

[RegularExpression("[\\w]{2,}",ErrorMessage = "At least 2 chars.")] #1

public virtual string Name
{

get { return _name; }

set { _name = value; NotifyPropertyChanged("Name"); }

}

}

#1 attributes for Data Annotations

 

The annotations will influence the way the property is displayed, and its value validated: ƒ the DisplayNameAttribute attribute is used to set a more friendly name to be displayed; ƒ the RequiredAttribute attribute lets us define the property as required, associating an error message to be displayed; ƒ we are specifying a new template using the DataTypeAttribute attribute; ƒ finally, a regular expression for validation is used, using the RegularExpressionAttribute. You can take a look at how Dynamic Data Controls will handle these attributes in figure 3.  

Figure 3 The Data Annotations attributes will modify the way the property is displayed, and its value handled. By using them you can influence what the engine is performing.  

Data Annotations are a very important way to leverage Entity Framework in ASP.NET, and its use is not only limited to Dynamic Data Controls, but can be further expanded to ASP.NET MVC model validation. You can find more information on the available attributes on MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx.

By Peter Bromberg   Popularity  (3911 Views)