ASP.NET MVC路由,404当我删除文化(语言)

时间:2014-05-08 09:53:12

标签: c# asp.net-mvc routing routes asp.net-mvc-routing

我的问题: 当我使用以下链接时,一切正常:

http://localhost:12816/en/Statistic/Reports

但是当我删除“/ en”时 - 我收到应用程序错误:

“/'应用程序中的服务器错误。无法找到资源。”

我有几种不同语言的资源文件。当用户请求没有任何语言标识的链接时,我希望我的应用程序使用默认语言(英语)。

E.g。我希望这些链接完全相同:

http://localhost:12816/Statistic/Reports
http://localhost:12816/en/Statistic/Reports
是的,我注意到当我要求没有语言的短链接时 - 一切正常:

http://localhost:12816/Statistic/

但是当链接更深时,我得到并且错误

我认为问题在于路由,但我是路由的新手,所以请帮帮我:)。

PS:我尝试过这样,但它不起作用:

routes.MapRoute("Default", "{lang}/{controller}/{action}/{id}",                 
        new{
            lang = "en",
            controller = "Home",
            action = "Index",
            id = UrlParameter.Optional,
        });

routes.MapRoute("Default no language", "{controller}/{action}/{id}",
        new
        {
            controller = "Home",
            action = "Index",
            id = UrlParameter.Optional
        });

1 个答案:

答案 0 :(得分:5)

您可以尝试从无语言路由中删除默认的“lang”值,并在语言路由中添加正则表达式常量(例如,允许使用“en”或“en-US”等文化名称,请检查{{3}关于文化名称的正则表达式):

routes.MapRoute(
    name: "Default lang",
    url: "{lang}/{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    constraints: new { lang = @"[a-z]{2,3}(?:-[A-Z]{2,3})?" }
);

routes.MapRoute(                
    name: "Default no language",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

如果你没有为lang参数添加约束,那么像/Statistics/Reports这样的网址将始终与语言路由(因为它首先定义)匹配错误的参数lang=Statistics, controller=Report, action=Index

因此,使用此路由配置,您将获得以下结果:

  • / - >路由到Home / Index,没有lang的路由值
  • /Home - >路由到Home / Index,没有lang的路由值
  • /Home/About - >路由到Home / About,没有lang的路由值
  • /en - >路由到Home / Index,路由值为lang = en
  • /en/Home - >路由到Home / Index,路由值为lang = en
  • /en/Home/About - >路由到Home / About,路由值为lang = en

然后,您可以对获取资源所涉及的任何逻辑使用 lang 路由值,并且当路径数据中缺少值时,您可以将其视为默认语言。

例如,假设您已创建了一个全局过滤器,它将根据此路由参数在线程上设置CurrentCulture和CurrentUICulture。如果没有提供lang,你可以保留它们的默认值(服务器或web.config上配置的值),否则根据lang参数覆盖它们:

public class InitializeCultureAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.RouteData.Values.ContainsKey("lang")) return;

        var culture = filterContext.RouteData.Values["lang"] as string;
        if (String.IsNullOrEmpty(culture)) return;

        var cultureInfo = CultureInfo.GetCultureInfo(culture);
        Thread.CurrentThread.CurrentCulture = cultureInfo;
        Thread.CurrentThread.CurrentUICulture = cultureInfo;                
    }
}

PS。我并不是说你应该使用这个属性,我只想展示一个如何处理路由数据中没有lang值的例子。因此,通过上面的路由,您应该能够通过查看路径数据中的lang参数来调整处理资源的逻辑(尽管我猜您可能希望在这种情况下设置CurrentUICulture!)

希望这有帮助!