[英]Route localization in ASP.NET Core 2.2
I am developing application using ASP.NET Core 2.2 and I am struggling with how to implement route localization, ex. 我正在使用ASP.NET Core 2.2开发应用程序,并且正在为如何实现路由本地化而苦苦挣扎。 depending on request I need to redirect to route /en/products, if language is not specified in the route.
如果未在路由中指定语言,则根据请求,我需要重定向到路由/ en / products。 If language is not specified then get locale from accept-language header.
如果未指定语言,则从accept-language标头获取语言环境。
Below demo is applied to use twoLetterLanguageName.Refer to this tutorial 下面的演示适用于使用twoLetterLanguageName。参考本教程
1.Create a RouteDataRequestCultureProvider
class: 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.And a LanguageRouteConstraint
class 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
: 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
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" });
});
}
Then you could change culture in browser url directly using /en/Home/Privacy
. 然后,您可以直接使用
/en/Home/Privacy
更改浏览器URL中的区域性。
If language is not specified then get locale from accept-language header
如果未指定语言,则从accept-language标头获取语言环境
You could use Url Rewriting Middleware to check the route value and redirect it to a new route with default culture. 您可以使用网址重写中间件来检查路由值,并将其重定向到具有默认区域性的新路由。
1.Create a Redirect rule: 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..Use the middleware in Startup Configure method: 2.在启动配置方法中使用中间件:
app.UseAuthentication();//before the Rewriter middleware
app.UseRewriter(new RewriteOptions()
.Add(RewriteRules.RedirectRequests)
);
//MVC middleware
Then if your input /Home/Privacy
in browser it will redirect to url like /en/Home/Privacy
. 然后,如果您在浏览器中输入
/Home/Privacy
,它将像/en/Home/Privacy
一样重定向到url。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.