在MVC中获取子域以进行国际化
本文关键字:国际化 MVC 获取 | 更新日期: 2023-09-27 18:25:46
我正在开发一个MVC网站,该网站将有多个翻译。我们希望通过像http://en.domain.com
或http://fr.domain.com
这样的子域来实现这一点。我们还希望支持常规域http://domain.com
。
如果您手动更改子域,翻译就会正常工作,但我正在寻找一种方法来自动执行此操作,并维护整个当前URL,以允许找到http://en.domain.com/product
的用户单击链接并获得同一页面的另一种语言版本。似乎很简单,只需隔离子域(如果存在),将其从当前url中删除,并替换为指定的语言版本。
本质上:
http://en.domain.com/product
(原件)
http://domain.com/product
(清洁)
http://fr.domain.com/product
或http://de.domain.com/product
等…(输出)
我开始寻找像Request.Url.Subdomain
这样的内置功能,但已经得出结论,没有这样神奇的生物。然后我转到了基本的字符串操作,但它似乎真的很复杂,所以我开始寻找regex解决方案。
我已经用一些通常为我工作的在线regex测试人员测试了这个regex,当子域存在时,他们会正确识别它,但在代码实际运行时找不到结果。
我只使用了一点正则表达式,我希望这里有一些明显的错误。如果有更好的解决方案,我愿意接受其他的实施方案。
C#
string url = Request.Url.AbsoluteUri; //http://en.domain.com/
Regex regex = new Regex(@"/(?:http[s]*':'/'/)*(.*?)'.(?=[^'/]*'..{2,5})/", RegexOptions.IgnoreCase);
GroupCollection results = regex.Match(url).Groups;
Group result = results[0];
这是我目前的解决方案。虽然没有我想要的那么优雅,但对于一些消耗了太多时间的东西来说,它现在正在按预期工作。
查看
<a href="@Html.Action("ChangeLanguage", new { lang = "en" })">English</a>
<a href="@Html.Action("ChangeLanguage", new { lang = "fr" })">French</a>
操作
public string ChangeLanguage(string controller, string lang)
{
string url = Request.Url.AbsoluteUri;
Regex regex = new Regex(@"(?:https*://)?.*?'.(?=[^/]*'..{2,5})", RegexOptions.IgnoreCase);
GroupCollection results = regex.Match(url).Groups;
Group result = results[0];
if (result.Success)
{
string[] resultParts = result.Value.Split('/');
string newSubDomain = resultParts[0] + "//" + lang + ".";
url = url.Replace(result.Value, newSubDomain);
}
else
{
string[] urlParts = url.Split('/');
string oldParts = urlParts[0] + "//";
string newParts = urlParts[0] + "//" + lang + ".";
url = url.Replace(oldParts, newParts);
}
return url;
}
您可以使用自定义路由来简化
routes.Add("LanguageRoute", new DomainRoute(
"{language}.example.com/{controller}/{action}", // Domain with parameters
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
))
并在控制器上获取语言值
public ActionResult Index(string language)
{
return View();
}
一个有用的链接可能会对您有所帮助:http://benjii.me/2015/02/subdomain-routing-in-asp-net-mvc/
使用以下内容(psuedocode-应添加安全检查等):
Uri myHost = new Uri("https://en.mydomain.com");
string hostname = myHost.Host; // returns en.mydomain.com
string subdomain = string.split(".", hostname)[0]; // subdomain = "en"
这将获得主机名,然后可以在"."上将其拆分为一个数组,并获取第一个元素。
编辑:链接到Uri.Host 上的MSDN文档
https://msdn.microsoft.com/en-us/library/system.uri.host(v=vs.110).aspx
我们在我的一个项目上做了类似的事情,这就是我获得当前子域的方式:
string GetSubDomain(Uri url, string defaultValue)
{
string subdomain = defaultValue;
if (url.HostNameType == UriHostNameType.Dns)
{
string host = url.Host;
if (host.Split('.').Length > 2)
{
int index = host.IndexOf(".");
int lastIndex = host.LastIndexOf(".");
subdomain = index.Equals(lastIndex) ? defaultValue : host.Substring(0, index);
}
}
return subdomain;
}
你会这样使用它:
var subdomain = GetSubDomain(HttpContext.Current.Request.Url, "en");
这假设您只想要当前URL中的第一个子域,因此http://fr.example.com
和http://fr.something.example.com
都将产生fr
,而http://example.com
将产生en
(本例中的默认值)。