Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net MVC - handling bad URL parameters

What's the best way to handle a visitor constructing their own URL and replacing what we expect to be an ID with anything they like?

For example:

ASP.Net MVC - handling bad URL parameters

But the user could just as easily replace the URL with:

https://stackoverflow.com/questions/foo

I've thought of making every Controller Function parameter a String, and using Integer.TryParse() on them - if that passes then I have an ID and can continue, otherwise I can redirect the user to an Unknown / not-found or index View.

Stack Overflow handles it nicely, and I'd like to too - how do you do it, or what would you suggest?

like image 274
Andrew Avatar asked Oct 25 '08 12:10

Andrew


People also ask

How to handle bad URL in MVC?

First: Add a route pattern to the end of your routing table that matches to any URL. Second: Set the default controller and action values for this pattern to the controller/action method that will display the "more helpful" View you want to provide. (And, I guess, a third step: Provide that controller/action/View.)


1 Answers

Here's an example of a route like yours, with a constraint on the number:

routes.MapRoute(
    "Question",
    "questions/{questionID}",
    new { controller = "StackOverflow", action = "Question" },
    new { questionID = @"\d+" } //Regex constraint specifying that it must be a number.
);

Here we set the questionID to have at least one number. This will also block out any urls containing anything but an integer, and also prevents the need for a nullable int.

Note: This does not take into account numbers that larger than the range of Int32 (-2147483647 - +2147483647). I leave this as an exercise to the user to resolve. :)

If the user enters the url "questions/foo", they will not hit the Question action, and fall through it, because it fails the parameter constraint. You can handle it further down in a catchall/default route if you want:

routes.MapRoute(
    "Catchall",
    "{*catchall}", // This is a wildcard routes
    new { controller = "Home", action = "Lost" }
);

This will send the user to the Lost action in the Home controller. More information on the wildcard can be found here.

NB: The Catchall should reside as the LAST route. Placing it further up the chain will mean that this will handle all others below it, given the lazy nature of routes in ASP.NET MVC.

like image 60
Dan Atkinson Avatar answered Oct 11 '22 06:10

Dan Atkinson