4

I want to map a route like this:

mysite.com/username

in ASP.NET MVC 3 application; How can I do it, please? Thanks to all, regards

amiry jd
  • 27,021
  • 30
  • 116
  • 215

2 Answers2

2

Maybe add custom route at the very beginning that would inherit from System.Web.Routing.Route, and override method

protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, 
   string parameterName, RouteValueDictionary values, RouteDirection routeDirection)

where you would check in db using indexed column.

Just add some not nullable constraint object like

Constraints = new { username = "*" }

so that route object will process constraints.

Before hitting database maybe make some heuristics whether this can be username. Remember you cant have user same as controller (when having default action), so you want to limit that somehow. Pay attention if that wont hurt year performance, but you probably dont have many routes with single value after slash.

This is how you can do this.

public class UserRoute : Route
{
    public UserRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
        : base(url, defaults, constraints, routeHandler)
    {
    }

    protected override bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.UrlGeneration)
            return true;

        object value;
        values.TryGetValue(parameterName, out value);
        string input = Convert.ToString(value, CultureInfo.InvariantCulture);
        // check db
        if (!CheckHeuristicIfCanBeUserName(input))
        {
            return false;
        }

        // check in db if exists, 
        // if yes then return true
        // if not return false - so that processing of routing goes further
        return new[] {"Javad_Amiry", "llapinski"}.Contains(input);
    }

    private bool CheckHeuristicIfCanBeUserName(string input)
    {
        return !string.IsNullOrEmpty(input);
    }
}

This add at the beginning.

routes.Add(new UserRoute("{username}", 
            new RouteValueDictionary(){ {"controller", "Home"}, {"action", "About"}}, 
            new RouteValueDictionary(){ { "username", "*" }}, new MvcRouteHandler()));

Works for me in both ways, generating and incomming.

MorioBoncz
  • 920
  • 11
  • 22
  • Probably cleaner would be to just use IRouteConstraint and derive from there, though you can do the same thing. – MorioBoncz Jul 10 '11 at 20:40
1

Maybe something like this?

routes.MapRoute(
    "Profile",
    "{username}",
    new { controller = "Profile", action = "View" }
);

With your controller being

public class ProfileController : Controller {

    public ActionResult View(string username) {
       // ...
    }

}
Bertrand Marron
  • 21,501
  • 8
  • 58
  • 94
  • thanks, but what about if there was a route like this: routes.MapRoute( "default", "{controller}/{action}/id", new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); – amiry jd Jul 02 '11 at 03:46
  • At least for me, a route like this will need to be at the top of the routes list. When it was below the 'default' route, I kept getting unable to find resource errors. Moving it fixed the issue. – RichieMN Jun 19 '14 at 22:21