views:

308

answers:

4

Hi!

In my routing I would like to have something like not found route handler.

For example I have created one mapping like

routes.MapRoute(
                     "default",
                     "{controller}/{action}/{id}",
                     new { controller = "Home", action = "Index", id="" }
             );

routes.MapRoute(
                     "Catchall",
                     "{*catchall}",
                     new { controller = "Home", action = "Lost" }
             );

but when user inserts address something like /one/two/three/four/bla/bla it will be cached with the Catchall mapping.

But when user inserts something that should match with default mapping, (like /one/two/ ,but this controller or action is not implemented) I would want that Catchall mapping would accept this request, because all other mappings failed. But instead of this I get an error.

Should I override some mapping handlers to catch the exception if controller or action getting an exception?

A: 

The issue here is that it's not the Route's responsibility to make sure that "one/two" maps to a file. That responsibility falls to the ViewEngine. Since "one/two" is a valid route, it will be chosen.

If you want to handle the error of an invalid route, what I would recommend you do is simply use the built in ErrorHandling "page" to display whatever message you would have done in the Catchall.

Timothy Khouri
A: 

Thank you for the answer!

Actually I want to create a CMS application.

So basically if route matches 100% I would like to hit the correct controller otherwise I would like to match another controller.

For instance /Home/Index will match HomeController function Index,

but when the address is something like /Home/My-first-birthday-article There is no function like this. So this trhows an exception but I would like to catch this situation in HomeController Lost(string id) function. To find out does this kind of article with keyword id="Home/My-first-birthday-article" exist or not.

Lauri Lüüs
A: 

I don't think this is the best solution, but you could always be more specific on your routes:

routes.MapRoute(
    "home and action",
    "home/index/{id}",
    new { controller = "Home", action = "Index", id="" }
);

... repeat for the rest of your actions ...

routes.MapRoute(
    "article catch all",
    "home/{article}",
    new { controller = "Home", action = "ArticleSearcher", article="" }
);

This would attempt to match a direct action, and if no action is found, pass what would normally be the {action} part of the default route to the 'ArticleSearcher' action as an article string parameter.

The downside is having to explicitly create each controller/action route.

eyston
A: 

Thanks, but I'm getting thinking that this is a bug in mappings section.

The idea would be if I have several matching mappings, but when controller or method is not found. the system will go on and try the next matching mapping in declarations.

So if the mappings are like

foo/{id}
bar/{id} (id is int)
tokens/{id}
{controller}/{action}/{id} (id is int)
{*catchall}

and request is /bar/test

then routing will match

bar/{id}
{controller}/{action}/{id}
{*catchall}

but id is not integer type but string, then the correct match should be a {*catchall} mapping. Right now it throws an exception

Lauri Lüüs
It is matching the one before the catchall:/bar/test will result in controller = bar, action = test
eyston