0

I'm looking for something similar like the old behaviour of setting the Culture and everything in the request after that has that Culture.

Similar like ASP.NET 4.5:

Thread.CurrentThread.CurrentCulture     = culture_info; 
Thread.CurrentThread.CurrentUICulture   = culture_info;

When I do this right now, some code seems to be constantly resetting the Culture to English at various points in the MVC pipeline.

Why do I want that? Because I want to set the culture through my extended routing logic in a very large (and customizable) platform-type of web project.

The default RouteDataRequestCultureProvider doesn't seem to work at all - see explained here:

https://irensaltali.com/en/asp-net-core-mvc-localization-by-url-routedatarequestcultureprovider/

and

Localization works when culture is set via QueryString but not when culture is in route

I don't want to use the "hardcoded" url parsing that is being presented as a solution, because my routing logic is complicated - not all routes will have a culture defined in the same spot in the URL.

I tried setting this, but that also didn't work:

httpContext.Features.Set<IRequestCultureFeature>(new RequestCultureFeature(request_culture, new DummyProvider()));

Is there any workaround for just simply setting the Culture for the rest of the request?

Dirk Boer
  • 7,770
  • 11
  • 56
  • 99

1 Answers1

0

A workaround for simply setting the Culture for the rest of the request is to use default QueryStringRequestCultureProvider.

Here is the whole demo:

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddLocalization(options => options.ResourcesPath = "Resources");

    services.AddControllersWithViews()
            .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
            .AddDataAnnotationsLocalization();
    //...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    var supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("de"),
        new CultureInfo("fr"),
    };

    app.UseRequestLocalization(new RequestLocalizationOptions
    {
        DefaultRequestCulture = new RequestCulture("en-US"),
        // Formatting numbers, dates, etc.
        SupportedCultures = supportedCultures,
        // UI strings that we have localized.
        SupportedUICultures = supportedCultures
    });

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Create Resource folder and add resource file as below:

enter image description here

Configure resource file like below:

Controllers.HomeController.de.resx

enter image description here

Controllers.HomeController.fr.resx

enter image description here

Reference:Resource file naming

Controller:

public class HomeController : Controller
{
    private readonly IStringLocalizer<HomeController> _localizer;

    public HomeController(IStringLocalizer<HomeController> localizer)
    {
        _localizer = localizer;
    }

    public IActionResult Index()
    {
        ViewData["Title"] = _localizer["Your Title"];
        return View();
    }
}

Index.cshtml:

@ViewData["Title"]

Result: enter image description here

Rena
  • 23,238
  • 5
  • 24
  • 53
  • Hi @Rena, thanks for your very extended answer - even a GIF! :O For me it's a prerequisite that I can set the culture during routing - so between routing and actually creating the controller. I can't use the QueryString version. – Dirk Boer Jun 02 '20 at 08:29
  • Did you mean you want to add the culture to the route? – Rena Jun 02 '20 at 08:44
  • Yeah - during some rather complicated (xml based) own routing logic - I'm not using the default routing. But I even wat more freedom - I just want to say at a certain point in the request: from now on everything will be this culture during this request. – Dirk Boer Jun 02 '20 at 08:47
  • Could you share how did you configure your routing?And it seems you want to set the culture for one time and the other request would use this culture?And which location you want to add the culture to the route? – Rena Jun 02 '20 at 08:52
  • Hi @Rena - I'm sorry it's a large library-kind-of-project where I route by using a centralized xml file - I think it's a bit out of the scope of the question. Mainly I'm just looking for *control*. I just want to set Thread.CurrentCulture and hope it is being honored. As a lot of .NET Core is customizable I hope also this is. – Dirk Boer Jun 02 '20 at 09:02