就其本身而言,您的路由将不起作用,因为如果 url 是 .../Product,这意味着您想导航到 ProductController 的 Index() 方法,它将匹配您的第一个路由(并假设“产品”是username。如果username 有效则返回true,如果无效则返回false(在这种情况下,它将尝试以下路由来查找匹配项)。
假设您有一个UserController,使用以下方法
// match http://..../Bryan
public ActionResult Index(string username)
{
// displays the home page for a user
}
// match http://..../Bryan/Photos
public ActionResult Photos(string username)
{
// displays a users photos
}
那么你的路由定义需要是
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "User",
url: "{username}",
defaults: new { controller = "User", action = "Index" },
constraints: new { username = new UserNameConstraint() }
);
routes.MapRoute(
name: "UserPhotos",
url: "{username}/Photos",
defaults: new { controller = "User", action = "Photos" },
constraints: new { username = new UserNameConstraint() }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Test", action = "Index", id = UrlParameter.Optional }
);
}
public class UserNameConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
List<string> users = new List<string>() { "Bryan", "Stephen" };
// Get the username from the url
var username = values["username"].ToString().ToLower();
// Check for a match (assumes case insensitive)
return users.Any(x => x.ToLower() == username);
}
}
}
如果url是.../Bryan,它将匹配User路由,你将在UserController中执行Index()方法(username的值将是"Bryan")
如果url是.../Stephen/Photos,它将匹配UserPhotos路由,你将在UserController中执行Photos()方法(username的值将是"Stephen")
如果url是.../Product/Details/4,那么路由约束对于前2个路由定义会返回false,你会执行ProductController的Details()方法
如果 url 是 .../Peter 或 .../Peter/Photos 并且没有 username = "Peter" 的用户,那么它将返回 404 Not Found
请注意,上面的示例代码对用户进行了硬编码,但实际上您将调用一个服务,该服务返回一个包含有效用户名的集合。为了避免每次请求都访问数据库,您应该考虑使用MemoryCache 来缓存集合。代码将首先检查它是否存在,如果不填充它,然后检查集合是否包含username。如果添加了新用户,您还需要确保缓存失效。