在ASP.net中为多语言重写URL

时间:2015-08-14 16:55:32

标签: asp.net url-rewriting multilingual

使用示例网址:

www.domain.com/contact-us

English呈现的内容。本网站支持一系列其他语言:

www.domain.com/es/contact-us
www.domain.com/jp/contact-us  
www.domain.com/de/contact-us
www.domain.com/pt/contact-us

以下是英语(默认语言)的重写规则

<rewrite url="^/contact-us(\?(.+))?$" to="~/Pages/Contact.aspx$1" processing="stop"/>

我如何修改此/添加新规则以重写:

www.domain.com/jp/contact-us  

要:

~/Pages/Contact.aspx?language=jp

最好不必为每个内容页面的每种语言编写新规则!

要使事情复杂化,需要匹配IETF语言标记。这些变化足够大,看起来像匹配它们的正则表达式将是一个困难的路线: https://en.wikipedia.org/wiki/IETF_language_tag

理想情况下,我需要从数据库中获取语言列表,并在运行时匹配语言标记字段。但我不知道怎么做,因为我只写过静态规则。

2 个答案:

答案 0 :(得分:3)

通过编写自己的URL重写模块解决了这个问题。遇到类似问题的任何人的示例代码如下。决定转储所有其他URL重写并通过此模块路由所有内容。

不要认为静态规则很容易实现这一点。

public class DynamicURLRewrite : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.AuthorizeRequest += new EventHandler(context_AuthorizeRequest);
    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }

    void context_AuthorizeRequest(object sender, EventArgs e)
    {
        var rw = new Rewriter();
        rw.Process();
    }
}

public class Rewriter
{
    public void Process()
    {
        using (MiniProfiler.Current.Step("Rewriter process"))
        {
            var context = HttpContext.Current;

            var rawURL = context.Request.RawUrl;
            var querystring = String.Empty;
            var urlParts = rawURL.Split('?');
            var url = urlParts[0];
            if (urlParts.Count() == 2) querystring = urlParts[1];
            if (url.StartsWith("/")) url = url.Substring(1);

            // Get language component
            Translation.Language inLanguage = null;
            {
                foreach (var lang in Translation.Language.GetAllLanguages())
                {
                    if (url.StartsWith(lang.LanguageTag, StringComparison.CurrentCultureIgnoreCase))
                    {
                        inLanguage = lang;
                        url = url.Substring(lang.LanguageTag.Length);
                        if (url.StartsWith("/")) url = url.Substring(1);
                        break;
                    }
                }
                if (inLanguage == null)
                {
                    inLanguage =
                        Translation.Language.GetLanguage(
                            Settings.Translation.ProjectReferenceVersionRequiredLanguageTag);
                }
            }

            // Querystring
            {
                if (!String.IsNullOrEmpty(querystring)) querystring += "&";
                querystring += "lang=" + inLanguage.LanguageTag.ToLower();
                querystring = "?" + querystring;
            }

            // Root pages
            {
                if (String.IsNullOrEmpty(url))
                {
                    context.RewritePath("~/pages/default.aspx" + querystring);
                    return;
                }
                if (url.Equals("login"))
                {
                    context.RewritePath("~/pages/login.aspx" + querystring);
                    return;
                }

然后是一些更复杂的规则:

            // Handlers
            if (url.StartsWith("handlers/"))
            {
                // Translation serving
                if(url.StartsWith("handlers/translations/"))
                {
                    var regex = new Regex("handlers/translations/([A-Za-z0-9-]+)/([A-Za-z0-9-]+).json", RegexOptions.IgnoreCase);
                    var match = regex.Match(url);
                    if (match.Success)
                    {
                        context.RewritePath("~/handlers/translation/getprojecttranslation.ashx" + querystring + "&project=" + match.Groups[1] + "&language=" + match.Groups[2]);
                        return;
                    }
                }
            }

答案 1 :(得分:1)

您是否可以访问主目录中的.htaccess文件?如果是这样,您可以通过编写以下内容来制作自动重写规则

Options +FollowSymLinks
RewriteEngine on
RewriteRule /(.*)/contact-us/ /Pages/Contact.aspx?language=$1
RewriteRule /contact-us/ /Pages/Contact.aspx?language=en

让我解释一下:

RewriteRule之后,用户友好的网址位于左侧,/(.*)/contact-us/ (.*)其中jp将在jp所在的位置。 然后,/Pages/Contact.aspx?language=$1转置在右侧的真实网址上,此处$1替换http://www.example.com/jp/contact-us

输入网址:http://www.example.com/Pages/Contact.aspx?language=jp
输出网址:RewriteRule

对于第二个http://www.example.com/contact-us/,由于网址http://www.example.com/Pages/Contact.aspx?language=en与第一个模型不匹配,它将自动变为.htaccess

请记住,Pages文件必须位于根目录(与12abc3def4 文件夹一起)。否则你将无法获得理想的结果。