ASP.NET Core Request Localization Options

30,275

Solution 1

You can get Accept-Language header from the current Request and set default language. Your code should be something like this:

services.Configure<RequestLocalizationOptions>(options =>
{
    //...

    options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(context =>
    {                    
       //...
       var userLangs = context.Request.Headers["Accept-Language"].ToString();
       var firstLang = userLangs.Split(',').FirstOrDefault();
       var defaultLang = string.IsNullOrEmpty(firstLang) ? "en" : firstLang;
       return Task.FromResult(new ProviderCultureResult(defaultLang, defaultLang));
   }));
});

Solution 2

Another way to get the Accept-Language header with a framework call (ASP.NET Core):

HttpContext.Request.GetTypedHeaders().AcceptLanguage

Solution 3

Inside your public class Startup:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...

    app.Use((context, next) =>
    {
        //get client prefered language
        var userLangs = context.Request.Headers["Accept-Language"].ToString();
        var firstLang = userLangs.Split(',').FirstOrDefault();

        //set allowed alanguage
        var lang = "en"; //default
        switch (firstLang)
        {
            case "hy": //allowed
            case "ru": //allowed
                lang = firstLang; 
                break;
            default:
                //client language not supported
                lang = "en"; //use our default
                break;
        }

        //switch culture
        Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(lang);
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

        //save for later use
        context.Items["ClientLang"] = lang;
        context.Items["ClientCulture"] = Thread.CurrentThread.CurrentUICulture.Name;
        
        // Call the next delegate/middleware in the pipeline
        return next();
    });

    //... then goes app.UseMvc etc..

}

Solution 4

as an additional option, Here is a full solution: Handle culture in route (URL) via RequestCultureProviders

as an option as well, here is a simplified code for CustomRequestCultureProvider:

options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(context =>
{
    var lang = context.Request.GetTypedHeaders().AcceptLanguage.FirstOrDefault()?.Value.Value ?? Constants.Languages.EN_US;

    return Task.FromResult(new ProviderCultureResult(lang, lang));

}));
Share:
30,275

Related videos on Youtube

Sergey Sypalo
Author by

Sergey Sypalo

Microsoft Certified Solutions Expert, IT Professional and Systems Engineer in wide range of products with over a 10 years of hands-on experience. I'm expert in planning, testing, configuring, designing and deploying Active Directory, virtualization, messaging, systems management and monitoring servers, including multi-tiered antivirus and backup solutions in large complex networks.

Updated on August 13, 2020

Comments

  • Sergey Sypalo
    Sergey Sypalo over 3 years

    Here is my custom request culture provider which returns "en" as a default culture if no culture specified in url (for example http://sypalo.com/ru or http://sypalo.com/en). My idea to show website on that language which is default in user's browser, so I'm looking a way how to determine it and return it instead of: return Task.FromResult(new ProviderCultureResult("en", "en"));

    services.Configure<RequestLocalizationOptions>(options =>
    {
        var supportedCultures = new List<CultureInfo>
        {
            new CultureInfo("en"),
            new CultureInfo("ru")                            
        };
    
        options.DefaultRequestCulture = new RequestCulture(culture: "en", uiCulture: "en");
        options.SupportedCultures = supportedCultures;
        options.SupportedUICultures = supportedCultures;
    
        options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(context =>
        {                    
            var pathSegments = context.Request.Path.Value.Split('/');
            if (pathSegments.Count() > 0)
            if (supportedCultures.Select(x => x.TwoLetterISOLanguageName).Contains((pathSegments[1])))
                return Task.FromResult(new ProviderCultureResult(pathSegments[1], pathSegments[1]));
           return Task.FromResult(new ProviderCultureResult("en", "en"));
       }));
    });
    
  • Sergey Sypalo
    Sergey Sypalo over 7 years
    Thanks a lot Adem, this is exactly what I was looking for!
  • Evgeni Nabokov
    Evgeni Nabokov about 5 years
    Do not forget to order languages by its priority q, e.g. OrderByDescending(x => x.Quality ?? 1).