Localising the DisplayAttribute in ASP.NET Core 1.1

This is a very quick post in response to a comment asking about the state of localisation for the DisplayAttribute in ASP.NET Core 1.1. A while ago I wrote a series of posts about localising your ASP.NET Core application, using the IStringLocalizer abstraction.

The IStringLocalizer is a new way of localising your validation messages, view templates, and arbitrary strings. If you're not familiar with localisation in ASP.NET Core, I suggest checking out my first post on localisation for the benefits and pitfalls it brings, but I'll give a quick refresher here.

Brief Recap

Localisation is handled in ASP.NET Core through two main abstractions IStringLocalizer and IStringLocalizer<T>. These allow you to retrieve the localised version of a string by essentially using it as the key into a dictionary; if the key does not exist for that resource, or you are using the default culture, the key itself is returned as the resource:

Resources are stored in .resx files that are named according to the class they are localising. So for example, the IStringLocalizer<ExampleClass> localiser would look for a file named (something similar to) ExampleClass.fr-FR.resx. Microsoft recommends that the resource keys/names in the .resx files are the localised values in the default culture. That way you can write your application without having to create any resource files - the supplied string will be used as the resource.

As well as arbitrary strings like this, DataAnnotations which derive from ValidationAttribute also have their ErrorMessage property localised automatically.

Finally, you can localise your Views, either providing whole replacements for your View by using filenames of the form Index.fr-FR.cshtml, or by localising specific strings in your view with another abstraction, the IViewLocalizer, which acts as a view-specific wrapper around IStringLocalizer.

Localising the DisplayAttribute in ASP.NET Core 1.0

Unfortunately, in ASP.NET Core 1.0, there was one big elephant in the room… You could localise the ValidationAttributes on your view models, but you couldn't localise the DisplayAttribute which would generate the associated labels!

That's a little unfair - you could localise the DisplayAttribute, it just required jumping through some significant hoops. You had to fall back to the ResourceManager class, use Visual Studio to generate .resx designer files, and move away from the simpler localisation approach adopted everywhere else. Instead of just passing a key to the Name or ErrorMessage property, you had to remember to set the ResourceType too:

These values will be used by the IStringLocalizer as keys in the resx files for localisation (or as the localised value itself if a value can't be found in the .resx). No fuss, no muss.

Note As an aside, I still really dislike this idea of using the English phrase as the key in the dictionary - it's too fragile for my liking, but at least you can easily fix that.

Summary

Localisation in ASP.NET Core still requires a lot of effort, but it's certainly easier than in the previous version of ASP.NET. With the update to the DisplayAttribute in ASP.NET Core 1.1, one of the annoying differences in behaviour was fixed, so that you localize it the same way you would your other DataAnnotations.

As with most of my blog posts, there's a small sample project demonstrating this on GitHub