Alex
Alex

Reputation: 1557

Not showing "Index" in URL and supplying a parameter with MVC5 routing

I'm trying to set up some routing in one of my MVC area's.

I have a controller named AgentGroups. I am trying to achieve the following:

So for example I'd like the following to work

/s/agentgroups   < (Index action)
/s/agentgroups/1 < (Index action)
/s/agentgroups/someotheraction
/s/agentgroups/someotheraction/1

I currently have this in my RegisterArea method:

        // s/agentgroups/action
        context.MapRoute(
            "Suppliers_actions",
            "s/{controller}/{action}/{agentgroupid}",
            new { controller = "AgentGroups", agentgroupid = UrlParameter.Optional },
            new { action = "^(?!Index$).*$" }
        );

        // s/agentgroups/
        context.MapRoute(
            "Suppliers_index",
            "s/agentgroups/{agentgroupid}",
            new { controller = "AgentGroups", action = "Index", agentgroupid = UrlParameter.Optional }
        );

This works for 3 of the 4 URL examples I gave, the one that doesn't work correctly is:

/s/agentgroups/1 < (Index action)

I'm pretty sure it thinks the 1 parameter is an action name and therefore it doesn't work..? It does work however, if, I pass the parameter like a regular query string ie: ?agentgroupid=1, but I'd like to avoid this if possible.

How can I change my routes to achieve the desired behavior?

Upvotes: 1

Views: 1196

Answers (1)

Daniel J.G.
Daniel J.G.

Reputation: 35022

You can reorder the area routes as Suppliers_index is more specific (only intended for the index action) than Suppliers_actions. Then you will need to add a constraint for the agentgroupid parameter in Suppliers_index.

As the parameter is optional and has to match an integer, we can use the regex \d*, but for more complicated patterns you might need to create your own route constraint as in this answer.

So your area routes may look like this: (namespaces will be different or even not needed in your case):

context.MapRoute(
    "Suppliers_index",
    "s/agentgroups/{agentgroupid}",
    defaults: new { controller = "AgentGroups", action = "Index", agentgroupid = UrlParameter.Optional },
    constraints: new { agentgroupid = @"\d*" },
    namespaces: new[] { "WebApplication6.Areas.AgentGroups.Controllers" }
);

context.MapRoute(
    "Suppliers_actions",
    "s/{controller}/{action}/{agentgroupid}",
    defaults: new { controller = "AgentGroups", agentgroupid = UrlParameter.Optional },
    namespaces: new[] { "WebApplication6.Areas.AgentGroups.Controllers" }
);

Upvotes: 1

Related Questions