使URL语言特定(通过路线)

时间:2013-02-21 15:53:28

标签: asp.net-mvc localization asp.net-mvc-routing globalization

很难找到这个具体问题的答案,所以生病了:

我们希望完全使用特定于语言的网址,这意味着

  

www.mysite.com/EN

     

www.mysite.com/DE

这是在RouteConfig中用

完成的
url: "{language}/{controller}/{action}/{id}"

然后是棘手的部分:

  

www.mysite.com/EN/Categories

     

www.mysite.com/DE/Kategorien

即。使控制器名称以多种语言显示,但指向同一个控制器。这甚至可能吗?

2 个答案:

答案 0 :(得分:15)

嗯,这部分是可能的(仅限语言部分)。使用不同语言的控制器名称绝对是一个有趣的点,但我认为很难实现这一点。想想像阿拉伯语和希伯来语这样的Bidi语言会是什么样子。使用不同语言的控制器可能是一个好主意,但是你会为自己造成破坏,我相信你必须改变底层的MVC结构来实现这一点。

语言更改部分很简单,可以像下面这样完成。

您可能想要看的是全球化。基本上语言部分对应于当前线程UI文化。您需要的是以下内容:

  1. 定义一条路线,如下所示:

    var lang = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
    
    routes.MapRoute(
        name: "Default",
        url: "{language}/{controller}/{action}/{id}",
        defaults: new { language = lang, controller = "Home", 
                        action = "Index", id = UrlParameter.Optional }
     );
    
  2. 注册Application_AcquireRequestState并将其定义为:

    protected void Application_AcquireRequestState()
    {
        var routes = RouteTable.Routes;
    
        var httpContext = Request.RequestContext.HttpContext;
        if (httpContext == null) return;
    
        var routeData = routes.GetRouteData(httpContext);
    
        var language = routeData.Values["language"] as string;
        var cultureInfo = new CultureInfo(language);
    
        System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
        System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
    }
    

    虽然CurrentUICulture是您需要的切换语言从资源文件加载信息,但您还应将CurrentCulture更改为相同的CultureInfo;

  3. 最后,请确保您有相应的资源文件和备用资源文件。

  4. 我使用了Name CultureInfo的{​​{1}}属性,因此德语将为de-DE,英语为en-US等。 这应该可以解决问题。

    如果您需要更多信息,我可以上传一个示例MVC项目供您检查。

    更新:一种粗暴的做法是将路线段的顺序颠倒为:

    routes.MapRoute(
        name: "NewDefault",
        url: "{language}/{id}/{action}/{controller}",
        defaults: new { language = lang, controller = "Home", action = "Index", id = "Category"}
    );
    

    这样您就可以发出以下请求http://www.your_url.com/de/Kategorien。在这种情况下,Kategorien映射到id而不是控制器。您的控制器保留英语或德语(取决于您的命名方式),但用户可以看到不同的语言。在后台,您的视图可能是这样的:

    public ActionResult Index(string id, string categoryName)
    {
        // Fetch data based on category name (categoryName)
        return View();
    }
    

    您可以将其他信息作为参数传递,但您需要调整路线,使其类似于:{language} / {category} / {subcategory} / {action} / {controller}

    只要知道从长远来看这可能会导致颈部疼痛,如果你试试这个,那么一定要把它记录下来。

答案 1 :(得分:-1)

我认为,除了翻译控制器名称之外,还有其他更有用的解决方案,无参数路由的成本非常高,现代且搜索引擎优化非常简单。

主要思想是将路线以及相关的控制器,操作和参数存储在数据库中。然后,当用户请求任何网址时,您就可以将其匹配。

{{1}}

在Nop-commerce中使用此方法,您可以下载源代码并查看本文NopCommerce ID-Less URL Structure

此解决方案的问题是:您应该保留自己的网址和性能。