We are currently building a mid-sized intranet application using MVC3. One requirement is the possibility to change and translate field names and labels on the fly. We are currently using extended versions of ViewPage
, ViewMasterPage
and ViewUserControl
enriched by an translation helper injected by spring.net to achieve this requirement.
This solution solves all requirements except MVC features that rely on ModelMetadata
(e.g. LabelFor
). My first thought was that there should be an extension point to replace the current implementation. Luckily the MVC team build ModelMetadataProviders
in a way that I can inject a custom translation aware DataAnnotationsModelMetadataProvider
.
protected override ModelMetadata CreateMetadata( IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName )
{
// Call the base method and obtain a metadata object.
var metadata = base.CreateMetadata( attributes, containerType, modelAccessor, modelType, propertyName );
if( containerType != null )
{
// Obtain informations to query the translator.
var objectName = containerType.FullName;
var displayName = metadata.GetDisplayName();
// Query the translator.
var translatedDisplayName = Translator.Translate( objectName, displayName );
// Update the metadata.
metadata.DisplayName = translatedDisplayName;
}
return metadata;
}
I'm using the containerType
and GetDisplayName()
as key to obtain a translation from a translation contributor (that uses caching, does not degrade performance), then calling base and change the returned ModelMetadata
by updating the DisplayName
property before returning it.
What makes me unconfident about this solution is that I can't predict what side effects I have to expect? Or if there is a better, proper solution?
Yes, this is the valid usage.
Make sure you derive from
DataAnnotationsModelMetadataProvider
as you do to reuse all the features it provides.You can also handle more custom attributes here - you can decorate your model with your own custom attributes and then update
ModelMetadata
based on them.