C# 如何使用MVC路由多语言URL

C# 如何使用MVC路由多语言URL,c#,asp.net-mvc,model-view-controller,routing,url-rewriting,C#,Asp.net Mvc,Model View Controller,Routing,Url Rewriting,我需要现有控制器的多语言URL路由。让我进一步解释: 我有一个名为“产品”的控制器和名为“软件”的视图;因此,默认情况下,如果用户输入“”,则获取正确的内容(实际上存在于中) 但是,如果另一个用户(法语用户)键入“”,则必须在控制器上方显示正确的内容(相同,但使用法语文本) 注意:我使用“{language}/{controller}/{action}/{id}”设置路由表 任何其他无效URL必须显示404页面 有可能吗?你应该有类似“英语”和“法语”的url,这很有意义 对两者使用相同的视图

我需要现有控制器的多语言URL路由。让我进一步解释:

我有一个名为“产品”的控制器和名为“软件”的视图;因此,默认情况下,如果用户输入“”,则获取正确的内容(实际上存在于中)

但是,如果另一个用户(法语用户)键入“”,则必须在控制器上方显示正确的内容(相同,但使用法语文本)

注意:我使用“{language}/{controller}/{action}/{id}”设置路由表

任何其他无效URL必须显示404页面


有可能吗?

你应该有类似“英语”和“法语”的url,这很有意义

对两者使用相同的视图


快乐编码。

正如之前所建议的,这与网站URL(和路由)使用英语的惯例不同

尽管如此,这是可能的,但为了做到这一点,您可能必须考虑为每种外语的每个动作生成一条路径。因此,对于一个有20个动作和三种语言(英语、法语和德语)的网站,您需要41条路线(20条法语、20条德语和1条英语)。我承认,这不是最有效的系统,但它可以按照你的意愿工作

//You'll only need one of these, which is the default.
routes.MapRoute(
  "English route",
  "en/{controller}/{action}/{id}"
  new { controller = "Home", action = "Index", language = "en" },
);

routes.MapRoute(
  "FrenchHome",
  "fr/Demarrer/Index/{id}",
  new { controller = "Home", action = "Index", language = "fr" }
);

routes.MapRoute(
  "GermanHome",
  "de/Heim/Index/{id}", //'Heim' is, I believe the correct usage of Home in German.
  new { controller = "Home", action = "Index", language = "de" }
);

//Some more routes...

routes.MapRoute(
  "FrenchSoftware",
  "fr/Produit/Logiciels/{id}",
  new { controller = "Product", action = "Software", language = "fr" }
);

routes.MapRoute(
  "GermanSoftware",
  "de/Produkt/Software/{id}", //In this instance, Software should be the same in German and English.
  new { controller = "Product", action = "Software", language = "de" }
);

//And finally, the 404 action.
routes.MapRoute(
  "Catchall",
  "{language}/{*catchall}",
  new { controller = "Home", action = "PageNotFound", language = "en" },
  new { language = "^(en|fr|de)$" }
);

//This is for the folks who didn't put a language in their url.
routes.MapRoute(
  "Catchall",
  "{*catchall}",
  new { controller = "Home", action = "PageNotFound", language = "en" }
);
在您的行动中,例如产品/软件

public ActionResult Software(string language, int id)
{
  //This would go off to the DAL and get the content in whatever language you want.
  ProductModel model = ProductService.GetSoftware(language, id);

  return View(model);
}
如果有人来告诉我有更好的方法可以做到这一点,我会喜欢,因为我同意使用外语的url是不好的,而且考虑到互联网本身正朝着允许url中使用非罗马字符的方向发展,我们越早找到解决方案越好


不仅如此,我知道骄傲的法国人不喜欢看到他们的网站URL包含英语

在丹的帖子的基础上,我正在使用下面的内容来翻译我的控制器和动作名称

我创建了一个表来存储这些值,这些值可以也可能应该保存在资源文件中,以将所有内容保存在一起;不过,我使用了一个数据库表,因为它更适合我的公司流程

