XLocalizer for Asp.Net Core

Ziya Mollamahmut
The Startup
Published in
7 min readNov 13, 2020

Asp.Net Core localization, powered by online translation, auto resource creating and more...

Introduction

Developing a multi cultural web application requires building the localization infrastructure that will process the request localization and localize views, error messages, …etc. On the other hand; every localized culture requires at least one resource file, filled with all localized key-value pairs.

Building the localization infrastructure and filling the resource files can take a lot of time and effort. XLocalizer has been developed from scratch to solve these two issues and free the developer from unnesseary workload.

What does XLocalizer offers?

Simple localization setup: First of all, it is built to help developers create localized web applications easily without wasting time on developing localization infrastructure.

Auto localization: The most attractive two features of XLocalizer are Auto resource creating and Online translation. So, any missed key will be translated and added automatically to the relevant resource file.

Support for multiple resource types: By default, Asp.Net Core uses “.resx” resource files for storing localized strings. XLocalizer breaks the barriers by offering built-in localization stores (XML, RESX, DB). Additionally, custom resource types for any other file or db format can be implemented.

Flexiblity: XLocalizer is using the standard localization interfaces IStringLocalizer and IHtmlLocalizer, so it is easy to switch from the default .net core localization system to XLocalizer or vice versa. And with the help of built-in resource exportes, all localization resources can be exported from any file/db type to “.resx” file type.

Customization: XLocalizer can be customized in every detail to:

  • Use custom resource types (e.g. mysql, json, csv, …etc).
  • Use custom resource exporters to export resources from any source to any source.
  • Use custom translation services for translating resources.

Centralization: One single place to easily customize all validation errors, model binding erros and identity errors in a simple way.

How it works?

In this tutorial I will show how to use XLocalizer with XML resource files and online translation. To learn the setup of other resource types like resx, db or custom sources, kindly visit: https://DOCS.Ziyad.info.

XLocalizer Workflow

Installation

  • A few nugets is required to get the best of XLocalizer, first I will mention all pacakges, then we will see the role of each one in the next steps.
// The main package
PM > Install-Package XLocalizer
// Online translation support
PM > Install-Package XLocalizer.Translate
// Translation service
PM > Install-Package XLocalizer.Translate.MyMemoryTranslate
// Use html tags to localize views
PM > Install-Package XLocalizer.TagHelpers
// Additional taghelper package for language dropdown
PM > Install-Package LazZiya.TagHelpers
  • Resources folder: Under the project root create a new folder named “LocalizationResources”, then inside it create a new empty class named “LocSource”. This class will be used to access the relevant resource files from the code.
// Dummy class for grouping and accessing resource files
public class LocSource { }

No need to create culture specific resource files, they will be created and filled automatically by XLocalizer.

Setup XLocalizer

A small tip to speedup coding; VS2019 can automatically insert missing namespaces (using …). Or you can press (Crtl + . ) to view a context menu that will add the missing namespace.

  • Open startup file and configure request localization options as usual:
services.Configure<RequestLocalizationOptions>(ops => 
{
var cultures = new CultureInfo[] {
new CultureInfo("en"),
new CultureInfo("tr"),
...
}; ops.SupportedCultres = cultures;
ops.SupportedUICultures = cultures;
ops.DefaultRequestCulture = new RequestCulture("en");
// Optional: add custom provider to support localization
// based on route value
ops.RequestCultureProviders.Insert(0, new RouteSegmentRequestCultureProvider(cultures));
});

XLocalizer supports multiple resource types such as XML, RESX, DB, …etc. In this sample I will use XML files to store localized values, so we need to register the built-inXmlResourceProvider, this provider will help us to use XML files as resource files for storing localized key-value pairs.

services.AddSingleton<IXResourceProvider, XmlResourceProvider>();
  • One of the major benefits of XLocalizer is online translation support, so we need to register at least one translation service in startup file.
services.AddHttpClient<ITranslator, MyMemoryTranslateService>();

I used MyMemoryTranslateService during the developmet of XLocalizer, but you are free to choose any of the available translation services or even implement your own one.

  • Optionally configure razor pages to use route based localization provider, so we can have the url like: http://localhost:111/en/Index. Then configure XLocalizer in the same step:
services.AddRazorPages()
.AddRazorPagesOptions(ops =>
{
ops.Conventions.Insert(0, new RouteTemplateModelConventionRazorPages());
})
.AddXLocalizer<LocSource, MyMemoryTranslateService>(ops =>
{
ops.ResourcesPath = "LocalizationResources";
ops.AutoAddKeys = true;
ops.AutoTranslate = true;
ops.TranslateFromCulture = "en";
});
  • Configure the app to use localization middleware
app.UseRequestLocalization();

Adding API Key for the translation Service

