C# – Dynamically generating many routes in ASP.NET MVC… is this a totally bad idea

asp.netasp.net-mvcasp.net-mvc-routingcrouting

Here is my dilemma. I have a collection of entities that I want to use to define as the starting point for a set of routes. For example, I want to give all of the users in my site their own "subsites" of the form mydomain.com/username, and then hang all of the UserController actions off of that.

Here is a rough example of what I am doing:

I have a "UserController", with action methods like "Index", "Profile" and "Bio".

public ActionResult Profile( int UserID )
{
    User u = User.SingleOrDefault(u => u.UserID == UserID);
    return View(u);
}

In RegisterRoutes() method, I do this:

foreach (User user in User.Find(u => u.Active == true))
{
    routes.MapRoute(
         "",
         user.UserName + "/{action}",
         new { controller="User", action="Index", UserID=user.UserID }
     );
}

This works, and it works exactly as I want it to:

domain.com/[username]/Profile
domain.com/[username]/Bio

are now valid, working routes, and they can take in the UserID as the method parameter in the controller because each user gets their own route. Also, the default routes still work. Yay.

My question is, is this insane? I am creating an entry in the route table for every user in the system. How many routes is too many? Will this kill my server if there are over 10 users? 50? 1000?

And if this is insane, how else might I accomplish this goal?

Thanks in advance. I look forward to some input from the hive-mind.

Best Answer

There are a lot of concerns with your approach in my mind. What if someone has a username that matches one of your other controller names? You would never be able to call into that controller. Additionally, the routing system (as I understand it), tests all routes sequentially, meaning that thousands of routes would start to slow down routing lookups, including generation of Urls (like Url.Content() or Route.GetVirtualPath()).

Can't you just do

/{username}/{action}

and pass in the username as part of your parameters? What's the point of generating routes for each user if every route is going to the same controller and action methods?

If you need that to only match the User controller, consider implementing a custom route constraint. The link provides an example of creating a list of values that the controller parameter must match, but you could easily do it for your Action method names. Alternately, your custom constraint code could look up a username in the database to see if it matched.

Related Topic