0

Is there a way to do regressive route handling in ASP.NET MVC v3?

Here's my business-case example: if given a URL "www.mysite.com/faq/Index", I'd like it to check to see if a route exists for controller "FAQ", action "Index"

routes.MapRoute("Default","{controller}/{action}/{id}",
            new { id = UrlParameter.Optional });

If that cannot be resolved, normally it would throw a 404 error. Instead, I'd like it to use this route:

routes.MapRoute("Content", "Content/{*contentPath}", 
            new { controller = "Content", action = "RenderPageByURL" });

If that fails, then it should return a 404.

I was thinking I could create a custom error handler, but this seems kludgy. Any ideas on where to start? Or is this a truly Bad Idea(TM) and I should go back to the business and tell them to use the correct path to start out with? Thanks.

Edit. To clarify, I'm not trying to see if it matches a route through simple URL matching. I'd like the routing mechanism to be intelligent enough to know if a route will be successful and find a proper controller.

2 Answers 2

1

Define the Content route below the Default in Globasl.asax.cs.

routes.MapRoute("Default","{controller}/{action}/{id}",
            new { id = UrlParameter.Optional });

routes.MapRoute("Content", "Content/{*contentPath}", 
            new { controller = "Content", action = "RenderPageByURL" });
Sign up to request clarification or add additional context in comments.

3 Comments

So does that mean that if www.mysite.com/faq/Index and there isn't a FaqController, it will go to the ContentController? I thought it would throw a 404 error.
How the routing works is, The incoming request is matched with the first route if that fails then it will be matched with the second one till the end. In the example you given both the route don't matches the request resulting a 404.
I tried that on a test project. The Default route automatically grabbed the /content/faq route and threw a 404 error. It never got to the second route.
1

I'm answering my question based on a co-worker's suggestion and the below link (thanks, Josh!):

http://stephenwalther.com/archive/2008/08/07/asp-net-mvc-tip-30-create-custom-route-constraints.aspx

Basically, I add a custom constraint on the route.

 routes.MapRoute("Content", "{*contentPath}", 
        new { controller = "Content", action = "RenderPageByURL" }, 
        new { matchController = new ContentRouteConstraint() });

 routes.MapRoute("Default","{controller}/{action}/{id}",
        new { id = UrlParameter.Optional });

ContentRouteConstraint() implements IRouteConstraint, and returns true on the Match method only if it doesn't match one of our existing route controllers. If the Match method fails on ContentRouteConstraint(), then it drops down to the next route.

The nice thing about this is I can ignore this route when trying to generate URLs (which we want to do in this instance).

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.