MVC.net站点URL中带有语言属性的自定义路由
我有一个网站,需要本地化成许多不同的语言。 为了实现这一点,我遵循了这里的教程 在我的路线配置中,我有:MVC.net站点URL中带有语言属性的自定义路由,.net,asp.net-mvc,routes,localization,.net,Asp.net Mvc,Routes,Localization,我有一个网站,需要本地化成许多不同的语言。 为了实现这一点,我遵循了这里的教程 在我的路线配置中,我有: routes.MapRoute( name: "DefaultLocalized", url: "{lang}/{controller}/{action}/{id}", constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" }, // en or
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 }
);
目前,我的语言切换器是这样工作的,对于每种可用的语言,我都会使用当前的URL并创建一个带有相应语言段塞的链接,即en-US
或ru
等
<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.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
根据我目前的设置,有没有关于如何实现我想要的目标的建议
更新
放置[Route(“{lang}/brokers/this/is/a/custom/url”)]
由于我的属性有一些有限的成功,只要当前url中有一个lang变量,它就可以工作,因此如果我打开了,链接就会正确创建,但如果我打开了,链接就不会正确创建
我尝试在控制器中设置两个属性:
[Route("brokers/this/is/a/custom/url")]
[Route("{lang}/brokers/this/is/a/custom/url")]
但它只使用第一个
更新2
在我使用属性的评论中,有以下建议:
[Route("{lang=en-GB}/brokers/this/is/a/custom/url")]
它工作得很好,我的链接生成正确,但是我需要能够适应默认的本地化,而不需要URL中的lang var如果将两个属性与order参数放在一起,路由将首先尝试将第一个路由与lang参数匹配,如果没有提供lang参数,它将回退到第二条路径
[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:
if (filterContext.RouteData.Values["lang"]?.ToString() == _DefaultLanguage)
{
filterContext.RouteData.Values.Remove("lang");
}
一个月后,我放弃了使用普通路由/路由配置文件,这对我来说很有用。请注意,我使用的是区域,这里的区域名称是“Merchant” 正常链接: 要将其作为自定义链接打开,请执行以下操作: MerchantAreaRegistration.cs文件
context.MapRoute(
"Merchant_default",
url: "{lang}/Merchant/{controller}/{action}/{id}",
constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },
defaults: new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "GHLogistics.Areas.Merchant.Controllers" }
);
RouteConfig.cs文件
namespace GHLogistics
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{lang}/{controller}/{action}/{id}",
constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },
defaults: new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "GHLogistics.Controllers" }
);
}
}
}
你试过属性[Route(“{lang}/brokers/this/is/a/custom/url”)]吗?事实上,是的,但只有当url中有slug的语言部分时,我想知道如何在没有slug的情况下让它工作,这样我就不必为默认语言(英语)提供if,如果我尝试放置两条路由,一条带lang slug,另一条不带lang slug,然后它默认为第一个,您将使用属性[Route(“{lang=en US}/brokers/this/is/a/custom/url”)。但是您必须在每个自定义路由中硬编码默认语言。我不能这样做,因为其中一个规定是默认本地化在带有[Route({lang})的URLTry中没有lang var/brokers/this/is/a/custom/url,Order=1)][Route(“brokers/this/is/a/custom/url,Order=2)]这样,路由器首先尝试将路由与{lang}匹配,如果没有提供lang参数,它会在没有lang的路由上后退,只剩下一个小问题,当语言为非默认语言时,如何让它选择最上面的一个,当它是默认语言时,它是最底层的,这样它就不会在URLOne中包含'en-GB'变量。实现这一点的方法是,当语言是默认语言时,从routeData中删除lang。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace GHLogistics.Areas.Merchant.Controllers
{
[RouteArea("{lang}")]
[RoutePrefix("Merchant")]
public class FinancialController : MerchantBaseController
{
[Route("Financial/Transactions/Transaction/Details/{Id}")]
public ActionResult TransactionDetails(long Id)
{
return Content("TransactionDetails" + " " + Id.ToString());
// or
//pass relative path of view file, pass model
//return View("~/Areas/Merchant/Views/Financial/TransactionDetails.cshtml",transactions);
}
}
}
context.MapRoute(
"Merchant_default",
url: "{lang}/Merchant/{controller}/{action}/{id}",
constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },
defaults: new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "GHLogistics.Areas.Merchant.Controllers" }
);
namespace GHLogistics
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{lang}/{controller}/{action}/{id}",
constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },
defaults: new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "GHLogistics.Controllers" }
);
}
}
}