默认情况下,内置的“请求本地化”中间件仅支持通过查询,Cookie或Accept-Language标头设置区域性。这个例子展示了如何创建一个中间件,该中间件可以将文化设置为路径中的一部分,例如in /api/en-US/products。
此示例中间件假定语言环境位于路径的第二段中。
public class UrlRequestCultureProvider : RequestCultureProvider { private static readonly Regex LocalePattern = new Regex(@"^[a-z]{2}(-[a-z]{2,4})?$", RegexOptions.IgnoreCase); public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext) { if (httpContext == null) { throw new ArgumentNullException(nameof(httpContext)); } var url = httpContext.Request.Path; // 目前无法使用httpContext.GetRouteData() // 因为它使用放在httpContext.Features中的IRoutingFeature //路由中间件寄存器。本地化中间件时未设置 // 被调用,因此此示例仅假设语言环境将始终 // 位于路径的第二段,例如/ api / en-US / products var parts = httpContext.Request.Path.Value.Split('/'); if (parts.Length < 3) { return Task.FromResult<ProviderCultureResult>(null); } if (!LocalePattern.IsMatch(parts[2])) { return Task.FromResult<ProviderCultureResult>(null); } var culture = parts[2]; return Task.FromResult(new ProviderCultureResult(culture)); } }
var localizationOptions = new RequestLocalizationOptions { SupportedCultures = new List<CultureInfo> { new CultureInfo("de-DE"), new CultureInfo("en-US"), new CultureInfo("en-GB") }, SupportedUICultures = new List<CultureInfo> { new CultureInfo("de-DE"), new CultureInfo("en-US"), new CultureInfo("en-GB") }, DefaultRequestCulture = new RequestCulture("en-US") }; // 将我们的UrlRequestCultureProvider添加为列表中的第一个对象 localizationOptions.RequestCultureProviders.Insert(0, new UrlRequestCultureProvider { Options = localizationOptions }); app.UseRequestLocalization(localizationOptions);
“路线约束”示例中显示了如何添加和创建自定义路线约束。使用约束简化了自定义路由约束的使用。
在不使用自定义约束的情况下注册路线的示例
app.UseMvc(routes => { routes.MapRoute( name: "default", template: "api/{culture::regex(^[a-z]{{2}}-[A-Za-z]{{4}}$)}}/{controller}/{id?}"); routes.MapRoute( name: "default", template: "api/{controller}/{id?}"); });