I have an architecture where I have numerous objects I can configure. Examples of URLs I want are as follows:
/configuration/building/add
/configuration/building/edit/1
/configuration/group/add
/configuration/group/edit/1
I have a Configuration controller but how do I intercept or deal with building/add and building/edit/1 etc… If it were AddBuilding I could simply add an AddBuilding() function, and similarily how do I get it to work for configuration/building/edit/
Here’s what you can do for the first one – open up the Global.asax.cs file of your site and put this in
RegisterRoutesbefore the standard MVC catch-all route (the one that uses the route"{controller}/{action}/{id}"):The others will be the same, but different names (first parameter) and action, whislt the edit routes but would include an
{id}route placeholder and route parameter (but not optional – unlike the MVC default route):By leaving the
idoff the route defaults we make it required. I’m assuming this, because I’m guessing the Url/Building/Editdoesn’t logically map to anything.As a side node – including verbs in your urls isn’t really in keeping with REST methodology, however you’re not the first to do it by a long way (I include myself in that too). That said – trying to keep to it usually makes your life a lot easier, as you’ll find your controllers will be cleaner, as will your route table, and your site’s URL space will be a lot smaller and more obviously hierarchical. This last point is – handy for zooming around the site at dev time, but more importantly it’s crucial for SEO.
So (I’ve commented this code heavily, hopefully enough to provide some nuggets of knowledge!):
I’ve left off the group stuff to keep it short, and hopefully you’ll be able to see how to do it from there.
With this in place, we only need at most two routes in Global.asax.cs – although I think the order will be important:
Now we are using the HTTP verbs to signify what we intend to do with a particular request, and our URLs have become more ‘logical’.
Another refactor
If you want to be ‘clever’ you can lump both buildings and groups under two routes
Now you do both buildings and groups controllers as I showed above, but replace
Buildings(remembering theActionNameattribute on the second method) withListandBuildingwithSingle.One final thing to consider is that because of the default MVC route:
Both of your two controllers can still be routed via
/Buildings/Single/1or/Groupsfor example. This is a minor issue (dupe content isn’t great SEO) but it can be something that people can use to sniff your site.If you absolutely want to prevent this other url format; you can take out the default route, meaning you’d have to explicitly route other stuff that might already work (not a great issue).
Or you can use a little trick that will make it far harder: use explicit
[ActionName]attributes with characters in the route name that won’t be allowed through IIS – e.g.":Single"or":List", and then adjust our two routes from a couple of code blocks back accordingly.