创建多语言翻译路线

时间:2019-03-09 14:57:39

标签: c# asp.net-mvc asp.net-core

我想在ASP.NET Core中创建一个路由系统,在该系统中将url转换为与此问题How to create multilingual translated routes in Laravel

相同的位置

目标是翻译网址路径中位于语言代码之后的部分,并以用户语言生成网址。

例如:

/fr/produit

将变成英语:

/en/product

我有以下配置:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {   
        services.Configure<RequestLocalizationOptions>(options =>
        {
            var translations = services.BuildServiceProvider().GetService<TranslationsDbContext>();
            var supportedCultures = translations.Cultures
                .ToList()
                .Select(x => new CultureInfo(x.Name))
                .ToArray();

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

            options.RequestCultureProviders = new RequestCultureProvider[]
            {
                new RouteDataRequestCultureProvider()
                {
                    RouteDataStringKey = "lang",
                    UIRouteDataStringKey = "lang",
                    Options = options
                },
                new CookieRequestCultureProvider(),
                new AcceptLanguageHeaderRequestCultureProvider()
            }; 
        });

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

        services.AddDbContextPool<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));

        services.AddDbContext<TranslationsDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("TranslationsConnection")));

        services.AddIdentity<User, IdentityRole<Guid>>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddSingleton<IStringLocalizerFactory, EFStringLocalizerFactory>();
        services.AddScoped<IStringLocalizer, StringLocalizer>();

        services
            .AddMvc()
            .AddDataAnnotationsLocalization();

    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
        ApplicationDbContext dbContext, TranslationsDbContext translationsDbContext,
        UserManager<User> userManager, RoleManager<IdentityRole<Guid>> roleManager)
    { 
        app.UseRequestLocalization();

        app.UseWhen(
            context => !context.Request.Path.StartsWithSegments("/api"),
            a => a.UseLocalizedStatusCodePagesWithReExecute("/{0}/error/{1}")
        );

        app.UseResponseCompression();

        app.UseCookiePolicy();

        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "localized",
                template: "{lang:lang}/{controller=Home}/{action=Index}/{id?}"
            );
            routes.MapRoute(
                name: "catchAll",
                template: "{*catchall}",
                defaults: new { controller = "Home", action = "RedirectToDefaultLanguage" }
            );
        });
    }
}

public class LanguageRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (!values.ContainsKey("lang"))
        {
            return false;
        }

        var lang = values["lang"].ToString();

        return lang == "fr" || lang == "en" || lang == "de";
    }
}

应用程序正确处理了语言代码。

但是,经过大量研究,我发现我可以使用IApplicationModelConvention自定义路由的工作方式。但是我不明白如何使用此界面来处理现有配置。

0 个答案:

没有答案