0

I know it's more of the same (SO has more than 5,600 questions on this), but I've been sitting on this one for a couple of days now so I guess it was the right time to ask a question.

My requirements

I want to have the following routes in my asp.net mvc app:

  1. myapp.com/sigin -> Controller = Account, Action = SignIn
  2. myapp.com/signout -> Controller = Account, Action = SignOut
  3. myapp.com/joe.smith -> Controller = User, Action = Index
  4. myapp.com/joe.smith/following -> Controller = User, Action = Following
  5. myapp.com/joe.smith/tracks -> Controller = Tracks, Action = Index
  6. myapp.com/about -> Controller = About, Action = Index
  7. Any other default route, so that's why I left the standard one there.

My Code

 public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "About",
            url: "about",
            defaults: new { controller = "About", action = "Index" }
        );

        routes.MapRoute(
            name: "MyTracks",
            url: "{username}/tracks",
            defaults: new { controller = "MyTracks", action = "Index" }
        );

        routes.MapRoute(
            name: "MyTunes",
            url: "{username}/tunes",
            defaults: new { controller = "MyTunes", action = "Index" }
        );

        routes.MapRoute(
            name: "MyProfile",
            url: "{username}",
            defaults: new { controller = "User", action = "Index"},
            constraints: new { username = "" }
         );

        routes.MapRoute(
            name: "Account",
            url: "{action}",
            defaults: new { controller = "Account" }
        );

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

Issue

Routes number 3 and 4 just don't work as they get mixed up with route 1 and 2. I have tried debugging my code with Phil Haack's routing debugger, but no luck. Any ideas what I am doing wrong?

1 Answer 1

2

The problem is in your last two custom routes. All the routing framework has to work with is just a single token from the URL, and two possible routes to match it with. For example, if you attempt to go to the URL, /signin, how is the routing framework supposed to know there's not a user with username "signin". It's obvious to you, a human, what should happen, but a machine can only do so much.

You need to differentiate the routes in some way. For example, you could do u/{username}. That would be enough to help the routing framework out. Short of that, you'll need to define custom routes for each account action before the user route. For example:

routes.MapRoute(
    name: "AccountSignin",
    url: "signin",
    defaults: new { controller = "Account", action = "Signin" }
);

// etc.

routes.MapRoute(
    name: "MyProfile",
    url: "{username}",
    defaults: new { controller = "User", action = "Index"},
    constraints: new { username = "" }
 );

That way, any of the actual action names will match first.

Sign up to request clarification or add additional context in comments.

1 Comment

I totally agree with your point on a machine can only do so much, however, I was hoping to have a trick where I wouldn't have to go and manually add all routes to my account controller so I can differentiate from the profile controller. Bottom line, if I want to keep my routes like that I'd have to have a route for each action in accountcontroller and myprofilecontroller.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.