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

And*_*rew 3 c# asp.net-mvc routing routes asp.net-mvc-routing

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

http://localhost:12816/en/Statistic/Reports
Run Code Online (Sandbox Code Playgroud)

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

"'''应用程序中的服务器错误.无法找到资源."

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

例如,我希望这些链接完全相同:

http://localhost:12816/Statistic/Reports
http://localhost:12816/en/Statistic/Reports
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我注意到当我要求没有语言的短链接时 - 一切正常:

http://localhost:12816/Statistic/
Run Code Online (Sandbox Code Playgroud)

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

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

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
        });
Run Code Online (Sandbox Code Playgroud)

Dan*_*.G. 5

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

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 }
);
Run Code Online (Sandbox Code Playgroud)

如果你没有为lang参数添加约束,那么类似的url /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 route值,并且当路径数据中缺少值时,您可以将其视为默认语言.

例如,假设您已创建了一个全局过滤器,它将根据此路由参数在线程上设置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;                
    }
}
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助!