Arbejder man med internationale web applikationer, er man nok
stødt på problemstillingen om, hvordan man oversætter sine sider.
Der findes mange metoder, men når nu man er lidt doven og gerne vil
undgå for meget arbejde, gælder det jo om at finde den metode som
involverer mindst arbejde. Desuden kan man jo lige så godt bruge de
metoder som frameworket tilbyder.
I mit arbejde med ASP.NET MVC 3 er jeg stødt på denne metode,
der muligvis kunne spare mig for noget kode og kompleksitet andre
steder i mit system. Det drejer sig om nedarvning af DataAnnotationsModelMetaDataProvider-klassen,
hvor metoden CreateMetadata
overstyres, således DisplayName-egenskaben oversættes. Det kunne se
nogenlunde således ud:
public class CustomModelMetadataProvider
: DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
var metaData = base.CreateMetadata(
attributes,
containerType,
modelAccessor,
modelType,
propertyName);
metaData.DisplayName =
metaData.GetDisplayName().Translate();
return metaData;
}
}
Den nye provider skal aktiveres i Global.asax, således den
bliver kaldt når dataannotations skal behandles. Dette gøres i
Application_Start således:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelMetadataProviders.Current =
new CustomModelMetadataProvider();
RegisterStorageConfiguration();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// ... og hvad vi ellers har...
}
Med dette på plads, kan (view)model udstyres med en nøgle til
oversættelsen. Det kunne se således ud:
public class Person
{
[Display(Name="First name")]
public string FirstName { get; set; }
[Display(Name="Last name")]
public string LastName { get; set; }
public string Address { get; set; }
}
Bemærk at for egenskaber uden Display-annotation vil det være
egenskabens navn er benyttes som nøgle til oversættelse. Nu vil
Person-objektets data kunne vises i et view således med oversatte
ledetekster:
@model Person
@{
Layout = null;
}
@Html.DisplayForModel()
Selve oversættelsen sker i Translate-funktionen, der i mit
tilfælde er en Extension på string-objektet og som slår op i et
datalager, hvor hver tekst er oversat til det aktuelle sprog.
Hvilket sprog der er tale om, hentes (af Translate extension
funktionen) i den aktuelle tråds UI Culture.