MVC .net站点的URL中具有语言属性的自定义路由 [英] Custom routing with language attribute in URL for MVC .net site

查看:85
本文介绍了MVC .net站点的URL中具有语言属性的自定义路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网站,需要将其本地化为多种不同的语言. 为此,我按照此处的教程进行操作 https://www.ryadel .com/en/setup-a-multi-language-website-using-asp-net-mvc/ 在我的路由配置中,我有:

I have a site which requires localization into a number of different languages. To achieve this I followed the tutorial here https://www.ryadel.com/en/setup-a-multi-language-website-using-asp-net-mvc/ In my route config I have :

routes.MapRoute(
                name: "DefaultLocalized",
                url: "{lang}/{controller}/{action}/{id}",
                constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },   // en or en-US
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

目前,我的语言切换器的工作方式是这样,对于每种可用的语言,我都会使用当前的网址,并使用相应的语言段(即en-USru-RU等)创建一个链接

Currently my language switcher works like this, for every available language I take the current URL and create a link with the appropriate language slug i.e. en-US or ru-RU etc

<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
        @foreach (CultureViewModel culture in Global.EnabledCultures)
        {
            <li><span class="Language dropdown-item" title="@culture.DisplayName">@Html.Raw(Url.LangSwitcher(culture.DisplayName, ViewContext.RouteData, culture.Name))</span></li>
        }
    </div>

Url.LangSwitcher是UrlHelper的扩展

Where Url.LangSwitcher is an Extension of UrlHelper

public static string LangSwitcher(this UrlHelper url, string name, RouteData routeData, string lang, bool isMainMenu = false)
{
    var action = (routeData.Values["action"] ?? "").ToString().ToLower();
    var controller = (routeData.Values["controller"] ?? "").ToString().ToLower();
    var requestContext = HttpContext.Current.Request.RequestContext;
    string link = "";

    // We need to create a unique URL for the current page for each of the enabled languages for this portal
    // If the lang variable is specified for current URL we need to substitute with the incoming lang variable
    //we need to duplicate the RouteData object and use the duplicate for URL creation as
    //changing the value of lang in RouteData object passed to this function changes the current culture of the request

        RouteData localValues = new RouteData();
        foreach (KeyValuePair<string, object> var in routeData.Values)
        {
            if (var.Key != "lang")
            {
                localValues.Values.Add(var.Key, var.Value);
            }
        }
    localValues.Values.Add("lang", lang);
    link = "<a href = \"" + new UrlHelper(requestContext).Action(action, controller, localValues.Values) + "\" >";


    string img = "<img src=\"/Content/images/Flags/" + lang + ".gif\" alt = \"" + lang + "\"> " + name;
    string closeTags = "</a>";

    return link + img + closeTags;
}

因此它将使用当前URL并切换语言提示,并输出我们正在创建的菜单的链接.

so it takes the current URL and switches out the language slug and outputs a link for the menu we are creating.

这对于遵循标准{lang}/{controller}/{action}/{id}模式的链接都可以正常工作

This all works fine on links that follow the standard {lang}/{controller}/{action}/{id} pattern

但是,我希望能够像这样在控制器上创建具有属性的自定义链接:

however, I want to be able to create custom links with attributes on the controllers like so:

[Route("brokers/this/is/a/custom/url")]
        public ActionResult CompareBrokers(int page = 1)
        {

因此,当我尝试从这样的视图访问此路由时:

so when I try to access this route from a view like so:

@Url.Action("CompareBrokers", "Brokers")

生成的URL如下:

https://localhost:44342/brokers/this/is/a/custom/url?lang=en-US

我希望它是这样的

https://localhost:44342/en-US/brokers/this/is/a/custom/url

在当前设置下,关于如何实现所需目标的任何建议?

Any advice on how I can achieve what I want given my current set up?

更新[Route("{lang}/brokers/this/is/a/custom/url")]设置为我的属性效果有限,只要当前URL中有一个lang变量,它就会起作用,因此,如果我使用的是 http://site.url/zh-CN ,则可以正确创建链接,但是如果我在

UPDATE putting [Route("{lang}/brokers/this/is/a/custom/url")] as my attribute has some limited success, it will work as long as there is a lang variable in the current URL, so if I am on http://site.url/en-US then the links get created correctly, but if I am on http://site.url they do not.

我尝试在控制器中添加2个属性:

Ive tried putting 2 attributes in my controller:

[Route("brokers/this/is/a/custom/url")]
[Route("{lang}/brokers/this/is/a/custom/url")]

但是它只使用第一个

更新2

在注释中,我使用了以下建议:

Following advice in the comments I used the attribute:

[Route("{lang=en-GB}/brokers/this/is/a/custom/url")]

它运行良好,可以正确生成我的链接,但是我需要能够容纳默认本地化,而无需在URL中添加lang var

and it works perfectly, my links get generated correctly, however I need to be able to accommodate the default localization without the lang var in the URL

推荐答案

如果放置两个具有顺序参数的属性,则路由将首先尝试将第一个路由与lang参数匹配,并且如果未提供lang参数它将退回到第二条路线.

If you put two attributes with the order paramter, the routing will first try to match the first route with the lang parameter, and if the lang parameter is not supplied it will fallback on the second route.

[Route("{lang}/brokers/this/is/a/custom/url", Order = 1)]
[Route("brokers/this/is/a/custom/url", Order =  2)]
public ActionResult CompareBrokers(int page = 1)
{
}

更新: 要在lang是默认语言时使用第二条路由,可以通过添加actionFilter或controllerActivator从路由数据中删除lang:

UPDATE : To use the 2nd route when lang is the default language you could remove lang from the routedata by adding in your actionFilter or controllerActivator :

if (filterContext.RouteData.Values["lang"]?.ToString() == _DefaultLanguage)
{
    filterContext.RouteData.Values.Remove("lang");
}

这篇关于MVC .net站点的URL中具有语言属性的自定义路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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