Tired of looking for errors in log files? Use OneTrueError - Automated exception management in .NET.

Better support for localization in ASP.NET.

If you’ve tried the built in localization features in ASP.NET you’ll probably written cluttered view models like:

 public class UserViewModel
{
    [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    [LocalizedDisplayName(ErrorMessageResourceName = "UserId", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    [LocalizedDescription(ErrorMessageResourceName = "UserIdDescription", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    public int Id { get; set; }

    [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    [LocalizedDisplayName(ErrorMessageResourceName = "UserFirstName", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    [LocalizedDescription(ErrorMessageResourceName = "UserFirstNameDescription", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    public string FirstName { get; set; }

    [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    [LocalizedDisplayName(ErrorMessageResourceName = "UserLastName", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    [LocalizedDescription(ErrorMessageResourceName = "UserLastNameDescription", ErrorMessageResourceType = typeof(Resources.LocalizedStrings))]
    public string LastName { get; set; }
}

I’ve solved that with my Griffin.MvcContrib project. But the solution is more of an hack than a solid approach.

The problem is really that there is no way to inject your own custom strings into the localization process of the DataAnnotation attributes. They use their own string tables (resource files) and that’s it. Well, unless you use attribute properties as shown above.

A much cleaner approach would be if the attributes asked a central class about the strings. Something like:

public static class LocalizationStringProvider
{
    public static string GetValidationMessage(Type attributeType, string text)
    {
        // scan registered providers after the text
    }
    
    public static string GetModelText(Type model, string propertyName, string metadataName)
    {
        // scan registered providers after the text
    }
    
    // add a new one
    public void Register(ILocalizationStringProvider provider)
    {
    }
    
    // remove all providers
    public void Clear()
    {}
}

Which in turn will get it’s text from a registered provider:

public interface ILocalizationStringProvider
{
    string GetValidationMessage(Type attributeType, string text);
    string GetModelText(Type model, string propertyName, string metadataName);
}

In this way we can by ourself choose if we want to use string tables, a SQL database, flat files or any other source. It will also work for attributes like the ASP.NET MVC CompareAttribute which requires to get a localized version of the property name which it’s compared to.

Hence to customize the localization of model and validation strings would simply be:

LocalizationStringProvider.Clear();
LocalizationStringProvider.Add(new MySqlProvider());

Summary

Vote at uservoice.com if you like this idea and want it implemented in ASP.NET.

Disclaimer: The decision of using a static class in this example was chosen since it’s how the other extension points of ASP.NET is made.

This entry was posted in Architecture, CodeProject and tagged , . Bookmark the permalink.
  • http://twitter.com/asapostolov Apostol Apostolov

    If you’r looking for a decent library for localization to get ideas from you can take a look at https://github.com/danielcrenna/i18n . It’s a little hard to comprehend but once you start using it – it’s a pleasure to work with. And it’s approach is similar to the one you describe in here – with central place to get the localized string from.

    • JonasGauffin

      Thank you for the comment. This post is however just an elaboration of the suggestion for the ASP.NET user voice site. The link is at the bottom of the post.

  • http://twitter.com/gblmarquez Gabriel Marquez

    As always simple is good and if you could make it simple it’s better.

  • Yustme

    Hi,

    I just voted you with 3. Can you update your request with support for localization for enums? That one is a pain in the ass!