99

I'm going mad. I just want the culture used in the entire Asp.net core application to be set to "en-US". But nothing seems to work. Where to I set the culture for the entire application? I'm not interested in client browser cultures and what not. The only thing that seems to change it is changing the language settings of Windows. I just want the culture to be determined from within the application itself, not by the client.

What I have tried so far:

  • Set <system.web><globalization uiCulture="en" culture="en-US" /></system.web> in web.config
  • Set System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo; and CurrentUICulture in Startup.Configure and even in the controller.
  • Use app.UseRequestLocalization(.. as shown below

        var enUsCulture = new CultureInfo("en-US");
        var localizationOptions = new RequestLocalizationOptions()
        {
            SupportedCultures = new List<CultureInfo>()
            {
                enUsCulture
            },
            SupportedUICultures = new List<CultureInfo>()
            {
                enUsCulture
            },
            DefaultRequestCulture = new RequestCulture(enUsCulture),
            FallBackToParentCultures = false,
            FallBackToParentUICultures = false,
            RequestCultureProviders = null
        };
    
        app.UseRequestLocalization(localizationOptions);
    

But nothing seems to change the CurrencyDecimalSeparator from (nl-NL) , to (en-US).

How can the culture be set?

EDIT: @soren This is how the configure method looks like. I've put a breakpoint on DetermineProviderCultureResult but it is never hit while visiting the website.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, FinOsDbContext context)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseIdentity();

        // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

        //TODO: Clean up
        //var cultureInfo = new CultureInfo("en-US");
        //System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
        //System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;

        app.UseRequestLocalization();

        // UseCookieAuthentication..
        // UseJwtBearerAuthentication..

        //add userculture provider for authenticated user
        var requestOpt = new RequestLocalizationOptions();
        requestOpt.SupportedCultures = new List<CultureInfo>
        {
            new CultureInfo("en-US")
        };
        requestOpt.SupportedUICultures = new List<CultureInfo>
        {
            new CultureInfo("en-US")
        };
        requestOpt.RequestCultureProviders.Clear();
        requestOpt.RequestCultureProviders.Add(new SingleCultureProvider());

        app.UseRequestLocalization(requestOpt);

        FinOsDbContext.Initialize(context);
        FinOsDbContext.CreateTestData(context);
    }

    public class SingleCultureProvider : IRequestCultureProvider
    {
        public Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
        {
            return Task.Run(() => new ProviderCultureResult("en-US", "en-US"));
        }
    }
AFract
  • 8,868
  • 6
  • 48
  • 70
Mike de Klerk
  • 11,906
  • 8
  • 54
  • 76
  • 1
    .net core don't look at web.config anymore, but everything you had done was so right Mike. I have a few multilingual project in .net core 1.0.1. could you share more code from your Startup.cs... – Søren Nov 06 '16 at 08:40
  • 6
    Shouldn't `UseRequestLocalization` be placed _before_ `UseMvc`? Othewise Mvc will have already handled the request by the time the `UseRequestLocalization`middleware runs – Richard Szalay May 31 '18 at 23:19

7 Answers7

180

This is what solves it for me:

Setting the following in StartUp.Configure

var cultureInfo = new CultureInfo("en-US");
cultureInfo.NumberFormat.CurrencySymbol = "€";

CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
Vadim Ovchinnikov
  • 13,327
  • 5
  • 62
  • 90
Mike de Klerk
  • 11,906
  • 8
  • 54
  • 76
  • 1
    I was working with CsvHelper when I encoutered this problem. This trick worked out. Thanks! – Abhi Jun 26 '17 at 14:19
  • Mike has you seen the answer from user mindingdata ? It seems that is the way to go... – Pascal Feb 15 '18 at 21:00
  • @Pascal I've not tried it myself. If more people are upvoting your comment, or the other answer, I am of course willing to make that the accepted answer. Judge me, but I have no motivation right now to try it out myself :$. – Mike de Klerk Feb 19 '18 at 13:41
  • 1
    @Pascal UseRequestLocalization is a different thing, it does set the application to use the client locale, which is totally different from setting the culture globally for all users – Max Favilli Aug 21 '18 at 17:37
  • 10
    This comment is a little off-topic for this thread but worth mentioning for anyone who's using `en-US` as the thread culture in Europe: Please don't set US as the culture because it puts all dates into month-day-year format, which is *not* what all other countries outside of the USA use, and it only serves to confuse. If you're using English on a European website then please consider using `en-GB` in order to display the dates in the European format. Write US English. into your en-GB resource files if you really prefer but please don't set the UI culture as `en-US` on a European website. – awj Feb 18 '20 at 09:36
  • You can also put this in the `Main` function in `Program.cs` instead of in the `Startup.cs` file. – Fred Apr 08 '21 at 09:06
  • This worked for me for the Blazor server-side and I was able to change the culture without the use of cookies – Amer Jun 11 '21 at 02:50
