我正在尝试进行路由,以便可以在URL中显示用户名,如下所示:
http:// localhost1234 / john
这是我的routeconfig:
routes.MapRoute( name: "users", // Route name url: "{username}", // URL with parameters defaults: new { controller = "Home", action = "Index", username = "" } // Parameter defaults ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
这是我的HomeController:
public ActionResult Index(string username = "Test") { return View(); }
首先,URL不变。当我username = "Test"在route-config中进行设置时,URL不会更改。
username = "Test"
其次,我无法导航到其他控制器。如果我将URL更改为http:// localhost123 / Welcome,则不会发生任何事情。它应该将我重定向到新页面。
我在这里做错了什么?
如果更改路线顺序,则可以导航到其他页面,但用户名未显示在URL中。
我已经用谷歌搜索,关于这个问题的所有答案都说我应该使用上述路线。
就其本身而言,您的路由将不起作用,因为如果url .../Product意味着您想要导航至的Index()方法ProductController,则它将与您的第一个路由匹配(并假设“ Product”为username。您需要向您的路线添加路由约束true如果username有效,false则返回定义,否则无效(在这种情况下,它将尝试以下路线查找匹配项)。
.../Product
Index()
ProductController
username
true
false
假设您有UserController以下方法
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路由匹配,并且您将在中执行Index()方法UserController(并且的值username将为"Bryan")
.../Bryan
User
"Bryan"
如果url为.../Stephen/Photos,则它将与UserPhotos路由匹配,并且您将在中执行Photos()方法UserController(并且的值username将为"Stephen")
.../Stephen/Photos
UserPhotos
Photos()
"Stephen"
如果url为.../Product/Details/4,则对于前两个路由定义,路由约束将返回false,并且您将执行的Details()方法ProductController
.../Product/Details/4
Details()
如果url为.../Peteror .../Peter/Photos且没有用户使用,username = "Peter"则它将返回404 Not Found
.../Peter
.../Peter/Photos
username = "Peter"
404 Not Found
请注意,上面的示例代码对用户进行了硬编码,但实际上,您将调用返回包含有效用户名的集合的服务。为了避免打入数据库的每个请求,您应该考虑使用MemoryCache来缓存集合。该代码将首先检查它是否存在,如果不存在,则检查集合中是否包含username。如果添加了新用户,您还需要确保缓存无效。
MemoryCache