Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a link to switch language in ASP.NET Core 2.2?

A website supports several languages. The code to support multi-language including the routes are already in place and working.

The localization is set up using the RouteDataRequestCultureProvider as explaned at https://joonasw.net/view/aspnet-core-localization-deep-dive.

app.UseRouter(routes =>
{
    routes.MapMiddlewareRoute("{culture=en-US}/{*mvcRoute}", subApp =>
    {
        subApp.UseRequestLocalization(localizationOptions);

        subApp.UseMvc(mvcRoutes =>
        {
             // Routes are here
        }   
    });
});

How to create a generic tag which will show the current page in a different language?

Ideally, I would just specify which language this link should point to and that it should keep all other route parameters (like the current controller, the current action, the current route model) so I can have this link in the _Layout.cshtml?

like image 295
alik Avatar asked Apr 02 '19 10:04

alik


People also ask

How do I redirect in middleware net core?

In a browser with developer tools enabled, make a request to the sample app with the path /redirect-rule/1234/5678 . The regular expression matches the request path on redirect-rule/(. *) , and the path is replaced with /redirected/1234/5678 . The redirect URL is sent back to the client with a 302 - Found status code.

How do I use MapControllerRoute?

MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); The route names give the route a logical name. The named route can be used for URL generation. Using a named route simplifies URL creation when the ordering of routes could make URL generation complicated.


1 Answers

I managed to do this with the partial view for language dropdown list.

  • First get a list of supported cultures by injecting RequestLocalizationOptions to the partial view
  • Collect route data values and query string parameters as well into a dictionary, so if you have a link like below it will catch all parameters.

    /en-US/Products/?page=5&keyword=bla-bla-bla

  • Loop in the supported cultures to create links and replace {culture} route value with the appropriate in the loop. The only thing to consider is to have {culture} defined in the global route.

here is my _Languages.cshtml partial view:

@using Microsoft.AspNetCore.Builder
@using Microsoft.Extensions.Options

@inject IOptions<RequestLocalizationOptions> LocOps

@{
    var requestCulture = CultureInfo.CurrentCulture;

    var supportedCultures = LocOps.Value.SupportedUICultures

        .Select(c => new SelectListItem
        {
            Value = $"{c.Name}",
            Text = $"{c.DisplayName}"
        }).ToList();

    var routeData = new Dictionary<string, string>();

    foreach (var r in ViewContext.RouteData.Values)
    {
        routeData.Add(r.Key, r.Value.ToString());
    }

    foreach(var qs in Context.Request.Query)
    {
        routeData.Add(qs.Key, qs.Value);
    }
}

<div class="dropdown">
    <a class="btn-sm btn-default border border-secondary dropdown-toggle" href="#" role="button" id="dropdownLang" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        @($"{requestCulture.DisplayName}")
    </a>

    <div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownLang">
        @foreach (var culture in supportedCultures)
        {
            if (culture.Value.ToLower() != requestCulture.Name.ToLower())
            {
                // replace {culture} value with the one from the list
                routeData["culture"] = culture.Value;

                <a class="dropdown-item small"
                   asp-all-route-data="@routeData">
                    @culture.Text
                </a>
            }
        }
    </div>
</div>

btw, I'm using bootstrap 4.

UPDATE

I created a nuget package that creates a language navigation menu with one line of code :)

  • install nuget package
PM > Install-Package LazZiya.RazorLibrary -Version 1.0.1
  • create a language navigaton dropdown:
<partial name="/Areas/LazZiya/Pages/_LanguageMenu.cshtml" />

compatible with .NetCote 2.1 or later and bootstrap 4

  • notice : Route key name must be culture

UPDATE 2 (14.04.2019)

I created a tag helper that supports all versions of current dotnet core frameworks to create a language navigation depending on supported cultures or manually selected list of cultures.

install nuget package (it contains another useful tag helpers as well):

Install-Package LazZiya.TagHelpers -Version 2.0.0

add tag helpers to _ViewImports.cshtml

@addTagHelper *, LazZiya.TagHelpers

Create the language naviation :

<language-nav view-context="ViewContext"></language-nav>

for more details visit project website, see live demos


like image 80
LazZiya Avatar answered Sep 29 '22 02:09

LazZiya