Erik Porter's Blog

Life and Development at Microsoft and Other Technology Discussions

News

    Using Custom Attributes in ASP.NET

    I've been working on a project pretty hard lately and after hearing Tom's presentation at our User Group meeting last month, I've been having Attributes spinning through my head.  Now granted, what I'm about to talk about is nothing very advanced, but it seems pretty cool to me and a way to better organize things.

    The first thing that came to mind were Titles of Pages.  It's typically something you set and you're done with it.  Sometimes it needs to be dynamic, sometimes not.  In most of my projects, I have some more of BasePage Class where I render skinning for the site, have common Methods all the pages might need to call, etc.  Having code in the overridden OnInit of every single page setting a Title Property defined in my BasePage Class gets to be pretty cumbersome after a while.  So I thought to myself, why not use a Custom Attribute?  Here is the Custom Attribute I ended up with:

    <AttributeUsage(AttributeTargets.Class, AllowMultiple:=True, Inherited:=True)> _
    Public Class
    PageTitleAttribute
         Inherits
    Attribute

         Private m_Title As
    String
         Private m_Order As
    Byte

        
    Public Sub New(ByVal Title As String
    )
              m_Title = Title
         End
    Sub

        
    Public Sub New(ByVal Title As String, ByVal Order As Byte
    )
              m_Title = Title
              m_Order = Order
         End
    Sub

        
    Public ReadOnly Property Title() As
    String
             
    Get
                  
    Return
    m_Title
              End
    Get
        
    End
    Property

        
    Public ReadOnly Property Order() As
    Byte
             
    Get
                  
    Return
    m_Order
              End
    Get
        
    End
    Property

    End
    Class

    Public
    Class
    PageTitleSorter
         Implements
    IComparer

         Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements
    System.Collections.IComparer.Compare
              Dim Item1 As PageTitleAttribute = DirectCast
    (x, PageTitleAttribute)
              Dim Item2 As PageTitleAttribute = DirectCast
    (y, PageTitleAttribute)

              If Item1.Order = Item2.Order
    Then
                  
    Return
    0
              ElseIf Item1.Order < Item2.Order
    Then
                  
    Return
    -1
             
    Else
                  
    Return
    1
              End
    If
        
    End
    Function

    End
    Class

    Very Simple.  Just Inherit from Attribute, set the AttributeUsage so it knows it's only allowed to be on a Class and can have more than one on a Class.  You'll also notice that I include an Order number (and a Comparer to sort through them later) so that I can specify the order in which they should be added to the title if there is more than one because doing a query to retrieve the attributes later seems to return them in a random order.  Now we're ready to attach it to one of the pages.

    <PageTitle("Section", 1), PageTitle("Page", 2)> _
    Public Class
    About
         Inherits
    BasePage

         ...

    End Class

    Now in my BasePage Class when I'm rendering the page all I have to do is write a little function to get the Title for the page.

    Private Function GetTitle() As String
        
    Dim Attributes() As
    PageTitleAttribute
         Dim Title As New
    System.Text.StringBuilder(25)

         Attributes = DirectCast(Me.GetType().GetCustomAttributes(GetType(PageTitleAttribute), True
    ), PageTitleAttribute())

         If Attributes.Length > 0
    Then
             
    If Attributes.Length > 1
    Then
                  
    Array.Sort(Attributes, New
    PageTitleSorter)
              End
    If
             
    For i As Integer = 0 To
    Attributes.Length - 1
                   If i > 0
    Then
                       
    Title.Append(TitleSeparator)
                   End
    If
                  
    Title.Append(DirectCast
    (Attributes(i), PageTitleAttribute).Title)
             
    Next
        
    End
    If

        
    Return
    Title.ToString()
    End Function

    That's all there is to it.  In my case I ended up leaving a Title Property in the BasePage Class and I make sure that OnInit is called first and sets up the Title Property from the Attributes (using the above Method) so then on the page I can add to it if I need anything else dynamic in the title.

    Another great use I've found for this is skinning.  I'm not going to post the code since it's just as simple as what I've already talked about, but basically I just created a Skin Attribute that has the ID of the Skin “Piece” that's in my database.  In my base page, I retrieve that Custom Attribute and pull the appropriate skin piece for that page.

    Comments

    TrackBack said:

    # May 3, 2004 6:13 PM