0

如何以这种格式映射 URL

http://DOMAIN/{userID}

但不覆盖默认格式 {controller}/{action}/{id}??

我试过这个,但它不工作:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

routes.MapRoute("Users", "{userID}", new { controller = "Users", action = "GetUser" });
4

2 回答 2

0

在默认路由之前插入这个

routes.MapRoute("Users", "{userID}", new { controller = "Users", action = "GetUser", userID=UrlParameter.Optional });

然后方法 GetUser 必须有一个名为的参数userID,以便路由处理程序能够正确路由。

更新 :

public class UsernameUrlConstraint : IRouteConstraint
{

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
                      RouteDirection routeDirection)
    {
        if (values[parameterName] != null)
        {
          // check if user exists in DB
          // if it does, return true
        }
        return false;
    }
}

在您的路线中:

routes.MapRoute("Users",
                "{userID}", 
                new { controller = "Users", action = "GetUser" },
                new {IsUser=new UsernameUrlConstraint()}
                );

请注意,这每次都会命中数据库,因此在您存储用户名及其是否存在的地方实现一些内存缓存(memcached 或 .net 内存缓存)可能是个好主意,这样您就可以防止不只有来自存在但不存在的用户的用户的 db 命中。例如,如果有人决定访问用户 X 1000 次,那么您将只使用缓存版本而不是进行 1000 次数据库调用。

于 2014-06-02T17:13:36.357 回答
0

你真的不能根据你提供的信息。如果用户 ID 是您可以使用正则表达式匹配的特定格式,您可能可以使用路由过滤器参数并按此过滤。该路由也需要列在默认路由上方。

routes.MapRoute(
    name: "Users",
    url: "{userID}",
    defaults: new
    {
        controller = "Users",
        action = "GetUser",
    }, 
    new {postId = @"[\w]{3,7}" }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

但是,由于 \w 是任何单词字符,它仍然会匹配任何介于 3 到 7 个字符之间的控制器名称。如果您可以使用更具体的正则表达式,则可以完成。

于 2014-06-02T17:11:15.123 回答