user32826
user32826

Reputation:

ASP.Net MVC with complex routes - how to keep it "sane"?

I have a client who wishes to use a URL naming convention along the lines of:

/{subjectarea}/{subject}/{action}

Which is fine - this works brilliantly, with one controller per subject area, and having the action after the id (subject) is no issue at all.

However, it then gets complicated, as the client then wants to further continue the hierarchy:

/{subjectarea}/{subject}/{action}/{tightlyrelatedsubject}/{tightlyrelatedsubjectvariables}/{tightlyrelatedsubjectaction}

I have a controller for the tightly related subject (its just another subject area) which handles all of the admin side, but the client insists on having the public view hung off of the parent subject rather than its own root.

How can I do this while avoiding breaking the entire principals of MVC, and also avoiding re-implementing a ton of ASP.Net MVC provided functionality in my subject area controller just to be able to handle the related subjects from that same controller?

Is it possible to somehow call the related subjects controller from within the parent subject controller, and return the resulting view (as this would keep the separation of functionality for the subjects to their own controllers)? If that is possible, it would solve a heck of a lot of issues with this.

Upvotes: 8

Views: 1910

Answers (2)

user32826
user32826

Reputation:

Here is the solution which solves my given issue - hope it solves someone elses.

As mentioned in my comment to Robert Harvey, all I actually need is another route which doesn't use the first two or three components as the controller, action and id, but instead takes those values from later on - if you hang this off of a static value in the route as well, its much easier to do.

So, here is the url I decided on to simplify the route:

/{subjectarea}/{subject}/related/{tightlyrelatedsubject}/{tightlyrelatedsubjectvariables}/{tightlyrelatedsubjectaction}

The route which satisfies this URL is as follows:

        routes.MapRoute(
            "RelatedSubjects",
            "{parentcontroller}/{parentsubject}/related/{controller}/{id}/{action}",
            new { controller = "shoes", action = "view", id = "all" }
        );

On the subsequent controller action, I can ask for parameter values for parentcontroller and parentsubject so I can filter out the related item to just be specific to the given parent subject - problem solved!

This route needs to be above the ones which just deal with the first two values, otherwise you run the risk of another route map hijacking the request.

I could do this entirely without the /related/ static portion as the route could easily match on number of values alone, and infact I may indeed do so - however, I consider it better for later administration if there is a static item in there to confirm the use of the route.

I hope this helps someone!

Upvotes: 2

Robert Harvey
Robert Harvey

Reputation: 180798

One way you can do it is specify a wildcard route (notice the asterisk):

routes.MapRoute("subjects", "{action}/{*path}",
    new { controller = "Subjects", action = "Index" });

This allows the controller to receive the entire path string after the action.

You can then obtain the hierarchy of subjects in the controller method like so:

string[] subjects = path.Split('/');

Once you have that, you can do anything you want, including dispatching different subjects to different handling methods for processing.

Upvotes: 1

Related Questions