Set CultureInfo in Asp.net Core to have a . as CurrencyDecimalSeparator instead of ,

C#asp.net Core

C# Problem Overview


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"));
        }
    }

C# Solutions


Solution 1 - C#

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;

Solution 2 - C#

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,
    }
});

Solution 3 - C#

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.

Solution 4 - C#

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;

Solution 5 - C#

this worked for me

 Response.Cookies.Append(
         CookieRequestCultureProvider.DefaultCookieName,
         CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(lang)),
         new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
        );

Solution 6 - C#

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMike de KlerkView Question on Stackoverflow
Solution 1 - C#Mike de KlerkView Answer on Stackoverflow
Solution 2 - C#benraayView Answer on Stackoverflow
Solution 3 - C#MindingDataView Answer on Stackoverflow
Solution 4 - C#Reza JenabiView Answer on Stackoverflow
Solution 5 - C#ali zareiView Answer on Stackoverflow
Solution 6 - C#EdiView Answer on Stackoverflow