Tauwin
Tauwin

Reputation: 33

ASP.NET 5.0 - How to get CookieRequestCultureProvider up and running

Localization - Settings

I can't get the localization to work using a cookie. I would be very happy to understand how to eventually incorporate this technology. I have to say that I am new to the developer world and have tried to research all approaches on the Internet in order to solve this problem on my own.

The default settings in Startup.cs are understandable for me so far. In the other classes, I have to go over to understanding again. I currently have no idea how and where to use the CookieRequestCultureProvider class to get the website's cookie functionality to work.

Thanks in advance.

PS: I worked on the following tutorials.
https://www.mikesdotnetting.com/article/345/localisation-in-asp-net-core-razor-pages-cultures
https://www.mikesdotnetting.com/article/346/using-resource-files-in-razor-pages-localisation

The following are my current settings:

dotnet --info

.NET SDK (reflecting any global.json):
 Version:   5.0.301
 Commit:    ef17233f86

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\5.0.301\

Host (useful for support):
  Version: 5.0.7
  Commit:  556582d964

.NET SDKs installed:
  5.0.301 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.16 [C:\ProgramFiles\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

startup.cs | ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    // Localization - adding resource path
    services.AddLocalization(options => 
    {
        // We will put our translations in a folder called Resources
        options.ResourcesPath = "Resources";
    });

    // Localization - look up MS docs
    // Add framework services.
    services.AddMvc()
        // adding localization for views
        .AddViewLocalization()
        // e.g. [Display(Name = "Remember Me?")]
        .AddDataAnnotationsLocalization(options => 
        {
            options.DataAnnotationLocalizerProvider = (type, factory) =>
            {
                var assemblyName = new AssemblyName(typeof(CommonResources).GetTypeInfo().Assembly.FullName);
                return factory.Create(nameof(CommonResources), assemblyName.Name);
            };
        });

    // we are configuring the localization service to support a list of provided cultures.
    services.Configure<RequestLocalizationOptions>(options =>
    {
        // Localization - the list of supported cultures
        // combination of parent language and region
        var supportedCultures = new List<CultureInfo>
        {
            new CultureInfo("de-DE"),
            new CultureInfo("en-GB"),
            new CultureInfo("nl-NL")
        };
        // State what the default culture for your application is. This will be used if no
        // specific culture can be determined for a given request.
        options.DefaultRequestCulture = new RequestCulture(
            culture: supportedCultures[0],
            uiCulture: supportedCultures[0]);

        // You must explicitly state which cultures your application supports.
        // These are the cultures the app supports for formatting numbers, dates, etc.
        options.SupportedCultures = supportedCultures;

        // UI strings that we have localized
        options.SupportedUICultures = supportedCultures;
    });

    ...
}

startup.cs | Configure

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider services)
{
   ...
app.UseRouting();

    // Localization - middleware
    // 1.QueryStringRequestCultureProvider – culture and ui - culture are passed in the query string.
    // 2.CookieRequestCultureProvider – culture is set in the ASP.NET Core culture cookie.
    // 3.AcceptLanguageHeaderRequestCultureProvider – which gets the culture from the browser’s language set by the user.
    // specify that globalization is being used in the pipeline.
    var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
    app.UseRequestLocalization(locOptions.Value);

   ...

   app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Culture Switcher Razor Component

<div>
    <form id="culture-switcher">
        <select name="culture" id="culture-options">
            <option></option>
            @foreach (var culture in Model.SupportedCultures)
            {
                <option value="@culture.Name" selected="@(Model.CurrentUICulture.Name == culture.Name)">@culture.ThreeLetterWindowsLanguageName</option>
            }
        </select>
    </form>
</div>

<script>
    document.getElementById("culture-options").addEventListener("change", () => {
        document.getElementById("culture-switcher").submit();
    });
</script>

CommonLocalizationService.cs

using KarriereWebseiteRazor.Resources;
using Microsoft.Extensions.Localization;
using System.Reflection;

namespace KarriereWebseiteRazor.Services
{
    public class CommonLocalizationService
    {
        private readonly IStringLocalizer _localizer;

        public CommonLocalizationService(IStringLocalizerFactory factory)
        {
            var assemblyName = new AssemblyName(typeof(CommonResources).GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create(nameof(CommonResources), assemblyName.Name);
        }

        public string Get(string key)
        {
            return _localizer[key];
        }
    }
}

Upvotes: 1

Views: 1765

Answers (1)

Mike Brind
Mike Brind

Reputation: 30045

Perhaps the simplest way to achieve what you want is to change the JavaScript in the ViewComponent to set the cookie:

const cultureOptions = document.getElementById("culture-options");
cultureOptions.addEventListener("change", () => {
    const culture = cultureOptions.value;
    document.cookie = `.AspNetCore.Culture=c=${culture}|uic=${culture}`;
    location.reload()
});

Upvotes: 2

Related Questions