【问题标题】:Routes not working properly in asp.net mvc multilanguage app路由在 asp.net mvc 多语言应用程序中无法正常工作
【发布时间】:2015-10-22 09:24:51
【问题描述】:

我的 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 编程的新手,所以如果有人可以帮助我详细解释如何解决这个问题,我会很高兴。

【问题讨论】:

    标签: asp.net asp.net-mvc routes


    【解决方案1】:

    问题是你有两条路线,但第一条路线将始终绑定,因为在绑定/gallery 时它无法区分{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
    • /gallery/actionName/idValue

    您的另一个选择是创建一个custom route constraint 来验证第一个值是有效的文化值:

    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 这样的 url / 在应用程序启动时,当我在浏览器中输入 localhost 时,它总是转到 localhost/culture/home/index...
    • 两条路线不可能共存。如果您有 culture 约束的默认值,那么您的第二条路由将永远不会被使用。
    • 您可以在操作和 ID {controller}/{action}/{culture}/{id} 之间添加文化,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 2019-04-21
    • 2017-06-15
    • 2020-12-30
    • 1970-01-01
    相关资源
    最近更新 更多