4

I'm looking to setup routes that conform to these patterns:

/users
Mapped to action GetAllUsers()

/users/12345
Mapped to action GetUser(int id)

/users/1235/favorites
mapped to action GetUserFavorites(int id)

The controller should always be the UsersController. I thought that this would work, but it's not.

routes.MapRoute("1", 
                "{controller}/{action}/{id}", 
                new { id = UrlParameter.Optional, action = "index" });

routes.MapRoute("2", 
                "{controller}/{id}/{action}");

I'm struggling to wrap my head around it. Any help would be much appreciated.

2
  • 2
    Use the route debugger! Commented Nov 4, 2011 at 17:05
  • +1 for @bzlm - I was not aware of that tool - thanks Commented Nov 4, 2011 at 17:22

2 Answers 2

10

To accomplish your goal, you would need three separate routes in RegisterRoutes in global.asax.cs, which should be added in the following order, and must be before the Default route (this assumes that id must be an integer):

routes.MapRoute(
    "GetUserFavorites", // Route name
    "users/{id}/favorites",  // URL with parameters
    new { controller = "Users", action = "GetUserFavorites" },  // Parameter defaults
    new { id = @"\d+" } // Route constraint
);

routes.MapRoute(
    "GetUser", // Route name
    "users/{id}",  // URL with parameters
    new { controller = "Users", action = "GetUser" }  // Parameter defaults
    new { id = @"\d+" } // Route constraint
);

routes.MapRoute(
    "GetAllUsers", // Route name
    "users",  // URL with parameters
    new { controller = "Users", action = "GetAllUsers" }  // Parameter defaults
);
Sign up to request clarification or add additional context in comments.

3 Comments

so there is no generic way of setting it so that I don't have to hard code the action or controller name?
Given the requirements you outlined, the routing must be very specific. However, if you have a consistent URL naming scheme, and consistent action names between your controllers, it would be possible to make rules to serve multiple controllers, not just your Users controller.
@Micah - yes there are, but not for the mapping from URL to Action that you stated in your question. I added this to my answer as there is more room.
3

counsellorben got to the answer before I did. If you want those exact URLs and those exact methods then that is the only way. You could reduce the number of routes by combining GetUser and GetAllUsers into one action with a nullable id, e.g.

routes.MapRoute(
    "GetUser",
    "users/{id}",  
    new { controller = "Users", action = "GetUser", id = UrlParameter.Optional} 
    new { id = @"\d+" } // Route constraint
);

Which would call a method GetUser(int? id)

If you want to use the URL to set the controller and action called automatically you would need something like

   routes.MapRoute(
        "GetUser",
        "{controller}/{action}/{id}",  
        new { id = UrlParameter.Optional} 
        new { id = @"\d+" } // Route constraint
    );

But this would require you to change the URLs you wanted so /users/getuser/1234 would go to GetUser(int id) and /users/getallusers would go to GetAllUsers(). This is untested by the way - might be some slight mistakes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.