54

A bit late but here is what worked for me:

var defaultDateCulture = "fr-FR";
var ci = new CultureInfo(defaultDateCulture);
ci.NumberFormat.NumberDecimalSeparator = ".";
ci.NumberFormat.CurrencyDecimalSeparator = ".";

// Configure the Localization middleware
app.UseRequestLocalization(new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture(ci),
    SupportedCultures = new List<CultureInfo>
    {
        ci,
    },
    SupportedUICultures = new List<CultureInfo>
    {
        ci,
    }
});
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
benraay
  • 783
  • 8
  • 14
  • 2
    IMHO, here's a nice article explaining what's going on: https://dotnetcoretutorials.com/2017/06/22/request-culture-asp-net-core/ – Dejan Jan 31 '19 at 21:51
  • tested and worked good on dotnet 6 also, just add before `app.UseRouting();` line. – Hicham O-Sfh May 28 '22 at 15:33
32

Your code looks all fine. The issue is your call to

app.UseRequestLocalization(...);

Needs to happen before your call to

app.UseMvc();

The reason your breakpoint is never hit is because it never goes that far. UseMVC completes the request and returns the result. Remember, Middleware happens in order and any one of the middleware can shortcircuit the process and halt processing going any further.

Chris F Carroll
  • 11,146
  • 3
  • 53
  • 61
MindingData
  • 11,924
  • 6
  • 49
  • 68
29

Localization is configured in the Startup.ConfigureServices method:

CultureInfo[] supportedCultures = new[]
           {
            new CultureInfo("ar"),
            new CultureInfo("fa"),
            new CultureInfo("en")
        };

        services.Configure<RequestLocalizationOptions>(options =>
        {
            options.DefaultRequestCulture = new RequestCulture("ar");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
            options.RequestCultureProviders = new List<IRequestCultureProvider>
                {
                    new QueryStringRequestCultureProvider(),
                    new CookieRequestCultureProvider()
                };

        });

Startup.Configure method

 app.UseRequestLocalization();

then UseRequestLocalization initializes a RequestLocalizationOptions object. This should be placed atleast before your UseMvc call

Change Culture:

[HttpPost]
public IActionResult SetLanguage(string culture, string returnUrl)
{
    Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(new     RequestCulture(culture)),
    new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
    );

    return LocalRedirect(returnUrl);
}

Current language:

var currentLanguage = HttpContext.Features.Get<IRequestCultureFeature>().RequestCulture.Culture.Name;
Reza Jenabi
  • 3,884
  • 1
  • 29
  • 34
2

this worked for me

 Response.Cookies.Append(
         CookieRequestCultureProvider.DefaultCookieName,
         CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(lang)),
         new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
        );
ali zarei
  • 1,212
  • 11
  • 17
2

Only configuring in startup didn't work for me

 services.Configure<RequestLocalizationOptions>(options =>
            {
                var ksCultureInfo = new CultureInfo("sq");
                var enCultureInfo = new CultureInfo("en");
                var srCultureInfo = new CultureInfo("sr");

                ksCultureInfo.NumberFormat.NumberDecimalSeparator = ".";

                var supportedCultures = new[]
                {
                    ksCultureInfo,
                    enCultureInfo,
                    srCultureInfo
                };

                options.DefaultRequestCulture = new RequestCulture(culture: enCultureInfo, uiCulture: ksCultureInfo);
                options.SupportedCultures = supportedCultures;
                options.SupportedUICultures = supportedCultures;
                options.RequestCultureProviders = new List<IRequestCultureProvider>
                {
                    new QueryStringRequestCultureProvider(),
                    new CookieRequestCultureProvider()
                };
            }); 

I added jquery globalize validation plugins: Then you need to use Globalize with jquery-validation-globalize plugin. Saw this here

Now it works as expected.

Edi
  • 1,900
  • 18
  • 27
2

Here is a quick answer based on the accepted one and the others :

var cultureInfo = new CultureInfo("fr-FR");
cultureInfo.NumberFormat.NumberDecimalSeparator = ".";
cultureInfo.NumberFormat.CurrencyDecimalSeparator = ".";
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

Tested and worked on : dotNet 6
PS : writed on program.cs (because there's no more Startup.cs file on Asp.net MVC 6), ensure that this lines of code are added before app.UseRouting(); line

nullPainter
  • 2,676
  • 3
  • 22
  • 42
Hicham O-Sfh
  • 731
  • 10
  • 12