Question

I'm trying to have a page on an ASP.NET MVC based web site where one page allows selecting by username instead of ID. I would have thought the route needs to be something like:

routes.MapRoute(
  "CustomerView", "Customer/Details/{username}",
  new { username = "" }
);

routes.MapRoute(
  "Default", "{controller}/{action}/{id}",
  new { controller = "Home", action = "Index", id = "0" }
);

but whenever I use HTML.Actionlink I get http://mysite.com/Customer/Details?username=valuehere . I considered a generic route like:

routes.MapRoute(
  "CustomerView", "Customer/Details/{username}",
  new { controller="Customer", action = "Details", username = "" }
);

but I imagine it would cause more problems when it mistakes which route should be applied of the two.

Was it helpful?

Solution

I'm not sure I fully understand the question... are you saying you want:

  1. one route {controller}/{action}/{username} that handles URLs where the 3rd token is a string, matching actions where there is a string "username" argument, and

  2. another route {controller}/{action}/{id} that handles URLs where the 3rd token is an integer, matching actions where there is an integer "id" argument?

If so, check the out the overload for MapRoute that takes a 4th argument specifying route constraints. It should let you do something like this:

routes.MapRoute(
    "CustomerView", "{controller}/{action}/{username}",
    new { controller="Customer", action = "Details", username = "" }
    new { username = @"[^0-9]+" }
);

This (untested) constraint should cause the {username} route to match anything where the 3rd token contains at least one non-digit character.

Of course, if it's legal for usernames to consist entirely of digits then this may not work for you. In that case, you may need to create specialized routes for each action that accepts a username instead of an ID.

OTHER TIPS

Does the Details method of your Customer controller have a "username" parameter, instead of an id parameter?

If the parameters don't match then they get appended as querystring variables.

This works:

routes.MapRoute(
  "CustomerView", "Customer/Details/{username}",
  new { controller="Customer", action = "Details", username = "" }
);

but in the above question the mistake I made in the second example was I meant:

routes.MapRoute(
  "CustomerView", "{controller}/{action}/{username}",
  new { controller="Customer", action = "Details", username = "" }
);

It just means I'll have to specifically declare a route for each instance where I pass a string value.

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