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.
0 Comments