Как показать текущую культуру в URL в ядре .net? - PullRequest
0 голосов
/ 16 мая 2019

Я пытаюсь реализовать локализацию в .Netcore, но я застрял в одном: как показать текущую культуру в URL.Я проверял и пробовал много вещей, но я не в состоянии заставить это работать.Я покажу, что я реализовал.

при моем запуске ConfigureServices:

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();

services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]
    {
        new CultureInfo("de"),
        new CultureInfo("en")
    };

    options.DefaultRequestCulture = new RequestCulture(culture: "de", uiCulture: "de");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
    options.RequestCultureProviders = new List<IRequestCultureProvider>
    {
        new QueryStringRequestCultureProvider(),
        new CookieRequestCultureProvider()
    };
});

Запуск Настройка:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
    app.UseRequestLocalization(locOptions.Value);
    var culture = locOptions.Value.DefaultRequestCulture.Culture;

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStaticFiles();
    app.UseSession();

    //configuring mvc routes...
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "areaRoute",
            template: "{area:exists}/{controller}/{action}/{id?}",
            defaults: new { controller = "Home", action = "Index" });

        routes.MapRoute(
            name: "default",
            template: "{culture}/{controller}/{action}/{id?}",
            defaults: new { culture = culture, controller = "Home", action = "Index" });
    });
}

Я создал частичное представление и изменил культуру, какэта культура успешно меняется: -

[HttpPost]
public IActionResult ChangeLanguage(string culture, string returnUrl)
{
    Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
        new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
    );

    return LocalRedirect(returnUrl);
}

Теперь я хочу показать свою текущую культуру в URL, например, www.test.com/en/home/view

Я создал маршрут итакже настраивает культуру, но принимает только культуру по умолчанию, даже после того, как я изменил культуру.

Также, пожалуйста, скажите, это правильный способ реализации локализации, потому что я слишком запутался в этой теме.

Изменить: - Мне просто нужно, чтобы моя культура в URL была изменена, когда я изменяю культуру моего приложения.

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Удалите var culture = locOptions.Value.DefaultRequestCulture.Culture; в настройках, которые всегда устанавливают культуру в качестве культуры по умолчанию.

Ниже приведена демонстрационная версия для использования twoLetterLanguageName. Ссылка на этот учебник

1. Создайте RouteDataRequestCultureProvider класс:

public class RouteDataRequestCultureProvider : RequestCultureProvider
{
    public int IndexOfCulture;
    public int IndexofUICulture;

    public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
    {
        if (httpContext == null)
            throw new ArgumentNullException(nameof(httpContext));

        string culture = null;
        string uiCulture = null;

        var twoLetterCultureName = httpContext.Request.Path.Value.Split('/')[IndexOfCulture]?.ToString();
        var twoLetterUICultureName = httpContext.Request.Path.Value.Split('/')[IndexofUICulture]?.ToString();

        if (twoLetterCultureName == "de")
            culture = "de-DE";
        else if (twoLetterCultureName == "en")
            culture = uiCulture = "en-US";

        if (twoLetterUICultureName == "de")
            culture = "de-DE";
        else if (twoLetterUICultureName == "en")
            culture = uiCulture = "en-US";

        if (culture == null && uiCulture == null)
            return NullProviderCultureResult;

        if (culture != null && uiCulture == null)
            uiCulture = culture;

        if (culture == null && uiCulture != null)
            culture = uiCulture;

        var providerResultCulture = new ProviderCultureResult(culture, uiCulture);

        return Task.FromResult(providerResultCulture);
    }
}

2. И LanguageRouteConstraint класс

public class LanguageRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
    {

        if (!values.ContainsKey("culture"))
            return false;

        var culture = values["culture"].ToString();
        return culture == "en" || culture == "de";
    }
}

3.startup.cs:

services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new List<CultureInfo>
    {
        new CultureInfo("en"),
        new CultureInfo("de"),
    };

    options.DefaultRequestCulture = new RequestCulture(culture: "en", uiCulture: "en-US");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;

    options.RequestCultureProviders = new[]{ new RouteDataRequestCultureProvider{
        IndexOfCulture=1,
        IndexofUICulture=1
    }};

});

services.Configure<RouteOptions>(options =>
{
    options.ConstraintMap.Add("culture", typeof(LanguageRouteConstraint));
});

services.AddMvc()
    .AddRazorPagesOptions(options =>
    {
        options.Conventions.AddAreaFolderRouteModelConvention("Identity", "/Account/", model =>
        {
            foreach (var x in model.Selectors)
            {
                if (x.AttributeRouteModel.Template.StartsWith("Identity"))
                {
                    x.AttributeRouteModel = new AttributeRouteModel()
                    {
                        Order = -1,
                        Template = AttributeRouteModel.CombineTemplates(("{culture=en}"),
                            x.AttributeRouteModel.Template)
                    };
                }
            }
        });
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);  

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "MyArea",
        template: "{culture:culture}/{area:exists}/{controller=Home}/{action=Index}/{id?}");

    routes.MapRoute(
            name: "LocalizedDefault",
            template: "{culture:culture}/{controller}/{action}/{id?}");

    routes.MapRoute(
            name: "default",
            template: "{controller}/{action}/{id?}",
            defaults: new { controller = "Home", action = "Index" });
});

ТогдаВы можете изменить культуру в URL-адресе браузера напрямую, используя /en/Home/Privacy.

4.Для отображения культуры при ее изменении вы можете изменить URL-адрес перенаправления, чтобы он содержал культуру в ChangeLanguage action:

[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) }
        );
        var array = returnUrl.Split("/");
        if (array[1] == "en" || array[1] == "de")//returnUrl like ~/en/Home/privacy
        {
            array[1] = culture;
            return LocalRedirect(String.Join("/", array));
        }
        else// returnUrl like ~/Home/privacy
        {
            return LocalRedirect("/" + culture + returnUrl.Substring(1));
        }

    }

5.set asp-area для вашего действия в _SelectLanguagePartial.cshtml, используйте asp-area="", если действие находится в корневой области.

<form id="selectLanguage" asp-area="" asp-controller="Home" ...>...
</form>
0 голосов
/ 16 мая 2019

Я думаю, что ваш конфиг должен понравиться

    CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("nl"),
        new CultureInfo("en")
    };

    services.Configure<RequestLocalizationOptions>(options =>
    {
        options.DefaultRequestCulture = new RequestCulture("nl"); // your language here
        options.SupportedCultures = supportedCultures;
        options.SupportedUICultures = supportedCultures;
        options.RequestCultureProviders = new List<IRequestCultureProvider>
        {
            new QueryStringRequestCultureProvider(), // support query string to change language
            new CookieRequestCultureProvider()
        };
    });

QueryStringRequestCultureProvider

Некоторые приложения будут использовать строку запроса для установить культуру и UI культуры. Для приложений, которые используют куки или Подход заголовка Accept-Language, добавление строки запроса к URL полезно для отладки и тестирования кода. По умолчанию QueryStringRequestCultureProvider зарегистрирован как первый поставщик локализации в списке RequestCultureProvider. Вы передаете параметры строки запроса культура и пользовательский интерфейс. Следующий пример устанавливает особую культуру (язык и регион) для испанского / мексиканского языка:

http://localhost:5000/?culture=es-MX&ui-culture=es-MX

Если вы передадите только один из двух (культура или пользовательский интерфейс), запрос Строковый провайдер установит оба значения, используя то, которое вы передали. Например, установка только культуры установит и Культуру, и UICulture:

http://localhost:5000/?culture=es-MX

...