ASP.NET Dynamic Data 4 – UI Table Localization


In my previous post I showed how simple it is to localize the field names in the Data Model, mainly for use with Dynamic Data in ASP.NET 4. This is done using the DisplayAttribute, but unfortunately it doesn’t work for objects of type Class, only Properties which relate to the fields or columns of the table or entity. So, I was looking for a quick-fix and having looked at Dynamic Data Preview 4, I decided to derive the MetaModel and MetaTable classes (both found in the System.Web.DynamicData namespace), like this:

Public Class MyMetaModel Inherits MetaModel
  Private resourceClass As String = Nothing

 Public Sub New()
 MyBase.New()
 End Sub

  Public Sub New(ByVal resourceClass As String)
 MyBase.New()

  If Not String.IsNullOrEmpty(resourceClass) Then
  Me.resourceClass = resourceClass
 End If
 End Sub

  Protected Overrides Function CreateTable(ByVal provider As TableProvider) As MetaTable
 If Not String.IsNullOrEmpty(Me.resourceClass) Then
  Return New MyMetaTable(Me, provider, resourceClass)
 End If

  Return New MyMetaTable(Me, provider)
 End Function
End Class

Public Class MyMetaTable Inherits MetaTable

 Private resource As String = Nothing

  Public Sub New(ByVal metaModel As MetaModel, ByVal tableProvider As TableProvider) MyBase.new(metaModel, tableProvider)
 End Sub

  Public Sub New(ByVal metaModel As MetaModel, ByVal tableProvider As TableProvider, ByVal resourceClass As String)
  MyBase.New(metaModel, tableProvider)

  resource = resourceClass
 End Sub

 ''' <summary> ''' Returns the name of the table for display.
 ''' </summary>
 ''' <value></value>
 ''' <returns>The table display name</returns>
 ''' <remarks>To localize the display name, the constructor with three parameters must be called, passing in the name of the global resource file. In addition, the display name of the table must be stored in the global resource file using a resource key of "Entity_" + the actual table name in the data model.</remarks> 
  Public Overrides ReadOnly Property DisplayName As String
 Get
  Dim tableDisplayName As String = Nothing

 ' Has a resource class been passed?
  If Not ResourceClass Is Nothing Then
 Try
  Dim tableName As String = "Entity_" & Me.Name

 ' Get the table name from the global resources
  tableDisplayName = HttpContext.GetGlobalResourceObject(ResourceClass, tableName).ToString()
 Catch ex As Exception
  Throw (New Exception(String.Format("A name for the table {0}, was not found in the global resource file named {1}.", Me.Name, ResourceClass)))
 End Try

  If Not String.IsNullOrEmpty(tableDisplayName) Then
  Return tableDisplayName
 End If
 End If

 Return MyBase.DisplayName
 End Get
 End Property

 Protected Overrides Sub Initialize()
 MyBase.Initialize()
 End Sub

  Private ReadOnly Property ResourceClass As Object
 Get
 Return Me.resource
 End Get
 End Property
End Class

This works, and because you generally instantiate the MetaModel object in Global.asax, there's no excuse for not passing in the name of the global resources file (.resx). Mind you, I have made the resource key prefix "Entity_" hardcoded, but feel free to change that as you please. Change this code in the Global.asax file:

Private Shared defaultModel As New MyMetaModel("DataStrings")

Public Shared ReadOnly Property DefaultMetaModel() As MyMetaModel
    Get
        Return defaultModel
    End Get
End Property
Advertisements