Some new features in Dynamic Data 4.0

Dynamic Data

Dynamic Data was introduced in the .NET Framework 3.5 SP1 release in mid-2008. This feature provides many enhancements for creating data-driven applications, including the following:

· A RAD experience for quickly building a data-driven Web site.

· Automatic validation that is based on constraints defined in the data model.

· The ability to easily change the markup that is generated for fields in the GridView and DetailsView controls by using field templates that are part of your Dynamic Data project.

Note   For more information, see the Dynamic Data documentation in the MSDN Library.

For ASP.NET 4, Dynamic Data has been enhanced to give developers even more power for quickly building data-driven Web sites.

Declarative DynamicDataManager Control Syntax

The DynamicDataManager control has been enhanced so that you can configure it declaratively, as with most controls in ASP.NET, instead of only in code. The markup for the DynamicDataManager control looks like the following example:

<asp:DynamicDataManager ID="DynamicDataManager1" runat="server"

AutoLoadForeignKeys="true">

<DataControls>

<asp:DataControlReference ControlID="GridView1" />

</DataControls>

</asp:DynamicDataManager>

<asp:GridView id="GridView1" runat="server"

</asp:GridView>

This markup enables Dynamic Data behavior for the GridView1 control that is referenced in the DataControls section of the DynamicDataManager control.

New Field Templates for URLs and E-mail Addresses

ASP.NET 4 introduces two new built-in field templates, EmailAddress.ascx and Url.ascx. These templates are used for fields that are marked as EmailAddress or Url with the DataType attribute. For EmailAddress objects, the field is displayed as a hyperlink that is created by using the mailto: protocol. When users click the link, it opens the user's e-mail client and creates a skeleton message. Objects typed as Url are displayed as ordinary hyperlinks.

The following example shows how fields would be marked.

[DataType(DataType.EmailAddress)]

public object HomeEmail { get; set; }

[DataType(DataType.Url)]

public object Website { get; set; }

Creating Links with the DynamicHyperLink Control

Dynamic Data uses the new routing feature that was added in the .NET Framework 3.5 SP1 to control the URLs that end users see when they access the Web site. The new DynamicHyperLink control makes it easy to build links to pages in a Dynamic Data site. The following example shows how to use the DynamicHyperLink control:

<asp:DynamicHyperLink ID="ListHyperLink" runat="server"

Action="List" TableName="Products">

Show all products

</asp:DynamicHyperLink>

This markup creates a link that points to the List page for the Products table based on routes that are defined in the Global.asax file. The control automatically uses the default table name that the Dynamic Data page is based on.

Support for Inheritance in the Data Model

Both the Entity Framework and LINQ to SQL support inheritance in their data models. An example of this might be a database that has an InsurancePolicy table. It might also contain CarPolicy and HousePolicy tables that have the same fields as InsurancePolicy and then add more fields. Dynamic Data has been modified to understand inherited objects in the data model and to support scaffolding for the inherited tables.

Support for Many-to-Many Relationships (Entity Framework Only)

The Entity Framework has rich support for many-to-many relationships between tables, which is implemented by exposing the relationship as a collection on an Entity object. New ManyToMany.ascx and ManyToMany_Edit.ascx field templates have been added to provide support for displaying and editing data that is involved in many-to-many relationships.

New Attributes to Control Display and Support Enumerations

The DisplayAttribute has been added to give you additional control over how fields are displayed. The DisplayName attribute in earlier versions of Dynamic Data allowed you to change the name that is used as a caption for a field. The new DisplayAttribute class lets you specify more options for displaying a field, such as the order in which a field is displayed and whether a field will be used as a filter. The attribute also provides independent control of the name used for the labels in a GridView control, the name used in a DetailsView control, the help text for the field, and the watermark used for the field (if the field accepts text input).

The EnumDataTypeAttribute class has been added to let you map fields to enumerations. When you apply this attribute to a field, you specify an enumeration type. Dynamic Data uses the new Enumeration.ascx field template to create UI for displaying and editing enumeration values. The template maps the values from the database to the names in the enumeration.

Enhanced Support for Filters

Dynamic Data 1.0 shipped with built-in filters for Boolean columns and foreign-key columns. The filters did not allow you to specify whether they were displayed up or in what order they were displayed. The new DisplayAttribute attribute addresses both of these issues by giving you control over whether a column shows up as a filter and in what order it will be displayed.

An additional enhancement is that filtering support has been rewritten to use the new QueryExtender feature of Web Forms. This lets you create filters without requiring knowledge of the data source control that the filters will be used with. Along with these extensions, filters have also been turned into template controls, which allows you to add new ones. Finally, the DisplayAttribute class mentioned earlier allows the default filter to be overridden, in the same way that UIHint allows the default field template for a column to be overridden.

Posted in: asp.net | Tags: queryextender dynamic data dynamic data 4.0 detailsview dynamicdatamanager syntax gridview urls and e-mail addresses datatype.emailaddress dynamichyperlink data model inheritance many-to-many relationships enumerations filters new attributes

Go with C# 4.0’s dynamic

In the case of dynamic, another frequent comment is that a statically-typed language should not try to look like a dynamic language. Well, I just don’t believe in that distinction.

Being dynamic is a trait that a language can have, and some have it more than others. But as soon as a language has a dictionary type or indexers, and most modern languages do, it starts having dynamicity. What people call a dynamic language is just one where it’s the only available type.

Now there is type safety of course, but to me that’s a different feature that is not as coupled with “statically-typed-ness” as we usually tend to think. Case in point, many modern JavaScript engines analyze the code in order to apply many of the optimization techniques that static languages have been applying at compile-time.

