ASP.NET Core Razor Pages:默认文化下生成URL移除/lang路由段的方法
解决ASP.NET Core默认文化下URL自动移除语言段的问题
针对你在.NET 8 ASP.NET Core项目中遇到的默认文化(ru-RU)生成URL时带/ru段的问题,无需在每个链接里写条件判断,可以通过自定义路由出站转换器+本地化配置来解决,具体步骤如下:
1. 配置本地化选项
首先明确默认文化和支持的文化,同时配置基于路由的文化提供器:
builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("ru-RU"), new CultureInfo("en-US") }; // 设置默认文化为ru-RU options.DefaultRequestCulture = new RequestCulture("ru-RU"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; // 添加路由文化提供器,从路由参数lang中获取文化 options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider { RouteDataStringKey = "lang", UIRouteDataStringKey = "lang", Options = options }); });
2. 自定义路由出站转换器
创建一个实现IOutboundParameterTransformer的类,用于生成URL时自动移除默认文化的语言段:
public class LanguageRouteTransformer : IOutboundParameterTransformer { private readonly RequestLocalizationOptions _localizationOptions; public LanguageRouteTransformer(IOptions<RequestLocalizationOptions> localizationOptions) { _localizationOptions = localizationOptions.Value; } public string TransformOutbound(object value) { if (value is string lang) { var defaultLang = _localizationOptions.DefaultRequestCulture.Culture.TwoLetterISOLanguageName; // 如果是默认文化的语言代码,返回空字符串,URL中将不包含lang段 if (lang.Equals(defaultLang, StringComparison.OrdinalIgnoreCase)) { return string.Empty; } // 非默认文化返回小写的语言代码 return lang.ToLowerInvariant(); } return null; } }
3. 配置路由约束(可选但推荐)
定义路由约束,确保lang参数仅支持指定的语言代码(en/ru)或空值:
public class LanguageRouteConstraint : IRouteConstraint { private readonly HashSet<string> _supportedLangs = new() { "en", "ru" }; public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (values.TryGetValue(routeKey, out var value)) { // 出站生成URL时,空值对应默认文化,允许通过 if (routeDirection == RouteDirection.UrlGeneration && value == null) { return true; } // 入站请求或指定lang时,检查是否为支持的语言 return value is string lang && _supportedLangs.Contains(lang.ToLowerInvariant()); } return false; } }
然后在服务中注册这个约束:
builder.Services.Configure<RouteOptions>(options => { options.ConstraintMap.Add("lang", typeof(LanguageRouteConstraint)); });
4. 配置路由(Razor Pages或MVC)
针对Razor Pages:
app.UseRequestLocalization(); app.MapRazorPages() .AddRouteTransformer<LanguageRouteTransformer>();
然后在页面模型中配置路由模板(以Index页面为例):
[PageRoute("{lang:lang?}")] public class IndexModel : PageModel { public void OnGet() { } }
针对MVC控制器:
app.UseRequestLocalization(); app.MapControllerRoute( name: "localized", pattern: "{lang:lang}/{controller=Home}/{action=Index}/{id?}", defaults: new { lang = RouteParameter.Optional }) .AddRouteTransformer<LanguageRouteTransformer>();
5. 生成链接
现在你可以直接使用常规的链接生成语法,无需手动写条件判断:
<!-- 当前文化为ru-RU时,生成https://localhost/;为en-US时生成https://localhost/en --> <a asp-page="/Index">Home</a> <!-- 切换语言的链接:点击Русский会跳转到根路径,点击English跳转到/en --> <a asp-page="/Index" asp-route-lang="ru">Русский</a> <a asp-page="/Index" asp-route-lang="en">English</a>
这样配置后,默认文化(ru-RU)下生成的URL会自动移除/ru段,完全符合你的需求,且不需要在每个链接中写条件判断。
内容的提问来源于stack exchange,提问作者AlexB
相关产品推荐
相关产品推荐

