为了满足您的需要,将 Route 配置更改为:
routes.MapRoute(
name: "Language",
url: "{language}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, language="en" },
constraints: new {language=new LanguageConstraint()}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
两个关键部分是路线本身{language}/{controller}/{action}/{id}
和约束部分new {language=new LanguageConstraint()}
。
第一部分将选择该{language}
部分作为控制器的变量(现在默认为 en)。控制器签名:
public ActionResult Index(string language) {
将选择新的语言变量。由于向每个控制器添加语言可能看起来很麻烦,您可以创建一个 ViewModelBase 类来传递给每个控制器,该类具有包含语言值的属性,每个后续视图模型类都继承自该语言值。
如果没有约束,路由模式将获取语言部分的 url 中的所有值,并且编写一个正则表达式来匹配所有想要的语言值将是乏味的,我认为编写一个基于 IRouteConstraint 的类更容易,类似于以下内容:
public class LanguageConstraint : IRouteConstraint{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
RouteDirection routeDirection) {
//create accepted lanaguages collection from somewhere.
string[] languageArray = new[]{"en","jp", "de"};
string language = values["language"].ToString();
if (string.IsNullOrEmpty(language))
return false;
return languageArray.FirstOrDefault(l=>l.Equals(language,StringComparison.InvariantCultureIgnoreCase)) != null;
}
}
只需创建一个已知语言值的列表,并根据该列表检查提供的语言值。如果不存在则返回 false 并抛出 404。