将 Razor 页面路由到/example.com/en/格式 [英] Routing Razor Pages to /example.com/en/ format

查看:18
本文介绍了将 Razor 页面路由到/example.com/en/格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的网站上有三种语言.我试图让我的剃刀页面像这样路由到文化/本地化:

I have three languages on my website. I'm trying to get my razor pages to route to culture/localization like so:

https://localhost:44396/en/
https://localhost:44396/ru/

在这一点上,我使用过去两天一直在谷歌搜索的方法注释掉了数百行代码,但似乎没有任何作用.该网站大部分是静态的,因此现在除了文化之外,没有其他需要路由的东西.

I have hundreds of lines of code commented out at this point using methods I've been googling for the past two days and nothing seems to do the job. The website is mostly static so right now beyond the culture there is nothing else that needs routing.

推荐答案

这是一种无需在所有页面上都放置中间件属性的方法.这适用于全球.

Here's a way you can do it that doesn't require you to put a middleware attribute on all of your pages. This works globally.

在Startup.cs的ConfigureServices方法中,添加以下内容:

In the ConfigureServices method of Startup.cs, add the following:

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
    });
});

这会设置全球路线、您支持的文化,并将主要文化提供者设置为来自该路线.(这仍然保持其他提供者不变,因此如果路由值失败,它仍然可以根据查询字符串、Cookie 或语言标头设置区域性.)

This sets up the global route, your supported cultures, and sets the primary culture provider to come from the route. (This still leaves the other providers intact, so failing the Route values, it can still set the culture based on the Query String, Cookies, or Language Header.)

现在,在您的 Configure 方法(仍在 Startup.cs 中)中,添加以下内容:

Now, in your Configure method (still in Startup.cs), add the following:

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.UseMvc 之前调用 app.UseRequestLocalization,否则我们的程序将在我们改变当前文化之前运行.但问题是,app.UseMvc() 是设置 RouteData 的那个.因此,在您调用它之前,路由值都是空白的.因此,当 RouteDataRequestCultureProvider 去尝试观察 {lang} 是什么时,它会返回空的,因此总是默认你en.抓住 22.

There's some trickery here. Firstly, we have to call app.UseRequestLocalization before we call app.UseMvc, or else our program will run before we've changed the current culture. But the problem is, app.UseMvc() is the one that sets up RouteData. So, until you call it, the routing values are all blank. Ergo, when the RouteDataRequestCultureProvider goes to try and observe what {lang} is, it'll come back empty, and thus always default you to en. Catch 22.

因此,我们只需在我们自己的自定义中间件中手动填充 RouteData.这样,RouteDataRequestCultureProvider 就可以看到它,一切都会正常运行.

So, we just go manually populate the RouteData ourselves in our own custom middleware. That way, the RouteDataRequestCultureProvider can see it, and all will work well.

(我承认这不是最有效的,因为你只是在复制 app.UseMvc() 本身也会做的路由工作,但我会采取这种不明显的延迟来确保我所有的页面都已本地化.)

(I admit this is not the most efficient, as you're just duplicating the routing work that app.UseMvc() will itself also do, but I'll take that unnoticeable delay to ensure all my pages are localized.)

这篇关于将 Razor 页面路由到/example.com/en/格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