【问题标题】:ASP.NET MVC twitter/myspace style routingASP.NET MVC twitter/myspace 风格的路由
【发布时间】:2010-01-15 11:28:22
【问题描述】:

这是我长期潜伏后的第一篇文章-所以请温柔:-)

我有一个类似于 twitter 的网站,人们可以注册并选择一个“友好的 url”,所以在我的网站上他们会有类似的内容:

mydomain.com/benjones

我也有根级静态页面,例如:

mydomain.com/about

当然还有我的主页:

mydomain.com/

我是 ASP.NET MVC 2 的新手(实际上我今天才开始),我已经设置了以下路线来尝试实现上述目标。

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("content/{*pathInfo}");
        routes.IgnoreRoute("images/{*pathInfo}");

        routes.MapRoute("About", "about",
            new { controller = "Common", action = "About" }
        );

        // User profile sits at root level so check for this before displaying the homepage
        routes.MapRoute("UserProfile", "{url}",
            new { controller = "User", action = "Profile", url = "" }
        );

        routes.MapRoute("Home", "",
            new { controller = "Home", action = "Index", id = "" }
        );
    }

在大多数情况下,这工作正常,但是,我的主页没有被触发!本质上,当您浏览到 mydomain.com 时,它似乎触发了带有空 {url} 参数的用户配置文件路由,因此永远无法访问主页!关于如何显示主页的任何想法?

【问题讨论】:

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


    【解决方案1】:

    知道不久前有人问过这个问题,但我只是想做同样的事情,找不到任何可以完全解决我问题的答案,所以我想我会为其他可能的人加 2 美分也希望将来做同样的事情。

    上面提出的解决方案的问题(如 Astrofaes 的评论中所述)是您需要为程序集中的每个控制器创建静态路由。所以最后我最终使用自定义路由约束来检查执行程序集中是否存在可以处理请求的控制器。如果有则在匹配时返回 false,以便请求将由另一个路由处理。

    public class NotControllerConstraint : IRouteConstraint
    {
        private static readonly IEnumerable<Type> Controllers = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.BaseType == typeof(Controller));
    
        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            return Controllers.Where(c => c.Name == values["id"] + "Controller").Count() == 0;
        }
    }
    

    然后可以按如下方式设置路线:

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

    【讨论】:

    • 这对我来说效果很好。只是想建议一个改变。如果您的控制器继承自自定义控制器类而不是基“控制器”类,则上述版本不起作用。可以这样修复:private static readonly IEnumerable&lt;Type&gt; Controllers = Assembly.GetExecutingAssembly().GetTypes().Where(t =&gt; typeof (Controller).IsAssignableFrom(t));
    • 另外,我想我也可以添加这个,有点挑剔,但 Match 的返回语句也可以简化。但结果相同。:return Controllers.All(c =&gt; c.Name != values["id"] + "Controller");
    【解决方案2】:

    可以不交换下面两条路线吗?

    【讨论】:

    • 谢谢!这似乎起到了作用。除了“关于”页面,我还会有“联系”、“帮助”等。有没有办法以编程方式找出哪些路由已经在使用,这样当用户注册用户名时,他们就会阻止获取应用程序 url,还是我需要在 url 黑名单中手动硬编码?
    【解决方案3】:

    交换路由起作用的原因是因为 {url} 路由没有针对空字符串的约束(这是您的最后一个路由)。结果,它将首先匹配空字符串,因为它在路由表中较高。

    考虑到这一点,您可以add constraints 或在路由表中添加您特别命名的路由,或者使用默认捕获 mvc 为您提供的所有路由。

    如果您想知道在任何给定时刻哪些路由匹配,那么您可以使用来自 Phil Haack 的 Route Debugger

    【讨论】:

      【解决方案4】:

      我希望为我的 MVC 1.0 应用程序实现相同样式的 url。

      我有 implemented that 和来自 Guy Burstein 的 blog post 的信息。

      感谢分享:)

      【讨论】:

        【解决方案5】:

        我有一个类似的设置如下:

            routes.MapRoute(
                "Common",
                "common/{action}/{id}",
                new { controller = "common", action = "Index", id = "" }
            );
        
            routes.MapRoute(
                "Home",
                "",
                new { controller = "Home", action = "Index", id = "" }
                );
        
        
            routes.MapRoute(
                "Dynamic",
                "{id}",
                new { controller = "dynamic", action = "Index", id = "" }
                );
        

        这让我变得灵活并拥有路线

        mysite.com/

        mysite.com/common/contact/ mysite.com/common/about/ mysite.com/common/{wildcard}/

        mysite.com/{anything}

        【讨论】:

          猜你喜欢
          • 2011-04-14
          • 1970-01-01
          • 2013-06-26
          • 1970-01-01
          • 2011-03-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多