Вот способ, которым вы можете сделать это, не требуя размещения атрибута промежуточного программного обеспечения на всех ваших страницах.Это работает глобально.
В методе ConfigureServices
файла Startup.cs добавьте следующее:
services.AddMvc().AddRazorPagesOptions(options => {
options.Conventions.AddFolderRouteModelConvention("/", model => {
foreach (var selector in model.Selectors) {
selector.AttributeRouteModel.Template = AttributeRouteModel.CombineTemplates("{lang=en}", selector.AttributeRouteModel.Template);
}
});
});
services.Configure<RequestLocalizationOptions>(options => {
var defaultCulture = new CultureInfo("en");
var supportedCultures = new CultureInfo[] {
defaultCulture,
new CultureInfo("fr")
};
options.DefaultRequestCulture = new RequestCulture(defaultCulture);
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider() {
RouteDataStringKey = "lang",
UIRouteDataStringKey = "lang",
Options = options
});
});
Это устанавливает глобальный маршрут, ваши поддерживаемые культуры и устанавливает основную культурупровайдер приехать с маршрута.(Это по-прежнему оставляет других провайдеров нетронутыми, поэтому, если значения Route не установлены, он все равно может установить культуру на основе строки запроса, файлов cookie или языкового заголовка.)
Теперь, в вашем методе Configure
(все ещев Startup.cs) добавьте следующее:
var routeBuilder = new RouteBuilder(app) {
DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
};
routeBuilder.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices));
var router = routeBuilder.Build();
app.Use(async (context, next) => {
var routeContext = new RouteContext(context);
await router.RouteAsync(routeContext);
context.Features[typeof(IRoutingFeature)] = new RoutingFeature() {
RouteData = routeContext.RouteData
};
await next();
});
var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(options.Value);
app.UseMvc();
Здесь есть некоторые хитрости.Во-первых, нам нужно вызвать app.UseRequestLocalization
, прежде чем мы вызовем app.UseMvc
, иначе наша программа запустится до того, как мы изменим текущую культуру.Но проблема в том, что app.UseMvc()
- это тот, который устанавливает RouteData.Таким образом, пока вы не вызовете его, все значения маршрутизации будут пустыми.Следовательно, когда RouteDataRequestCultureProvider
попытается выяснить, что такое {lang}, он вернется пустым и, таким образом, по умолчанию всегда будет en .Уловка 22.
Итак, мы просто вручную заполняем данные RouteData в нашем собственном специальном промежуточном программном обеспечении.Таким образом, RouteDataRequestCultureProvider может его видеть, и все будет хорошо работать.
(Я признаю, что это не самый эффективный вариант, поскольку вы просто дублируете работу по маршрутизации, которую тоже будет выполнять app.UseMvc()
, ноЯ возьму эту незаметную задержку, чтобы убедиться, что все мои страницы локализованы.)