How to localize your webapp with Asp Net Core and DewLocalizationMiddleware

I’ve started to use Asp Net .core some month ago, and I like it. However, some approach used by default from the system like configuration options or localization for me are a little “old style”.

In this case, lets take the localization like example. Here how it works.

Defaults

The middleware has the DewLocalizationMiddlewareOptions type. If you don’t want customize anything you can just call the middleware with his Usexxx method. However you can customize a bit the middleware with the options.

Here the type with default values.

/// <summary>
/// DewLocalization options class
/// </summary>
public class DewLocalizationMiddlewareOptions
{
    /// <summary>
    /// Default language
    /// </summary>
    public string Language = "en-us";
    /// <summary>
    /// Default localization files path (not should start with "/" and should end with "/")
    /// </summary>
    public string Path = "Localization";
    /// <summary>
    /// Default cookie language name
    /// </summary>
    public string Cookie = "lang";
    /// <summary>
    /// Httpcontext item name
    /// </summary>
    public string CustomName = "DewLocalization";
}

Options

Language

By default the middleware assume the language “en-us”. Every language file must by a “<lang>.json” where <lang> is a choosed string from the cookie or the default language.

In default case the file is called “en-us.json”, obviously you can change the default value.

For example you can leave “en-us” like default value, and call the other files “fr-fr”,”it-it”,”it-ch”, etc. and use this notation in the cookie.

NOTE : default language works only when the call to the first file (for example “it-it”) fails.

Path

By default the middleware assume that the localization folder is in the main project folder and it’s called “Localization”.

You can change it, however be carefull that you don’t need to place the “/” at the end of the new Path string.

For example if you want place it into a directory called “Language/Dictionaries/it-it.json” Path must be “Language/Dictionaries”.

Cookie

This is just the language Cookie name. Call it how you want. Default value is “lang”.

CustomNameWORKS ONLY IN > V. 2.1.0

If you need a custom name for HttpContext item you can set it here, just remember to pass to GetDewLocalizationTranslator (HttpContext extension class method).

Default is “DewLocalization”

How add middleware to pipeline

//default
app.UseDewLocalizationMiddleware();
//or with options
app.UseDewLocalizationMiddleware(new DewLocalizationMiddlewareOptions()
{
    Cookie = "LanguageCookie",
    Path = "MyNewLocalizationPath"
});

NOTE : If no file are present, ever the default file, the middleware throw an exception.

Remember to add the:

using DewCore.AspNetCore.Middlewares;

to use the UseDewLocalizationMiddleware method

Use Translator like a service

If you don’t want use the localization middleware as middleware in the pipeline, you can use it like a service. This is how you can do it.

public void ConfigureServices(IServiceCollection services)
{
    //if you want use it with custom options
    services.AddScoped<IDewTranslator, DewTranslatorService>((sp) =>
    {
        var service = sp.GetRequiredService<IHostingEnvironment>();
        return new DewTranslatorService(new DewLocalizationMiddlewareOptions() { Language = "it-it" }, service);
    });
    //if you want use it with default options
    //->services.AddScoped<IDewTranslator,DewTranslatorService>();


    services.AddMvc();
}

In this case, you should use the dependency injection to get the translator:

public class HomeController : Controller
{
    IDewTranslator _translator = null;
    public HomeController(IDewTranslator translator)
    {
        _translator = translator;
    }
}

you can see in the next example how to work with it in both ways.

NOTE: if you set the translator as a service you cannot read the dictionary from HttpContext, and same is the inverse (if you use it like middleware it will not work with D-Injection)

NOTE: You can set both way (but why?)

Work with Translator

Middleware expose an Helper class, the DewTranslator.

If you want use it, you need to remember to add this into using section:

using DewCore.AspNetCore.Middlewares;

After that, in the controller.

//a method into a controller
public async Task<IActionResult> About()
{
    //if no item is setted with Default name or custom name, this method returns null
    var translator = HttpContext.GetDewLocalizationTranslator();
    // if you use the DewTranslator as a Service you should do
    await _translator.GetDictionaryFromFiles(HttpContext);
    ViewData["Message"] = translator.GetString("Your application description page."); //return the key as text if not found value
    //or _translator.GetString(...)_
    ViewData["Message"] = translator.GetString("Your application description page.", "Text not found!"); //return the second argument if key value not found
    //or
    ViewData["Message"] = translator["Your application description page."]; //however square notation throw an exception if key not exists
    return View();
}

Differences between service and middleware

The main difference is that in the middleware way the dictionary will be read automatically in a point of request pipeline, and you after this can use it just calling HttpContext.GetDewLocalizationTranslator().

In the service way, you just inject the object with its options to controller, but before you can use it, you need to read the dictionary by calling method GetDictionaryFromFiles(HttpContext)

After that, the use is the same.

Github

Source code

NuGet

You can find it on nuget with the name DewLocalizationMiddleware