我试图制作一条路线,这样我就可以在网址中显示用户名:
这是我的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未更改。当我在route-config中设置username = "Test"
时,URL不会更改。
其次,我无法导航到我的其他控制器。如果我将网址更改为http://localhost123/Welcome,则不会发生任何事情。它应该将我重定向到新页面。
我在这里做错了什么?
如果我更改路线的顺序,我可以导航到其他页面,但用户名不显示在URL中。
我用谷歌搜索过,关于这个主题的所有答案都说我应该使用像上面这样的路线。
答案 0 :(得分:9)
如果网址为.../Product
意味着您要导航到Index()
ProductController
方法,那么您的路由就不会有效,因为它会匹配您的第一条路线(并假设" Product"是username
。如果true
有效且username
,则需要向路由约束添加路由约束,返回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);
}
}
}
如果网址为.../Bryan
,则会与User
路由匹配,您将在Index()
中执行UserController
方法(以及username
的值将是"Bryan"
)
如果网址为.../Stephen/Photos
,则会与UserPhotos
路由匹配,您将在Photos()
中执行UserController
方法(以及username
的值将是"Stephen"
)
如果网址为.../Product/Details/4
,则前2个路由定义的路由约束将返回false,您将执行Details()
的{{1}}方法
如果网址为ProductController
或.../Peter
且没有.../Peter/Photos
用户,则会返回username = "Peter"
请注意,上面的示例代码对用户进行硬编码,但实际上您将调用返回包含有效用户名的集合的服务。为避免在每个请求中访问数据库,您应该考虑使用404 Not Found
来缓存集合。代码首先检查它是否存在,如果没有填充,则检查集合是否包含MemoryCache
。如果添加了新用户,您还需要确保缓存无效。
答案 1 :(得分:0)
您需要为网站的不同部分对网址进行分类,以便网址模式匹配机制顺利进行。例如,在您的情况下,放置一个类别&#39; profile&#39;或其他任何东西。现在您的请求网址看起来像http://localhost1234/profile/john,路由将是
routes.MapRoute(
name: "users", // Route name
url: "Profile/{username}", // URL with parameters
defaults: new { controller = "Home", action = "Index" } // Parameter defaults
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
有关详细信息,请访问链接Routing in MVC