Adding custom metadata providers in ASP.NET 3.5 Extensions Preview

Published 10 December 07 05:30 PM

5/22/08 Note: this post talks about an outdated ASP.NET release. Please have a look at this updated dynamic metadata provider sample.

One of the most powerful elements of the new ASP.NET Dynamic Data feature we are working on is the ability to associate metadata (for example, range validation or formatting) with your data model. You can then query the model and use the provided information to customize the processing of your data. In the recently released ASP.NET 3.5 Extensions Preview this annotation is done by declaring special metadata attributes on the partial classes representing the entities in the model. The initial implementation is a bit limited, however, because the metadata association can only be done using CLR attributes and those attributes have to be declared on the class (even if they pertain to the class's properties):

[Range("Quantity", 0, 10000)] 
[Range("Price", 0, 20000)]
partial class Product {
}

A better approach

The MVC Toolkit (which incorporates a number of modifications to the Preview that will be included in later milestones – download here) contains an alternative implementation. This implementation has the following improvements:

  • A pluggable metadata model based on providers.
  • New metadata attributes that can be declared on the properties of a special metadata "buddy" class.
  • An alternative reference provider implementation based on XML files.

The best way to familiarize yourself with the new model is to look at the samples included with the MVC toolkit. However, here are a few points to get you started:

  1. The registration of a metadata handler is done on a DataContext type using the MetadataHandlerRegistration class. This needs to be done only once per application, for example in the Global.asax file:
    protected void Application_Start(object sender, EventArgs e) {
        MetadataHandlerRegistration.Register(
    typeof(MyDataContext),
    MetadataHandlerRegistration.XmlMetadataProvider); }
    Note: Only Linq to SQL models are supported in this version. Future releases will support both Linq to SQL and ADO.NET Entities.
  2. MetadataHandlerRegistration contains references to 2 different metadata providers: buddy class-based and XML file-based.

Buddy class metadata

Buddy class metadata is a model in which you associate a "buddy class" with your actual data model class and declare the metadata attributes on properties of the buddy class. "Why do I need to declare a parallel class?", you ask. The simple answer is that the current versions of C# and VB have no concept of partial properties.

This implementation supports two ways of associating the buddy class:

  1. Explicit: using an attribute on the model partial class that points to the type of the buddy class
  2. Implicit: using a name matching pattern (append "_Metadata" to the name of the model class and look for a class with that new name in the current namespace/assembly)

Using the explicit option looks like this:

[MetadataClass(typeof(Product_Metadata))]
partial class Product {
}

public class Product_Metadata {
    [Range(0, 10000)]
    public int Quantity { get; set; }
}

Comment out the MetadataClass attribute and you get the implicit option.

XML file metadata

An alternative metadata provider uses an XML file as the metadata store. Currently the file location is hard-coded to be ~/metadata.xml. A very basic metadata.xml file could look like this (a slightly bigger one is included in the sample blog project of the MVC Toolkit):

<metadata xmlns="http://tempuri.org/metadataFile"
    xmlns:m="http://tempuri.org/metadataElements"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://tempuri.org/metadataFile ../Schemas/MetadataFile.xsd
http://tempuri.org/metadataElements ../Schemas/MetadataElements.xsd"> <metadataAttributes> <metadataAttribute tagPrefix="m" assembly="MVCToolkit" namespace="Microsoft.Web.DynamicData.Metadata"/> </metadataAttributes> <tables> <table name="Product"> <columns> <column name="Quantity"> <m:Range Minimum="0" Maximum="100000"/> </column> </columns> </table> </tables> </metadata>

The metadataAttributes section defines metadata attribute mappings. These are used by the logic that creates a CLR attribute type instance from an XML element. For example, the m:Range element will be converted into the class Microsoft.Web.DynamicData.Metadata.RangeAttribute in the MVCToolkit assembly. The attributes on the element are automatically converted and set on the properties of the attribute type instance. You can add your own metadata attribute collection by defining a new metadataAttribute entry.

The tables section allows you to define metadata on all of the tables and their columns that make up your model.

As a final note, most of the attributes on the root metadata element are there to support IntelliSense in your XML editor. The relative URLs work in the sample Dynamic Data MVC blog project. You might have to change some of the paths if you decide to move the XSD files around or if you create a new project in a different location.

Implementation details

The underlying implementation uses the TypeDescriptor mechanism from System.ComponentModel. It is basically a pluggable layer on top of standard reflection. Have a look at the code to learn more.

Conclusion

This post discusses elements that will be incorporated in some way or another in future releases of ASP.NET Extensions. However, some of the implementation details might change. We will certainly have detailed documentation for the final release.

In the meantime feel free to explore the provided code and make sure you give back any feedback you might have on how these features can be improved. You can post your comments/questions at:

ASP.NET 3.5 Extensions Preview discussion
ASP.NET Dynamic Data discussion

Additional resources

Visit these blogs for additional tips on ASP.NET 3.5 Extensions and Dynamic Data:

David Ebbo's ASP.NET blog
Scott Hunter: ASP.NET and .NET Musings

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Scott Hunter said on December 11, 2007 12:29 PM:

Marcin Dobosz is a member of Dynamic Data team in ASP.NET. He has written a great post on metadata in

# Christopher Steen said on December 12, 2007 1:21 AM:

Link Listing - December 11, 2007

# di .NET e di altre Amenit said on December 12, 2007 3:44 AM:

ASP.NET 3.5: Un po' di link alla rinfusa #4

# Sam Gentile said on December 12, 2007 8:54 AM:

Prodded by Mike to pick up the slack, I am trying to get one of these out each morning before all my

# Brad Abrams said on December 14, 2007 12:47 AM:

Dynamic data is a very cool feature of the ASP.NET 3.5 Extensions that allows you to trivially easy build,

# Programming said on December 18, 2007 10:28 AM:

Dynamic data is a very cool feature of the ASP.NET 3.5 Extensions that allows you to trivially easy build

# Huan-Lin's Blog said on January 19, 2008 11:49 PM:

上一篇是 ASP.NET Dynamic Data 的入門練習,主要是體驗一下 Dynamic Data 技術的威力,看看它如何幫我們在幾分鐘內完成一個資料驅動 Web 應用程式的骨幹(scaffolding)。本文則打算整理一些 Dynamic Data 技術的基本觀念,並延續上一篇的練習,將原本的範例網站修改成我們希望的樣子(把欄位名稱改成中文)。

# jkergosi said on March 4, 2008 3:08 PM:

Being able to add custom meta data is just what I was looking for!  I noticed that the MVC Toolkit offers this, but are there options for options to take advantage of custom meta data provider for LINQ to SQL or EF for web forms?

# marcind said on March 4, 2008 4:06 PM:

** jkergosi: Could you clarify what you mean by your question? What would you like to achieve?

# 不足道 said on August 21, 2008 10:17 PM:

ASP.NET里的支架:DynamicDataSupport

作者HartmutWilms译者张海龙发布于2007年12月23日下午10时44分 社区

.NET

主题

...

# Блог Олега Аксенова said on September 24, 2008 2:22 AM:

Решил-таки написать о новой технологии от Microsoft, о которой почему-то мало кто пишет из русскоязычных...

# Sam Gentile's Blog said on December 2, 2008 7:05 PM:

Prodded by Mike to pick up the slack, I am trying to get one of these out each morning before all my work REST/Astoria/Web Programming/Web Services Christian shows how to access SSDL (ADO.NET Entity Framework's s tore s chema d efinition l anguage and

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

This Blog

Syndication

Page view tracker