【问题标题】:Having issues with MVC RoutingMVC 路由有问题
【发布时间】:2009-02-06 05:32:41
【问题描述】:

我正在尝试实现如下路由:

posts/535434/This-is-a-post-title

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}

并将默认操作设置为“显示”,它可以工作,但不允许我导航到其他命名操作,如“标记”。

我错过了什么?

谢谢!

【问题讨论】:

    标签: asp.net-mvc routing


    【解决方案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() }
    );
    

    【讨论】:

    • 好答案。问题虽然。我需要在 IRouteContraint 中做什么?我没用过,能不能多解释一下。
    • 您可以执行任何有意义的逻辑来验证它尝试针对路由验证的请求。 Match() 方法为您提供路线和提供的值,您可以编写 if(values["PostID"] = "foo") return true;
    【解决方案2】:

    我不是 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 方法。

    【讨论】:

      【解决方案3】:

      实际上没有使用作为“描述”的网址部分。 例如,这篇文章是 519222,我仍然可以使用 url:Having issues with MVC Routing

      【讨论】:

        猜你喜欢
        • 2011-07-31
        • 1970-01-01
        • 2016-11-09
        相关资源
        最近更新 更多