1

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:

  • Remove Index from the URL
  • Supply a parameter to the Index action
  • Allow all other actions to have their name in the URL and provide an optional parameter to them

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?

2
  • Are agentgroupid in your route "Suppliers_index" integers? Commented Oct 20, 2014 at 16:32
  • @DanielJ.G. Yes, the agentgroupid is an integer in both routes. Commented Oct 20, 2014 at 23:07

1 Answer 1

1
+50

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" }
);
Sign up to request clarification or add additional context in comments.

Comments

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.