Локализация маршрутов в ASP.NET Core 2.2 - PullRequest
0 голосов
/ 23 мая 2019

Я разрабатываю приложение, используя ASP.NET Core 2.2, и я борюсь с тем, как реализовать локализацию маршрутов, напр.в зависимости от запроса мне нужно перенаправить на route / en / products, если язык не указан в маршруте.Если язык не указан, получите локаль из заголовка accept-language.

1 Ответ

2 голосов
/ 24 мая 2019

Ниже приведена демонстрационная версия для использования 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 ConfigureServices:

services.AddLocalization(options => options.ResourcesPath = "Resources");

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

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

4.startup.cs Configure

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
        app.UseRequestLocalization(options.Value);

        //other middlewares

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                   name: "LocalizedDefault",
                   template: "{culture:culture}/{controller}/{action}/{id?}",
                   defaults: new {controller = "Home", action = "Index" });
            //constraints: new { culture = new CultureConstraint(defaultCulture: "en", pattern: "[a-z]{2}") });

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

        });
    }

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

Если язык не указан, получить локаль из заголовка accept-language

Вы можете использовать Промежуточное программное обеспечение перезаписи URL , чтобы проверить значение маршрута и перенаправить его на новый маршрут с культурой по умолчанию.

1.Создайте правило перенаправления:

public class RewriteRules
{
    public static void RedirectRequests(RewriteContext context)
    {
        //Your logic

        var request = context.HttpContext.Request;
        var path = request.Path.Value;

        var userLangs = request.Headers["Accept-Language"].ToString();
        var firstLang = userLangs.Split(',').FirstOrDefault();
        var defultCulture = string.IsNullOrEmpty(firstLang) ? "en" : firstLang.Substring(0,2);

        //Add your conditions of redirecting
        if ((path.Split("/")[1] != "en") && (path.Split("/")[1] != "de"))// If the url does not contain culture
        {
            context.HttpContext.Response.Redirect($"/{defultCulture}{ request.Path.Value }");
        }

    }
}

2.Используйте промежуточное ПО в методе настройки запуска:

app.UseAuthentication();//before the Rewriter middleware

app.UseRewriter(new RewriteOptions()
        .Add(RewriteRules.RedirectRequests)
        );
//MVC middleware

Тогда, если ваш ввод /Home/Privacy в браузере, он будет перенаправлен на URL, как /en/Home/Privacy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...