asp.net mvc多语言应用程序中的路由无法正常工作

asp.net mvc多语言应用程序中的路由无法正常工作,asp.net,asp.net-mvc,routes,Asp.net,Asp.net Mvc,Routes,我的asp.net mvc应用程序中有两条路线 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{culture}/{controller}/{action}/{id}", defaults: new { culture = CultureHelp

我的asp.net mvc应用程序中有两条路线

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

            routes.MapRoute(
                name: "Default no language",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
当我输入url
http://localhost/gallery
在浏览器中,我被重定向到
http://localhost/
,当我尝试
http://localhost/gallery/index
,我发现404错误

 The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

Requested URL: /gallery/index
当我向url添加任何实现的语言时(
http://localhost/en/gallery
),应用程序正在运行


我不熟悉路由和webapp编程,所以我想知道是否有人能帮我详细解释如何解决这个问题。

问题是你有两条路由,但第一条路由总是绑定的,因为它不能区分
{culture}/{controller}/{action}/{id}
{controller}/绑定时{action}/{id}
是区域性还是控制器名称

没有检查就无法判断,它只会绑定第一个匹配项

如果删除默认值,则它可能会起作用,但必须始终指定操作和控制器:

routes.MapRoute(
    name: "Default",
    url: "{culture}/{controller}/{action}/{id}",
    defaults: new { culture = CultureHelper.GetDefaultCulture(), 
    /* controller = "Home", action = "Index",*/ id = UrlParameter.Optional }
);
{culture}/{controller}/{action}/{id}
现在将绑定:

  • /en/gallery/actionName
  • /en/controllerName/actionName
  • /en/controllerName/actionName/idValue
{controller}/{action}/{id}
将绑定:

  • /画廊
  • /画廊/活动名称
  • /gallery/actionName/idValue
您的另一个选项是创建以验证第一个值是否为有效的区域性值:

public class IsValidCultureConstraint : IRouteConstraint
{
    public bool Match
        (
            HttpContextBase httpContext, 
            Route route, 
            string parameterName, 
            RouteValueDictionary values, 
            RouteDirection routeDirection
        )
    {

        if (string.IsNullOrWhiteSpace(values["culture"]))
        {
            return this.IsValidCulture();
        }

        return false;
    }

    private bool IsValidCulture(string cultureString)
    {
        //
        // Logic here to check valid culture(s)
        //

        // Example
        if (String.Equals(cultureString.Trim(), "en", 
               StringComparison.OrdinalIgnoreCase))
        {
            // English is valid
            return true;
        }

        return false;
    }
}


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

如果URL中输入的值是有效的区域性,那么它将只匹配第一个路由。当然,您需要提供正确执行检查的逻辑。

这起作用,并解决了主要问题,因为我可以在短时间内对其进行测试,但现在应用程序忽略了我的默认设置区域性,并采用默认浏览器区域性在开始时…另外,在应用程序开始时,当我在浏览器中输入localhost时,它总是转到localhost/culture/home/index…这两个路由不可能共存。如果您有
culture
约束的默认值,则将永远不会使用第二个路由。您可以在活动之间添加区域性n和id
{controller}/{action}/{culture}/{id}