如何以此格式映射网址
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" });
答案 0 :(得分:0)
您实际上无法根据您提供的信息。如果UserID采用可以使用正则表达式匹配的特定格式,则可以使用路由过滤器参数并按此过滤。该路线也需要列在默认路线上方。
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个字符之间的任何控制器名称。如果您可以使用更具体的正则表达式,则可以完成。
答案 1 :(得分: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命中,而且防止不存在的用户的db命中。例如,如果有人决定访问用户X 1000次,这样您将只使用缓存版本而不是1000 db调用。