Question

I'm a bit hesitant to put this broad question here but I just can't find the keywords I need to use to research this.

I'm having a hard time finding a way to have a Custom Route in ASP.Net MVC 4 (or 5) to recreate what I've seen all over the place on the web.

What I need is that if a user goes to http://www.myApp.com/user1 the route will take that and interpret this as http://www.myApp.com/Users/Index/user1 and forward the request to the right controller in this case Users and the right Action with the Id of user1

I can create a broad Route that will catch this but it will disable all the default routing that I will need, if I let it go down the pipeline the default route will catch this and the user will get a 404.

I suppose I can manually have all the controllers routed and the put this one last to catch the rest but I really don't think that is the best solution, Is it?

Was it helpful?

Solution

This is tricky because the username parameter could override your action methods that are in the same controller, and even implicit action methods in other controllers.

Example

Supposed you have an action method in your HomeController called "Profile"

http://www.myapp.com/profile/

All is fine until one of your users decided to use the word "profile" as their username. Suddenly the username profile could override the action method profile, now your users could no longer go to the profile page.

Route Configuration.

Here is the route configuration that you are looking for. Of course this doesn't solve the problem mentioned earlier. You just have to stop users from using usernames with special meanings.

// /{username} configuration
routes.MapRoute(
    name: "UserIndexRoute",
    url: "{username}",
    defaults: new { controller = "Users", action = "Index", username= UrlParameter.Optional },
    namespaces: new[] { "MyApp.Controllers" }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    namespaces: new[] { "MyApp.Controllers" }
);

OTHER TIPS

I always recommand http://attributerouting.net/, because it is so much easier to create nice and seo-friendly urls.

With attribute routing it will look like this:

public class UserController : Controller
{
     [GET("/users/{userName}")]
     public ActionResult UserRedirect(string userName)
     {
         return RedirectToAction(User, new { userName = userName });
     }

     [GET("/users/index/{userName}")]
     public ActionResult User(string userName)
     {
         return RedirectToAction(User, new { userName = userName });
     }
 }

If you are using MVC 5, there is also a builtin attribute mechanism. If you do not want to use attributes, you have to use some blacklists, so that the username ist no interpreted as action name:

http://weblogs.asp.net/jasonconway/archive/2009/10/23/include-and-exclude-constraints-in-asp-net-mvc.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top