ASP.NET MVC 3.0路由行为

时间:2011-09-02 12:47:25

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

我的控制器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 {{1 }}

1 个答案:

答案 0 :(得分:2)

使用单个控制器操作执行两项操作并且当然违反单一责任原则(如果未指定id则列出所有帖子并且如果指定了id则显示给定帖子),这是一个坏主意并且针对RESTful约定。正确的方法是拥有以下内容:

  • /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)=>删除给定的帖子