【问题标题】:ASP.NET MVC 3.0 Routing behaviourASP.NET MVC 3.0 路由行为
【发布时间】:2011-09-02 12:47:25
【问题描述】:

我有控制器 BlogController 有几个动作:

1)Index(string id) - show all posts/show single post if parameter id specified
2)New() - add new post
3)Delete() - delete post
4)And some more another actions

所以如果我在浏览器中输入 mysite/blog 我可以看到所有帖子如果我输入 mysite/blog/postnameid 我想看到单个帖子。

问题是当我输入mysite/blog/postnameid 时它不工作 (The resource cannot be found.),但如果我输入mysite/blog/index/postnameid 以这种方式工作。我怎样才能让mysite/blog/postnameid也能正常工作。

这是我在global.ascx的博客路线

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 routes.MapRouteLowercase(
               "Blog", // Route name
               "Blog/{action}/{id}", // URL with parameters
               new { controller = "Blog", action = "Index" } // Parameter defaults
            );

            routes.MapRouteLowercase(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
            );

如果我这样改变它

routes.MapRouteLowercase(
               "Blog", // Route name
               "Blog/{id}", // URL with parameters
               new { controller = "Blog", action = "Index" } // Parameter defaults
            );

mysite/blog/postnameid 工作,但所有其他操作,如 New()、Delete() 之后停止工作 (The resource cannot be found.)

更新: 我忘了提到 id 是 sting,而不是 int。所以从@Darin 回答我将new { id = @"\w+" } 更改为new { id = @"\d+" } 并且所有接缝都可以工作,但是现在当我输入blog/new 时,它正在路由到show/new insteard blog/new

【问题讨论】:

    标签: asp.net-mvc-3 routing asp.net-mvc-routing


    【解决方案1】:

    使用单个控制器操作来做两件事是一个坏主意并且违反 RESTful 约定,当然这违反了单一责任原则(如果没有指定 id,则列出所有帖子,如果指定了 id,则显示给定帖子) .正确的方法是:

    • /blog => BlogController/Index => 列出所有帖子
    • /blog/123 => BlogController/Show(id = 123) => 显示给定帖子的详细信息
    • /blog/new => BlogController/New() => 开始写新文章
    • /blog/delete/123 => BlogController/Delete(id = 123) => 删除给定的帖子

    这将通过以下路线实现:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapRoute(
            "Blog",
            "blog/{id}",
            new { controller = "Blog", action = "Show" },
            new { id = @"\d+" }
        );
    
        routes.MapRoute(
            "Default",
            "blog/{action}/{id}",
            new { controller = "Blog", action = "Index", id = UrlParameter.Optional }
        );
    }
    

    注意第一个定义中所需的路由约束,它指示所有 id 必须是什么形式,以便路由引擎可以消除 id 和操作名称之间的歧义。

    这就是说,如果你想违反我前面提到的 2 条原则,并且有你想要的路线,则需要稍微调整一下:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapRoute(
            "Blog",
            "blog/{id}",
            new { controller = "Blog", action = "Index" },
            new { id = @"\d+" }
        );
    
        routes.MapRoute(
            "Default",
            "blog/{action}/{id}",
            new { controller = "Blog", action = "Index", id = UrlParameter.Optional }
        );
    }
    

    现在:

    • /blog => BlogController/Index(id = null) => 列出所有帖子
    • /blog/123 => BlogController/Index(id = 123) => 显示给定帖子的详细信息
    • /blog/new => BlogController/New() => 开始写新文章
    • /blog/delete/123 => BlogController/Delete(id = 123) => 删除给定的帖子

    【讨论】:

    • 感谢您提供如此详细的回复,因此默认路由将仅处理博客内容,但如果我需要另一个类似于博客路由的行为,在这种情况下我不能有两个“默认”不是路线图吗?
    • url /blog 不能映射到两个不同的默认路由,这是不可能的,也没有意义。但是,您可以使用另一条路线,例如 /page ,默认为默认页面或其他内容。同样根据达林的建议,我只会做出一个改变,并将列出帖子的路线命名为 /posts。或者,如果您有一个名为“博客”的区域,那么它将是 /blog/posts。我喜欢末尾的 s 来表示多重性
    • 一些更详细的信息,我的 id 正在搅拌,但是当我输入 int 时它可以工作 /blog/123,但 blog/slagurl 不行,我怎样才能让它与字符串参数一起工作?
    • @jason,字符串模式存在问题,因为路由引擎无法消除 /blog/slagurl 和 /blog/new 之间的歧义。他不知道在第一种情况下你在谈论一个 id 而在第二种情况下你在谈论一个动作名称。诸如\d+ 之类的路由约束仅在它们允许您消除url 歧义时才起作用。看来这不是你的情况。因此,为了解决这个问题,您可以通过从Route 类派生并覆盖GetRouteData 方法来编写自定义Route。
    • 我正在查看 NBlog http://nblog.codeplex.com/,他们有类似的东西,但他们使用的路线定义有点不同,我不能像我想的那样拥有相同的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多