Ant
no notes

Model Level Resource Declaration

Putting a DisplayAttribute on every property in your model is boring and a bit WET (not DRY anyway). You can instead, create an attribute for the model which you can hook into MVC for a one-stop display resource type thingy-ma-jig.

The Model

This Model is pretty simple, it has a DisplayAttribute on each property, which does exactly the same thing on each..

public class PersonModel {

    [Display(Name = "FirstName",
        ResourceType = typeof(LabelResources))]
    public string FirstName { get; set; }

    [Display(Name = "LastName", 
        ResourceType = typeof(LabelResources))]
    public string LastName { get; set; }
}

It would be better to do this..

[DisplayResource(typeof(LabelResources))]
public class PersonModel {

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

Especially as your model gets bigger, setting the resource type on the class and using the property name is enough to get your display name data

The DisplayResourceAttribute

This declares the type of resource to use for every property on the model

public class DisplayResourceAttribute : Attribute {

    public DisplayResourceAttribute(Type type) {
        Type = type;
    }

    public Type Type { get; private set; }
}

Now the clever bit

ASP.NET MVC 3 is more extendible than previous versions, you can introduce all manner of bespoke functionality using the new DependencyResolver methods. I am going to override the DataAnnotationsModelMetadataProvider in order to add my own logic to retrieve a suitable display value from the resource file for the properties in my model.

public class ApplicationModelMetadataProvider 
        : DataAnnotationsModelMetadataProvider {

    protected override ModelMetadata GetMetadataForProperty(
            Func<object> modelAccessor, 
            Type containerType,
            PropertyDescriptor propertyDescriptor) {
        var metaData = base.GetMetadataForProperty(
            modelAccessor, containerType, propertyDescriptor);

        // find the attribute
        var displayResourceAttr 
            = (DisplayResourceAttribute)containerType
                .GetCustomAttributes(
                    typeof(DisplayResourceAttribute), false)
                .FirstOrDefault();
        if(displayResourceAttr!=null) {

            // check for an entry in the resource file
            var displayProp = displayResourceAttr.Type
                .GetProperties()
                .FirstOrDefault(
                    p => p.Name.Equals(propertyDescriptor.Name));
            if(displayProp != null) {

                // set the value
                metaData.DisplayName 
                    = (string)displayProp.GetValue(null, null);
            }
        }

        return metaData;
    }
}

Now using DependencyResolver.SetResolver..

protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    DependencyResolver.SetResolver(
        t => {
            if (t == typeof (ModelMetadataProvider)) {
                return new ApplicationModelMetadataProvider();
            }
            return null;
        },
        t => {
            return new object[] {};
        });
}

Making sure you have a Resource file in your project with appropriate properties

in your view

@Html.LabelFor(model => model.Active)

Will render the value from your resource file

Post a Note

(required)

(required never shown)

On Twitter Follow MrAntix on Twitter

15/05/2012
WindowsAzure
Announcing the MEET Windows Azure Event! Streamed online June 7th. Register at http://t.co/bObzTAuL  #MEETAzure #WindowsAzure

10/05/2012
kevinwhinnery
Comparing Titanium and PhoneGap - A common question I get asked at developer events and conferences is how... http://t.co/Zq2eND6B

09/05/2012
brianleroux
PhoneGap goals and philosophy: http://t.co/wkq8wI2T

just now
satonaoki
RT @WindowsAzure: The Bing Search API on #WindowsAzure Marketplace is Here!  http://t.co/GLILFMYe

just now
itsacloudyworld
Latest The Bing Search API on Windows Azure Marketplace is Here! http://t.co/S9K9cRwm