在MVC中获取子域以进行国际化

本文关键字:国际化 MVC 获取 | 更新日期: 2023-09-27 18:25:46

我正在开发一个MVC网站,该网站将有多个翻译。我们希望通过像http://en.domain.comhttp://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/producthttp://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;
    }

在MVC中获取子域以进行国际化

您可以使用自定义路由来简化

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.comhttp://fr.something.example.com都将产生fr,而http://example.com将产生en(本例中的默认值)。