Localization Support for ValidatableBase

Localization Support

The included Validation Attributes now all support localization, allowing your failure messages to be presented to the user in the native language for global applications. In order to provide this in a cross-platform manor (iOS, Android and Windows), localization support must be handled with a couple levels of indirection.

Without localization, you would manually specify the FailureMessage like this:

[ValidateObjectHasValue(
    FailureMessage = "Email address must not be blank.",
    ValidationMessageType = typeof(ValidationErrorMessage))]
public string Email
{
    get
    {
        return this.email;
    }

    set
    {
        this.email = value;
        this.OnPropertyChanged("Email");
    }
}

Localization is done by specifying a localization key on your validation rules and omitting the FailureMessage property assignment like the following.

[ValidateObjectHasValue(
    LocalizationKey = "User-Email-Validation-Failure-Cannot-be-blank",
    ValidationMessageType = typeof(ValidationErrorMessage))]
public string Email
{
    get
    {
        return this.email;
    }

    set
    {
        this.email = value;
        this.OnPropertyChanged("Email");
    }
}

When validation is performed, and the Email property is null, a localized failure message will be assigned to the FailureMessage property.

In order to facilitate this, the validation rules fetch an implementation of IValidationLocalizationService from a new Factory, the ValidationLocalizationFactory. The API ships with a Windows App Store supported localization service in the Universal App Shared project.

The factory must provide this service to the validation rules. In order to do that, you must initialize the factory. This is demonstrated in the sample projects as well, in the App.Xaml.cs file.

public App()
{
    this.InitializeComponent();
    this.Suspending += this.OnSuspending;

    ValidationLocalizationFactory.Initialize<ValidationLocalizationService>();
}

The factory is initialized with our Windows App Store version of the localization service included in the sample project. The validation rules will use this service any time that it needs to fetch a localized string.

Another feature of the localization support are fallback messages. While you are developing the application, you often don't have all of the localization done. You can assign a value to both FailureMessage and LocalizationKey. The validation rule will try to fetch a localized string and if none exist, continue to use the specified FailureMessage. If it finds a localized string, it replaces the fallback value with the localized string for you.

The following demonstrates this:

[ValidateObjectHasValue(
    FailureMessage = "Email address can not be blank.", /* fallback if localization does not exist for the key yet */
    LocalizationKey = "User-Email-Validation-Failure-Cannot-be-blank",
    ValidationMessageType = typeof(ValidationErrorMessage))]
public string Email
{
    get
    {
        return this.email;
    }

    set
    {
        this.email = value;
        this.OnPropertyChanged("Email");
    }
}

You can create a custom implementation of IValidationLocalizationService for iOS and Android apps as well. Just initialize the ValidationLocalizationFactory with the Service type for each platform. This allows you to use localized text across all platforms that your app can run on, without making any changes to your models or building custom validation rules per-platform.

Check out the latest build over on the GitHub Repository.