我正在尝试实现以下路由:
文章/ 535434 /这-是-A-后标题
posts/tagged/tags+here
// Matches {controller}/{action}/{id} - Default
// Displays all posts with the specified tags
// uses PostsController : ActionTagged(string tags)
posts?pageSize=50&pageIndex=4
// Matches {controller}/{action}/{id} - Default
// Displays all posts
// uses PostsController : Index(int? pageSize, int? pageIndex)
以下是我想要解决的问题:
posts/39423/this-is-a-post-title-here
// Typically this is implemented using an action like 'Details'
// and would normally look like : posts/details/5
我似乎无法使路由正常工作。我试过这样的事情:
{controller}/{id}/{description}
并将默认操作设置为“显示”,但不允许我导航到“标记”等其他命名操作。
我错过了什么?
谢谢!
答案 0 :(得分:1)
两件事:
首先,你应该总是按照递减的特异性排序你的路线(例如,大多数特定情况优先,最不具体的情况最后),这样路线将“通过”,如果一个不匹配,它将尝试下一个。
所以我们要在定义{controller} / {action} / ...(可能是其他任何东西)之前定义{controller} / {postid} / ...(必须是postid)
接下来,我们希望能够指定如果postid的提供值看起来不像Post ID,则路径应该失败并进入下一个路径。我们可以通过创建IRouteConstraint类来实现:
public class PostIDConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection)
{
//if input looks like a post id, return true.
//otherwise, false
}
}
我们可以将它添加到路径定义中,如下所示:
routes.MapRoute(
"Default",
"{controller}/{postid}/{description}",
new { controller = "Posts", action = "Display", id = 0 },
new { postid = new PostIDConstraint() }
);
答案 1 :(得分:0)
我不是100%我理解你的问题,但听起来你可以定义几条不同的路线。
routes.MapRoute("PostId", "posts/{id}/{title}",
new { Controller = "Posts", Action = "DisplayPost", id = 0, title = "" },
new { id = @"\d+" });
routes.MapRoute("TaggedPosts", "posts/tagged/{tags}",
new { Controller = "Posts", Action = "DisplayTagged", tags = "" });
routes.MapRoute("Default", "posts",
new { Controller = "Posts", Action = "Index" });
您可以使用正则表达式来验证我在第一个路径中用于id的参数,或者如果您想要更好的验证,请执行Rex M发布的操作。查询字符串参数pageSize和pageIndex不需要包含在您的路由中;只要参数名称匹配,它们就会被传递给您的Index方法。
答案 2 :(得分:0)
实际上不使用“描述”的网址部分。 例如,这篇文章是519222,我仍然可以使用网址:Having issues with MVC Routing