ASP.NET MVC twitter/myspace风格的路由

ASP.NET MVC twitter/myspace风格的路由,asp.net,asp.net-mvc,routes,Asp.net,Asp.net Mvc,Routes,这是我在长期潜伏之后的第一篇帖子,所以请温柔一点:-) 我有一个类似于twitter的网站,人们可以注册并选择一个“友好的url”,因此在我的网站上,他们会有如下内容: mydomain.com/benjones 我还有根级别的静态页面,例如: mydomain.com/about 当然还有我的主页: mydomain.com/ 我是ASP.NETMVC2的新手(事实上我今天才开始学习),我已经设置了以下途径来尝试实现上述目标 public static void RegisterRou

这是我在长期潜伏之后的第一篇帖子,所以请温柔一点:-)

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

mydomain.com/benjones

我还有根级别的静态页面,例如:

mydomain.com/about

当然还有我的主页:

mydomain.com/

我是ASP.NETMVC2的新手(事实上我今天才开始学习),我已经设置了以下途径来尝试实现上述目标

    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}参数的用户配置文件路由,因此永远无法访问主页!关于如何显示主页有什么想法吗?

你不能交换最下面的两条路径吗?

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

我从这篇文章和盖伊·伯斯坦那里得到了一些信息


感谢分享:)

交换路由之所以有效,是因为{url}路由没有针对空字符串的约束(这是您的上一个路由)。因此,它将首先匹配空字符串,因为它在路由表中较高

考虑到这一点,您可以在routes表的更高位置添加特定命名的routes,也可以使用mvc提供的默认catch all routes开始


如果您想知道在任何给定时刻匹配的路由,则可以使用Phil Haack提供的。

我有一个simlar设置,如下所示:

    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}

我知道这个问题是前一段时间问的,但我只是想做同样的事情,找不到任何对我来说完全解决问题的答案,所以我想我会为将来可能也会做同样事情的其他人加上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;
    }
}

非常感谢。这似乎奏效了。除了“关于”页面,我还将有“联系”、“帮助”等。是否有一种方法可以通过编程找出哪些路由已经在使用,这样当用户注册用户名时,他们将无法获取应用程序url,或者我需要手动硬编码url黑名单?这对我来说非常有效。我只是想建议一个改变。如果控制器继承自自定义控制器类而不是基“控制器”类,则上述版本不起作用。它可以这样修复:
private static readonly IEnumerable Controllers=Assembly.getExecutionGassembly().GetTypes()。其中(t=>typeof(Controller.IsAssignableFrom(t))另外,我想我还可以添加这个,有点挑剔,但是Match的返回语句也可以简化。但结果相同。:
返回Controllers.All(c=>c.Name!=值[“id”]+“Controller”)
 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 });