Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

ASP.NET MVC 3.0 Routing behaviour

I have controller BlogController with a couple of actions:

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

So if i type in browser mysite/blog i could see all posts if i type mysite/blog/postnameid i want to see single post.

the problem is when i type mysite/blog/postnameid it is not working (The resource cannot be found.), but if i type mysite/blog/index/postnameid this way it is working. How could i make mysite/blog/postnameidto work as well.

Here is my blog route in 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 } 
            );

Than if i change it like that

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

the mysite/blog/postnameid working but all another actions like New(), Delete() stop working after that (The resource cannot be found. )

UPDATE: I forgot to mention that id is sting, not int. so from @Darin answer i changed new { id = @"w+" } to new { id = @"d+" } and all seams to be working but now when i typed blog/new for example, it is routing to show/new insteard blog/new

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It is a bad idea and against RESTful conventions to have a single controller action that do 2 things and of course violating the single responsibility principle (list all posts if no id is specified and show a given post if an id is specified). The correct way would be to have the following:

  • /blog => BlogController/Index => list all posts
  • /blog/123 => BlogController/Show(id = 123) => show details of a given post
  • /blog/new => BlogController/New() => start writing a new post
  • /blog/delete/123 => BlogController/Delete(id = 123) => delete given post

which would be achieved with the following routes:

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 }
    );
}

Notice the required route constraint on the first definition which indicates what form all ids must be so that the routing engine could disambiguate between an id and an action name.

This being said if you want to violate the 2 principles I mentioned earlier and have the routes you want a slight adaptation would be required:

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 }
    );
}

Now:

  • /blog => BlogController/Index(id = null) => list all posts
  • /blog/123 => BlogController/Index(id = 123) => show details of a given post
  • /blog/new => BlogController/New() => start writing a new post
  • /blog/delete/123 => BlogController/Delete(id = 123) => delete given post

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...