CREATE TABLE [dbo].[RoutingTranslations](
[RouteId] [int] IDENTITY(1,1) NOT NULL,
[ControllerName] [nvarchar](50) NOT NULL,
[ActionName] [nvarchar](50) NOT NULL,
[ControllerDisplayName] [nvarchar](50) NOT NULL,
[ActionDisplayName] [nvarchar](50) NOT NULL,
[LanguageCode] [varchar](10) NOT NULL)
然后,RouteConfig.cs文件更改为:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        //Build up routing table based from the database.  
        //This will stop us from having to create shedloads of these statements each time a new language, controller or action is added
        using (GeneralEntities db = new GeneralEntities())
        {
            List<RoutingTranslation> rt = db.RoutingTranslations.ToList();
            foreach (var r in rt)
            {
                routes.MapRoute(
                    name: r.LanguageCode + r.ControllerDisplayName + r.ActionDisplayName,
                    url: r.LanguageCode + "/" + r.ControllerDisplayName + "/" + r.ActionDisplayName + "/{id}",
                    defaults: new { culture = r.LanguageCode, controller = r.ControllerName, action = r.ActionName, id = UrlParameter.Optional },
                    constraints: new { culture = r.LanguageCode }
                );
            }                
        }

        //Global catchall
        routes.MapRoute(
            name: "Default",
            url: "{culture}/{controller}/{action}/{id}",
            defaults: new {culture = CultureHelper.GetDefaultCulture(), controller = "Default", action = "Index", id = UrlParameter.Optional }
            //defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

    }
}
公共类路由图
{
公共静态无效注册表项(路由收集路由)
{
routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
//根据数据库建立路由表。
//这将使我们不必在每次添加新语言、控制器或操作时都创建这些语句
使用(GeneralEntities db=new GeneralEntities())
{
List rt=db.RoutingTranslations.ToList();
foreach(rt中的var r)
{
routes.MapRoute(
名称:r.LanguageCode+r.ControllerDisplayName+r.ActionDisplayName,
url:r.LanguageCode+“/”+r.ControllerDisplayName+“/”+r.ActionDisplayName+“/{id}”,
默认值:新建{culture=r.LanguageCode,controller=r.ControllerName,action=r.ActionName,id=UrlParameter.Optional},
约束:新{culture=r.LanguageCode}
);
}                
}
//全球捕鲸
routes.MapRoute(
名称:“默认”,
url:“{culture}/{controller}/{action}/{id}”,
默认值:新建{culture=CultureHelper.GetDefaultCulture(),controller=“Default”,action=“Index”,id=UrlParameter.Optional}
//默认值:新建{controller=“Home”,action=“Index”,id=UrlParameter.Optional}
);
}
}
默认情况下,这将始终使用英文控制器和操作名称,但允许您通过在表中输入值来提供覆盖

(我的国际化代码主要基于这篇伟大的博文。
)

我强烈推荐以下方法在MVC5中实现多语言(这意味着不友好的URL,因为世界上不是每个人都说英语。默认情况下,你应该使用英语erikkallen@erikkallen:那么OP应该以所有可能的语言提供URL吗?URL应该识别资源,并且在这样做时尽可能描述该资源的性质。这并不意味着uld可以是多个URL以满足多种语言的需求。资源呈现的语言才是最重要的。向上投票。非常感谢您的快速响应,对我来说没问题,但如何做???如何找到合适的控制器并查看和设置???注:我使用“{language}/{controller}/{action}/{id}”对于routeHamid,请查看Fred回答的此链接。实际上,如果您关心搜索引擎排名,这不是一个好主意。您可以始终重定向到英文页面,或者对同一实体的所有实例使用标准规范URL。(有人提供了更好的方法…)不关心传递到action方法中的内容如何?相反,要像普通一样路由它。但在基本控制器上为OnActionExecuting()设置重载,根据路由相应地设置CultureUI(例如,它会查看filterContext中的Request.Url)。或者,更强类型的版本是创建您自己的LangaugeRoute()类,该类继承自Route。在该类上添加新属性LanguageCode,并在回答中的MapRoute中设置它。然后,您可以在OnActionExecuting()中强制转换它.我喜欢这样,但检查当前的文化也有风险,主要是因为您可能没有网站的实际版本。例如,土耳其文化有很多问题(谷歌Turkish-I问题)。无论如何,你必须在某个地方创建一组if/else或casing语句来处理你的翻译,以便在不正确的情况下默认为另一个。此外,这是Maarten Balliauw关于这个主题的一篇优秀博文。@DanAtkinson感谢你的回答。这对我帮助很大。但是如何创建“现在”ActionLink呢还有,去守护那条河