MyMemory translate API’s offers free anonymous usage till 1000 words/day (for the time of writing this story). So basicly you don’t have to add any key to test it. Anyhow, you can increase the free usage till 30.000 words/day just by providing an email and a freely generated key. See MyMemory API usage limits for more details.

Use MyMemory API Keygen to get a key, then add the key with a valid email address to user secrets file as below:

{   
"XLocalizer.Translate": {
"MyMemory": {
"Email": "...",
"Key": "..."
}
}
}

Different translation services may require different setup. See translation services docs for details about setup of different translation services.

Complete XLocalizer Startup Code

Sample startup file with unnecessary code ommitted for simplification:

Sample startup file for XLocalizer setup based on Xml resource files and online translation

That is all the setup required in startup file. Next, we will configure views and backend localization.

Localizing Views

We have installed a handy nuget for localizing views XLocalizer.TagHelpers, this package makes it easy to localize views using html tag and html attributes, which keeps the html code clean and easy to read and maintain.

  • Add the taghelper in _ViewImports.cshtml file:
@addTagHelper *, XLocalizer.TagHelpers
  • Use localize-content attribute inside html tags to localize inner text/html:
<h1 localize-content>Welcome</h1>
  • Localize inner text/html paragraph with localize html tag:
<localize>
<h1>Welcome</h1>
<p>My contents...</p>
</localize>
  • Localize html string with arguments:
@{
var args = new object[] { "http://DOCS.Ziyad.info" }
}
<p localize-args="args">
Visit <a href="{0}">DOCS</a> for more details.
</p>
  • Localize html attributes like title:
<img src="../picture.jpg" localize-att-title="Nature picture" />

Below is the fully localized sample of Register.cshtml page, notice that we only need to add “localize-content” attribute to the relevant tag, that keeps the page code clean and makes it easy to read and update.

View localization sample with XLocalizer.TagHelpers

Localizing Validation Attrbiutes Errors, Model Binding Errors and Identity Error Messages

Localizing all framework error messages do not require any additional setup with XLocalizer, and it is not necessary to provide any error message inside the attribute tags! All error messages will be assigned and localized by the default setup of XLocalizer in startup.

Below is a sample use for some validation attributes.

[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }

Also for model binding errors and identity errors, we don’t have to do any additional setup, XLocalizer will take care of localizing all the error messages by default.

Below is a sample of backend localization of Register.cshtml.cs file:

Validation attributes usage without defining error messages

Customizing Error Messages

In some cases you may need to customize the error messages for validation attributes, model binding or identity. Or you may want to provide the default error messages in a culture other than “en”, so XLocalizer can do translate from the correct culture.

The first solution is to use inline options setup in startup file, by providing the relevant error messages as below:

Customizing error messages in startup file

The other option is to configure all XLocalizer settings in a json file.

JSON Settings

If you are a developer who likes to keep startup file clean “like me :)” you will be happy to know that you can do all these customizations in a json file and use only one line to read the configurations in startup.

{
"XLocalizerOptions" : {
"AutoAddKeys" : true,
"AutoTranslate" : true,
// ...
}
}
  • Setup XLocalizer to read the relevant configuration section:
services.AddRaqzorPages()
.AddXLocalizer<...>(ops => Configuration.GetSection("XLocalizerOptions").Bind(ops));
  • Below is a sample json settings for XLocalizer options with the customizable error messages:
See full settings here

So, this is a single place and simple way to customize all error messages. These messages will be translated to other cultuers by XLocalizer depending on the request culture.

Adding Language Navigation

Each multi cultural web application must provide a way to switch between different languages. You may have your own implementation for language navigation, but just in case you need to add one easily (we’ve installed LazZiya.TagHelpers earlier);

  • Add taghelpers to _ViewImports file:
@addTagHelper *, LazZiya.TagHelpers
  • Open _layout.cshtml and add the language navigation wher you need it to appear:
<language-nav></language-nav>

I highly recommed to setup the language navigation to configure culture cookie as described in the docs page here. So the culture choice can be stored in a cookie for later use.

Run The Application

If you have done all the steps correctly, and once you start the application take a look at the ouput window in VS to see the logs, you will see that XLocalizer has started to translate the views and insert values automatically. Additionally, all validation attributes, model binding and identity error also localized.

Sample screenshot of localized registration form

Notice: Localizing identity pages requires scaffolding the identity into the project.

All you need to add a new culture is; add the culture to the supported cultures in startup file, and keep all the rest to be done by XLocalizer :)

Supported .net core versions:

2.x, 3.x and 5.0

Supported project types:

Razor Pages, MVC, Blazor Server

References

--

--

Ziya Mollamahmut
The Startup

Software Developer, Regional Training Expert, 3D Modeling Hobbyist