Using custom attributes in ASP.NET Dynamic Data

In a previous post, I presented the built-in attributes that you can use to add metadata information to your tables or data fields when using ASP.NET Dynamic Data.

In this post, I'll talk about how you can create your own custom attribute, use it and consume it in a field template.
One of the reasons that you can use a custom attribute is to change the appearance and behavior of a data field.

You can create a custom attribute by creating a class that inherits from Attribute. Then, you apply the AttributeUsage attribute to the new class. In the case of a data field, you can say that the attribute is valid on properties and fields, like in the following example:

 using System;
using System.Drawing;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class ForeColorAttribute: Attribute
{
    public static ForeColorAttribute Default = new ForeColorAttribute(KnownColor.Black);

    public ForeColorAttribute(KnownColor forecolor)
    {
        ForeColor = forecolor;
    }

    public KnownColor ForeColor { get; private set; }

}

In the case of a table, then you can say the attribute is valid on classes.

After you create your custom attribute, you can apply it to the data field as you would apply one of the built-in attributes:

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

[MetadataType(typeof(ProductMetadata))]
public partial class Product
{
}

public class ProductMetadata
{
    [ForeColor(KnownColor.Aquamarine)]
    public object Name;

    [ForeColor(KnownColor.Red)]
    public object StandardCost;
}

Last but not least, you need to consume the attribute. In this case, I'm replacing the existing Text field template with the following code:

 <%@ Control Language="C#" Inherits="System.Web.DynamicData.FieldTemplateUserControl" %>
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Drawing" %>

<script runat="server">

  public override Control DataControl
  {
    get
    {
      return Label1;
    }
  }

  protected override void OnDataBinding(EventArgs e)
  {
    base.OnDataBinding(e);
    var metadata = 
      MetadataAttributes.OfType<ForeColorAttribute>().DefaultIfEmpty(ForeColorAttribute.Default).First();
    Label1.ForeColor = Color.FromKnownColor(metadata.ForeColor);
  }
</script>

<asp:Label runat="server" ID="Label1" Text="<%# FieldValueString %>" />

You can also create a custom field template and set the UIHint for the data field.

That's it! Now you have a custom attribute!