Локализованные имена страниц с помощью asp.net core 2.1

При создании страницы Razor, например "Events.cshtml", имя модели устанавливается равным

@page
@model EventsModel

где имя страницы в данном случае - «События», а URL-адрес будет иметь вид

http://example.com/Events

Чтобы иметь возможность использовать названия страниц на норвежском языке, я добавил следующее в "Startup.cs"

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
    .AddRazorPagesOptions(options => {
        options.Conventions.AddPageRoute("/Events", "/hvaskjer");
        options.Conventions.AddPageRoute("/Companies", "/bedrifter");
        options.Conventions.AddPageRoute("/Contact", "/kontakt");
});

При этом я также могу использовать такой URL-адрес и по-прежнему обслуживать страницу «События».

http://example.com/hvaskjer

Я планирую поддерживать еще много языков и задаюсь вопросом, является ли это рекомендуемым способом настройки локализованного имени страницы / маршрута? Или есть более подходящий способ верный для достижения того же.

Я имею в виду, что с приведенным выше образцом и с 15 страницами на 10 языках становится / кажется беспорядочным использование options.Conventions.AddPageRoute("/Page", "/side"); 150 раз.

Если это не похоже на «настоящий» маршрут, но псевдоним для чего-то еще, может быть лучше использовать либо модуль перезаписи URL-адреса IIS, либо это промежуточное ПО docs.microsoft.com/en-us/aspnet/core/fundamentals/…

boateng 13.09.2018 20:19

@numbtongue Спасибо за ваш комментарий. Поскольку приложение может работать в другой среде, кроме, например, IIS, мне нужно избегать такого решения. Использование промежуточного программного обеспечения для перезаписи кажется менее правильным, чем то, что у меня уже есть, и я надеюсь, что будет встроенная опция для решения этой проблемы.

Ason 13.09.2018 20:30

Было бы неплохо, если бы вы могли поместить их в web.config, где вы могли бы указать <location path = «konrakt»> (хотя может запутать будущего разработчика) stackoverflow.com/a/40220739/3254405

boateng 13.09.2018 20:36

@numbtongue Я бы не хотел хранить сотни тегов пути в "web.config", они хранятся и читаются из базы данных с учетом выбранного языка, и их легко изменить.

Ason 13.09.2018 20:43

Можно создавать маршруты только для таких доменов, как .com и .no, и оттуда вы узнаете, какой путь использовать.

boateng 13.09.2018 20:55

@numbtongue Выбранный язык не имеет никакого отношения к используемому домену.

Ason 13.09.2018 21:33

Многие крупные веб-сайты используют язык в строке запроса, такой как / en / или / fr / (не уверен, что это поможет) google.com/amp/s/gunnarpeipman.com/aspnet/…

boateng 13.09.2018 21:58
3
7
529
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете сделать это с помощью интерфейса IPageRouteModelConvention. Он обеспечивает доступ к PageRouteModel, где вы можете эффективно добавлять больше шаблонов для маршрутов для сопоставления для конкретной страницы.

Вот очень простое подтверждение концепции, основанное на следующем сервисе и модели:

public interface ILocalizationService
{
    List<LocalRoute> LocalRoutes();
}
public class LocalizationService : ILocalizationService
{
    public List<LocalRoute> LocalRoutes()
    {
        var routes = new List<LocalRoute>
        {
            new LocalRoute{Page = "/Pages/Contact.cshtml", Versions = new List<string>{"kontakt", "contacto", "contatto" } }
        };
        return routes;
    }
}

public class LocalRoute
{
    public string Page { get; set; }
    public List<string> Versions { get; set; }
}

Все, что он делает, это предоставляет список опций для конкретной страницы. Реализация IPageRouteModelConvention выглядит так:

public class LocalizedPageRouteModelConvention : IPageRouteModelConvention
{
    private ILocalizationService _localizationService;

    public LocalizedPageRouteModelConvention(ILocalizationService localizationService)
    {
        _localizationService = localizationService;
    }

    public void Apply(PageRouteModel model)
    {
        var route = _localizationService.LocalRoutes().FirstOrDefault(p => p.Page == model.RelativePath);
        if (route != null)
        {
            foreach (var option in route.Versions)
            {
                model.Selectors.Add(new SelectorModel()
                {
                    AttributeRouteModel = new AttributeRouteModel
                    {
                        Template = option
                    }
                });
            }
        }
    }
}

При запуске Razor Pages создает маршруты для приложения. Метод Apply выполняется для каждой страницы с возможностью навигации, которую находит фреймворк. Если относительный путь текущей страницы совпадает с путем в ваших данных, для каждой опции добавляется дополнительный шаблон.

Вы регистрируете новое соглашение в ConfigureServices:

services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.Add(new LocalizedPageRouteModelConvention(new LocalizationService()));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

Большое спасибо, именно то, что я искал. Я нашел IPageRouteModelConvention, хотя я слишком новичок в ASP.Net Core, чтобы понять, как это сделать :)

Ason 13.09.2018 21:59

По совпадению, у меня есть черновик статьи в блоге об этом интерфейсе, почти готовый к работе. Я мог бы включить этот вариант использования в качестве дополнительного примера его применения.

Mike Brind 13.09.2018 22:10

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

Ason 13.09.2018 22:18

И я только что понял, что если на странице есть директива вроде @page "{edit?}/{id?}", ее тоже можно / нужно добавить, чтобы все работало, например new LocalRoute{Page = "/Pages/Events.cshtml", Versions = new List<string>{"hvaskjer/{edit?}/{id?}" } }

Ason 13.09.2018 22:29

@MikeBrind, как дела с тем сообщением в блоге, которое вы упомянули? Это опубликовано?

PussInBoots 28.03.2019 13:29

@PussInBoots Я опубликовал это около 6 месяцев назад: mikesdotnetting.com/article/327/…

Mike Brind 28.03.2019 13:47

@MikeBrind Как вы генерируете ссылки (<a asp-page="????"> Ссылка на локализованную версию страницы контактов </a>) на новые локализованные маршруты?

PussInBoots 30.03.2019 02:18

@MikeBrind, как бы вы добавили дополнительные версии страницы или новые страницы? Поскольку пользовательское соглашение выполняется один раз во время запуска приложения, новые страницы или версии страницы не будут сопоставлены ни с какими шаблонами маршрутов, и мне нужно будет перезапускать приложение каждый раз, когда я добавляю новые страницы, например при использовании CMS.

PussInBoots 16.05.2019 20:22

Другие вопросы по теме