我的网站上有三种语言。我正试图让我的剃刀页面如此路由到文化/本地化:
https://localhost:44396/en/
https://localhost:44396/ru/
此时我已经使用过去两天谷歌搜索的方法注释了数百行代码,似乎没有任何工作。 该网站大多是静态的,所以现在除了文化之外没有其他需要路由的东西。
答案 0 :(得分:1)
您可以通过这种方式不需要在所有页面上放置中间件属性。这在全球范围内有效。
在Startup.cs的ConfigureServices
方法中,添加以下内容:
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()
本身也会做的路由工作,但是我会采取明显的延迟来确保我的所有页面都已本地化。)
答案 1 :(得分:0)
我会告诉你我做了什么工作。唯一的区别是我使用了5个字符的语言代码,但我想这并不难改变。
确保安装了以下nuget库
Microsoft.AspNetCore.Localization.Routing
在Startup.cs的ConfigureServices方法中,我们在servcies.AddMvc()下输入以下代码;
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/Account/Manage");
options.Conventions.AuthorizePage("/Account/Logout");
options.Conventions.AddFolderRouteModelConvention("/", model =>
{
foreach (var selector in model.Selectors)
{
var attributeRouteModel = selector.AttributeRouteModel;
attributeRouteModel.Template = AttributeRouteModel.CombineTemplates("{lang=el-GR}", attributeRouteModel.Template);
}
});
});
IList<CultureInfo> supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("fr-FR"),
new CultureInfo("el-GR"),
};
var MyOptions = new RequestLocalizationOptions()
{
DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
};
MyOptions.RequestCultureProviders = new[]
{
new RouteDataRequestCultureProvider() { RouteDataStringKey = "lang", Options = MyOptions } // requires nuget package Microsoft.AspNetCore.Localization.Routing
};
services.AddSingleton(MyOptions);
我们添加以下类
using Microsoft.AspNetCore.Builder;
public class LocalizationPipeline
{
public void Configure(IApplicationBuilder app, RequestLocalizationOptions options)
{
app.UseRequestLocalization(options);
}
}
现在,您必须在PageModel类上添加以下行:
[MiddlewareFilter(typeof(LocalizationPipeline))]
public class ContactModel : PageModel
{
public void OnGet()
{
}
}
我希望它有所帮助。