Localized page names with ASP.NET Core 2.1

偶尔善良 提交于 2019-12-01 06:55:58

问题


When create a Razor page, e.g. "Events.cshtml", one get its model name set to

@page
@model EventsModel

where the page's name in this case is "Events", and the URL would look like

http://example.com/Events

To be able to use page name's in Norwegian I added the following to the "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");
});

With this I can also use an URL like this and still serve the "Events" page

http://example.com/hvaskjer

I'm planning to support many more languages and wonder, is this the recommended way to setup localized page name's/route's?, or is there a more proper, correct way to accomplish the same.

I mean, with the above sample, and having 15 pages in 10 languages it gets/feels messy using options.Conventions.AddPageRoute("/Page", "/side"); 150 times.


回答1:


You can do this with the IPageRouteModelConvention interface. It provides access to the PageRouteModel where you can effectively add more templates for routes to match against for a particular page.

Here's a very simple proof of concept based on the following service and model:

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

All it does is provide the list of options for a particular page. The IPageRouteModelConvention implementation looks like this:

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

At Startup, Razor Pages build the routes for the application. The Apply method is executed for every navigable page that the framework finds. If the relative path of the current page matches one in your data, an additional template is added for each option.

You register the new convention in ConfigureServices:

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


来源:https://stackoverflow.com/questions/52317610/localized-page-names-with-asp-net-core-2-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!