Mike de Klerk
Mike de Klerk

Reputation: 12328

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

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:

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

Upvotes: 108

Views: 137846

Answers (8)

KodFun
KodFun

Reputation: 423

ASP.NET 7 short answer:

    app.UseRequestLocalization("en-US");

Note:

The localization middleware must be configured before any middleware that might check the request culture (for example, app.UseMvcWithDefaultRoute()).

For detailed explanation:

Implement a strategy to select the language/culture for each request in a localized ASP.NET Core app

Upvotes: 4

Hicham O&#39;Sfh
Hicham O&#39;Sfh

Reputation: 841

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

Upvotes: 2

benraay
benraay

Reputation: 863

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

Upvotes: 57

MindingData
MindingData

Reputation: 12470

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.

Upvotes: 34

Edi
Edi

Reputation: 2301

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.

Upvotes: 2

Reza Jenabi
Reza Jenabi

Reputation: 4279

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;

Upvotes: 30

ali zarei
ali zarei

Reputation: 1241

this worked for me

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

Upvotes: 3

Mike de Klerk
Mike de Klerk

Reputation: 12328

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;

Upvotes: 189

Related Questions