So just how dynamic was C# before 4.0? Well, there are dictionaries and indexers, as I’ve said, but there are also other interesting and less known features such as custom type descriptors. Go look them up if you don’t know about them. Type descriptors are for example used to provide a level of indirection between a design surface and the components being edited.

But type descriptors can also be built completely dynamically and decide to expose a completely virtual object model that is entirely built at runtime. Of course, the client code for that object has to go through the right APIs to make use of that quasi-dynamic model. And of course those APIs are not simple. Implementing a custom type descriptor in itself is not exactly trivial.

If anything, the dynamic keyword is going to provide a friendlier syntax for this sort of thing. One problem is that it has no relationship whatsoever with custom type descriptors.

So I thought I’d try to bridge that gap. How can we take a type that exposes a custom type descriptor, such as DataRowView, and transform that into something that plays nice with the dynamic keyword? What we want to be able to write is something like the following:

var table = new DataTable("People");
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("Children", typeof(int));
table.LoadDataRow(
new object[] {"Bertrand", "Le Roy", 2},
LoadOption.OverwriteChanges); var tableView = new DataView(table);
dynamic dynRecord =
new TypeDescriptorDynamicWrapper(tableView[0]);
Console.WriteLine("{0} {1} has {2} children.", dynRecord.FirstName, dynRecord.LastName, dynRecord.Children);

To do that, I built the TypeDescriptorDynamicWrapper that you see being used above. What is does is pretty simple, as it just inherits from DynamicObject and implements TryGetMember as follows:

public override bool TryGetMember(
GetMemberBinder binder, out object result) {
var name = binder.Name; var property = _properties.Find( p => p.Name.Equals(name, binder.IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); if (property == null) { result = null; return false; } result = property.GetValue(
_descriptor.GetPropertyOwner(null)); return true; }

As you can see, the method just finds the right property on the type descriptor and delegates to it if it finds it. I didn’t implement the setting of properties but it would be fairly easy to do so.

Using that simple wrapper, the program above just works and displays:

Bertrand Le Roy has 2 children.

That was easy. Now what about the reverse, getting any dynamic object to expose a custom type descriptor?

Well, that’s where things get tricky.

The dynamic capabilities of C# 4.0 are targeted at two things:

  1. Providing syntactic sugar for getting to dynamic members that looks like accessing statically-defined ones.
  2. An easy way to create dynamic types by implementing a form of method_missing.

But there is one thing that exists in DLR but didn’t make it to C# yet, which is the ability to easily reflect on dynamic objects (other than by using the #1 syntactic sugar above).

For example, in JavaScript, a.foo and a[“foo”] are exactly the same thing, which enables easy reflection: you can enumerate the members of an arbitrary object and do stuff like a[someStringVariable].

Doing the same thing with C# on dynamic objects is much more difficult. The equivalent of a.foo is easy, but not the equivalent of a[someStringVariable].

Forget about using reflection, it doesn’t work on dynamic objects because dynamic really is a compiler trick. There is no such thing as a “dynamic” type to reflect on. It’s a keyword that tells the compiler to relax type-checking and generate code to access those dynamic members at runtime. If you try to reflect on an instance of one of the dynamic-friendly type, such as ExpandoObject, you’ll see the statically-defined members of that type, but not the dynamic ones. In a way, you’re looking at the messenger instead of the message.

This is a problem because in order to wrap an arbitrary dynamic object into a custom type descriptor, we need to be able to reflect on the dynamic members of that object.

To solve the problem, and with some help from the nice folks who are building the DLR, I compiled a simple program that sets and gets a property on a dynamic object, an then I looked at the generated code from Reflector (“luckily”, Reflector is not yet aware of dynamic and shows the generated code instead of something closer to the actual code you wrote).

I was then able to refactor that code and replace the string constants for the accessed member with a method parameter, thus creating a generic way to access dynamic object properties:

public static object GetValue(
object dyn, string propName) {
// Warning: this is rather expensive,
// and should be cached in a real app var GetterSite =
CallSite<Func<CallSite, object, object>>
.Create( new CSharpGetMemberBinder(propName, dyn.GetType(), new CSharpArgumentInfo[] { new CSharpArgumentInfo(
CSharpArgumentInfoFlags.None, null) })); return GetterSite.Target(GetterSite, dyn); } public static void SetValue(
object dyn, string propName, object val) {
// Warning: this is rather expensive,
// and should be cached in a real app var SetterSite =
CallSite<Func<CallSite, object, object, object>>
.Create( new CSharpSetMemberBinder(propName, dyn.GetType(), new CSharpArgumentInfo[] { new CSharpArgumentInfo(
CSharpArgumentInfoFlags.None, null), new CSharpArgumentInfo(
CSharpArgumentInfoFlags.LiteralConstant | CSharpArgumentInfoFlags.UseCompileTimeType,
null) })); SetterSite.Target(SetterSite, dyn, val); }

Once we have that, implementing the custom type provider is relatively straightforward. The only part that is not immediately obvious is how to enumerate the properties of the dynamic object.

This is done as follows. Dynamic objects implement IDynamicMetaObjetProvider, which has a GetMetaObject method, which returns a DynamicMetaObject object on which you can call GetDynamicMemberNames to get the list of members.

We can now take any dynamic object and for example present it in a property grid, which is one of those components that know how to handle custom type descriptors but not the new dynamic objects:

dynamic person = new ExpandoObject();
person.FirstName = "Bertrand";
person.LastName = "Le Roy";
person.Children = 2;
propertyGrid1.SelectedObject = 
new DynamicTypeDescriptorWrapper(person);
Posted in: asp.net | Tags: c# dynamic data 4.0 dynamic api datarowview typedescriptordynamicwrapper dynamicobject trygetmember