Search code examples
asp.net-mvcasp.net-mvc-4maproute

MVC 4, MapRoute for /{parameter} URL


How can I map a URL in this format

http://DOMAIN/{userID}

but not overriding the default format {controller}/{action}/{id}??

I tried this but it's not working:

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

routes.MapRoute("Users", "{userID}", new { controller = "Users", action = "GetUser" });

Solution

  • Insert This BEFORE the default route

    routes.MapRoute("Users", "{userID}", new { controller = "Users", action = "GetUser", userID=UrlParameter.Optional });

    Then the method GetUser must have a parameter named userID in order for the route handler to be able to route properly.

    Update :

    public class UsernameUrlConstraint : IRouteConstraint
    {
    
        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
                          RouteDirection routeDirection)
        {
            if (values[parameterName] != null)
            {
              // check if user exists in DB
              // if it does, return true
            }
            return false;
        }
    }
    

    In your routes :

    routes.MapRoute("Users",
                    "{userID}", 
                    new { controller = "Users", action = "GetUser" },
                    new {IsUser=new UsernameUrlConstraint()}
                    );
    

    Please note that this will hit the DB every time, so it might be a good idea to implement some memory cache (memcached, or .net memory cache) where you store the username and whether it exists or not, that way you will prevent not only db hits from users that exists but for users that don't exists. For example if someone decides to access user X 1000 times, this way you will only use the cached version instead of doing 1000 db calls.