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/postnameid
to 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 = @开发者_C百科"\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
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
精彩评论