3

ASP.NET MVC 2 controllers and actions use UpperCamelCase.

For some reasons many big sites, including SO, use lowercase (with underscore) for controllers and actions in the urls. Examples:

https://stackoverflow.com/questions
https://stackoverflow.com/users/377920/randomguy
http://www.reddit.com/ad_inq/
http://www.wired.com/special_multimedia/mobile/
etc.

I would like to know how this is accomplished.

The default router seems to be case-insensitive, ie. stackoverflow.com/questions/ask will be directed to Questions-controller's Ask() method without a problem.

However, say we want to direct questions/add_to_favorites to Questions-controller's AddToFavorites() action.

  1. How is this accomplished?
  2. Is it now required to use Html.ActionLink("add_to_favorites") instead of Html.ActionLink("AddToFavorites") to make the links in the HTML point as questions/add_to_favorites instead of Questions/AddToFavorites?

Edit: Similar posts

One way to support underscores is to use the ActionName attribute:

[ActionName("add_to_favorites")]
public ActionResult AddToFavorites() {
  // ...
}

However, this doesn't work for controllers. Perhaps if we could somehow remove all the underscores from the request before it gets to the routing mechanism, then it would work.

Community
  • 1
  • 1
randomguy
  • 12,042
  • 16
  • 71
  • 101
  • Quick side note. Please ensure that `add_to_favorite` requires POST. GET request should never modify state on the server – Earlz Jun 29 '10 at 23:42
  • Agreed! This is seriously not only for RESTful purists: state changing GET requests create security holes. Although, if you force authorization and prevent cross-site request forgery (using AntiForgeryToken), I don't think GET'ing is a problem technically speaking. – randomguy Jun 29 '10 at 23:48
  • And please note that simply adding [HttpPost] won't solve the security issues; the bad guy could simply emulate a form post. So even though you are forcing POSTs (or DELETEs/PUTs from AJAX), you still have be careful. – randomguy Jun 29 '10 at 23:56

1 Answers1

2

You can add custom routes manually. This is not an universal solution and must be added for every controller and action separately.

routes.MapRoute(
    "Web2.0 RoR style lowercase URLs with underscores", 
    "questions-foo/add_to_favorites", 
    new { controller = "Questions", action = "AddToFavorites" }
);

The cool thing is that the URL generating Html-helper methods don't need to be modified. The routing table is used to route incoming requests and to generate URLs. So,

Html.ActionLink("Add to favorites", "Questions", "AddToFavorites"); maps to /questions-foo/add_to_favorites.

Note that the original /Question/AddToFavorites still works as does /qUeStIoN/aDdtOfAvOrItEs as well as /qUeStIoNs-FOO/ADD_TO_FAVORITES because the default routing mechanism is case-insensitive.

randomguy
  • 12,042
  • 16
  • 71
  • 101