Маршрутизация страниц бритвы в /example.com/en/ формат - PullRequest
0 голосов
/ 29 мая 2018

У меня на сайте три языка.Я пытаюсь заставить мои бритвенные страницы перенаправлять на культуру / локализацию следующим образом:

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

На данный момент у меня есть сотни строк кода, закомментированных с использованием методов, которые я гуглял в течение последних двухдни и ничто, кажется, не делает работу.Сайт в основном статичен, так что сейчас, за пределами культуры, нет ничего, что требует маршрутизации.

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Вот способ, которым вы можете сделать это, не требуя размещения атрибута промежуточного программного обеспечения на всех ваших страницах.Это работает глобально.

В методе 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(), ноЯ возьму эту незаметную задержку, чтобы убедиться, что все мои страницы локализованы.)

0 голосов
/ 29 мая 2018

Я скажу вам, что я делаю, что работает.Единственное отличие состоит в том, что я использую 5-значный код языка, но я думаю, что это не сложно изменить.

Убедитесь, что у вас установлена ​​следующая библиотека nuget

Microsoft.AspNetCore.Localization.Routing

ВВ методе ConfigureServices файла Startup.cs мы вводим следующий код под 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()
    {

    }
}

Надеюсь, это поможет.

...