Search code examples
asp.net-mvcasp.net-mvc-routing

ASP.Net Routing Issues


I am newish to MVC and I've looked around and nothing has exactly met my needs.

Here is how I want my routes set up:

domain/{action}
domain/{username}/{action}
domain/{username}

(username takes the place of id) The same controller is used for all three.

If I type all three in, it should load the page for me

Here is what I originally have. It doesn't work. I have URL.Action methods creating links for me, and they don't create them properly. I tried switching the order, but issues still remain, which means I'm missing something conceptually about the routing.

Here is what I originally had

routes.MapRoute(
    "WithUsername","{username}",
    new { controller = "Home", action = "Landing"}
);
routes.MapRoute(
    "WithOutUsername",
    "{action}",
    new { controller = "Home", action = "Landing"}
);

routes.MapRoute(
    "Default",
    "{username}/{action}",
    new {controller = "Home", action = "Landing"}
);

Could anyone lead me in the right direction?

Here is an example on how the link is messed up. Let's say I click on the Url to take me to Learning Resources. The URL.Action points to the Learning Resources action. There are no duplicate names.

Here is the URL.Action

<a href="@Url.Action(title.actionName, title.controllerName, new {Model.username})">@title.name</a>

Instead of getting this

domain/LearningResources

I get this

domain/LearningResources?username=LearningResources

Somehow it detects LearningResources as the username, even though there is no username. All my actions take username as an optional parameter (set up as string username = ""), so it seems to be confused as to what is a username and what is an action, because if I type it in the URL manually it works as intended.

It also seems to only mess up if I initally use just the domain as my address. If I start off with domain/{action} or domain/{username} all the links work accordingly.

Would the fix be to reroute just the domain to always be domain/{action}?


Solution

  • Ok, so the solution to this is extremely simple. Thanks to NightOwl888 for the help.

    One is that username will always be in the format of "word.word". Actions will never have periods for that, so I can use Regex to check for that and route accordingly.

    Secondly, specific routes to actions can be set up. Lets say I have two different controllers, but I still want to have the same functionality. Without the controller in the url, there is no way for MVC to automatically know what controller I'm pointing to.

    So the solution I found is to make specific routes for the Actions.

    So if I have an action called Resources, and its in the controller called NotHome, I can make my routes look like this:

    routes.MapRoute(
        "Resources",
        "{username}/Resources",
        new { controller = "NotHome", action = "Resources"}
    );
    

    So now every time I type in whatever/Resources, it will hit that route.