You need to ensure that you are always passing an int when building a URL.
More typically, the argument would of type int? (i.e. nullable) and can also handle no id being specified. (In which case you default id in you route definition to (int?)null.)
If this is input from a form, then likely I'll render the edit (populated with the submitted data listing the error. In this case I would be doing the parsing in my code and use a string parameter.
If the only valid route (i.e. not user just typing into the address bar) is an application created URL a generic error page might be the right thing (400 bad request).
Summary: either you handle bad format (so pass in a string and do the parsing yourself) or you don't (in which case the application's error handler is the route to go).
Of course, this being a preview, the MVC implementation might make your choice overly hard... The MVC team have indicated this is a good place for feedback (and now the source is available you could suggest how it should change).
I think JontyMC asked not "what should we do in case of error (generate 400 or 404, show error message, etc)", but "how should we catch and handle this error (where to place try-catch block, how to display error, etc)"
@maartenba - Thanks, thats an interesting use of the Action Filter attribute. It can't be used with this issue though, as the exception is thrown before OnActionExecuted fires. Perhaps there should be a generic way of dealing with this exception? Maybe an
OnActionParameterError with a FilterExecutingContext and some container for the parameter errors.
Having posted the question, however, I'm struggling to think of a scenario where this would actually get used. You'd normally do as ricox said and just deal with the error via the application error handler and make sure your application only generated valid
links.
Has no one mentioned Contraints yet? I can't leave you guys alone for 10 minutes can I. ;)
Option 1:
Url = "{controller}/{action}/{id}"
Contraints = new RouteValueDictionary{ new { id = "\d*" } }
that will ensure that only digits are accepted as the id parameter
Then you should have a catchall route
Url = "{*catchall}"
Defaults = new RouteValueDictionary{ new { controller = "Error", action = "NotFound" } }
Then your ErrorController should have a NotFound action which renders a 404 page. so
/edit/NaN would render the 404
Option 2:
This would be pretty ugly if you used a regex for dates. e.g.
"(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" and that doesn't take into account the number of days in each month or leap years etc.
You could change your action signature to void Edit(string id) and you can do the
int.TryParse(id, out value) yourself. This would work similarly for dates. but again you're doing extra work that should be handled by the framework.
Option 3 (not implemented yet)
Unfortunately, the ActionFilterAttirbute suggestion from maartneba won't work because the exception is thrown before the action filters are called.
I've suggested previously, that the parameter resolution should occur after the action filters OnActionExecuting methods have successfully finished. And the That way you can check the RouteData values before your action gets called. You could also change
the RouteData values, so you would be able to do your own custom deserialization.
You'd also be able to write an ActionFilterAttribute which caught the InvalidCastException in the OnActionExecuted method. This is exactly what you want.
So, when they make this change, this is probably your ideal solution. Of course by that time they should have some standard ActionFilterAttributes like an ErrorHandlerFilter so you'll have even less to do. ;)
JontyMC
Member
394 Points
144 Posts
Invalid controller parameter error handling
Apr 02, 2008 11:41 AM|LINK
With the standard route of {controller}/{action}/{id} and an action in the controller such as:
rjcox
Contributor
7064 Points
1444 Posts
Re: Invalid controller parameter error handling
Apr 02, 2008 12:08 PM|LINK
You need to ensure that you are always passing an int when building a URL.
More typically, the argument would of type int? (i.e. nullable) and can also handle no id being specified. (In which case you default id in you route definition to (int?)null.)
JontyMC
Member
394 Points
144 Posts
Re: Invalid controller parameter error handling
Apr 02, 2008 01:09 PM|LINK
I realise that. What I'm asking is if you want to handle the error, is there a normal defined way to do it?
Maybe a better example would be a querystring date value perhaps something like /Orders/List?date=2008-02-30
How would you capture and handle that error?
rjcox
Contributor
7064 Points
1444 Posts
Re: Invalid controller parameter error handling
Apr 02, 2008 01:38 PM|LINK
OK, but unclear from original message.
Depends.
If this is input from a form, then likely I'll render the edit (populated with the submitted data listing the error. In this case I would be doing the parsing in my code and use a string parameter.
If the only valid route (i.e. not user just typing into the address bar) is an application created URL a generic error page might be the right thing (400 bad request).
Summary: either you handle bad format (so pass in a string and do the parsing yourself) or you don't (in which case the application's error handler is the route to go).
Of course, this being a preview, the MVC implementation might make your choice overly hard... The MVC team have indicated this is a good place for feedback (and now the source is available you could suggest how it should change).
vecalion
Member
28 Points
11 Posts
Re: Invalid controller parameter error handling
Apr 02, 2008 01:47 PM|LINK
I think JontyMC asked not "what should we do in case of error (generate 400 or 404, show error message, etc)", but "how should we catch and handle this error (where to place try-catch block, how to display error, etc)"
maartenba
Member
368 Points
76 Posts
Re: Invalid controller parameter error handling
Apr 02, 2008 01:52 PM|LINK
Spotted this today: http://www.squaredroot.com/post/2008/04/MVC-Error-Handler-Filter.aspx
It's an Action Filter which handles exceptions of a specific type to a specific error URL.
Order my book ASP.NET MVC 1.0 Quickly via http://www.packtpub.com/asp-net-model-view-controller-1-0-quickly/book
JontyMC
Member
394 Points
144 Posts
Re: Invalid controller parameter error handling
Apr 02, 2008 04:27 PM|LINK
@vecalion - Yes, this is exactly what I mean.
@maartenba - Thanks, thats an interesting use of the Action Filter attribute. It can't be used with this issue though, as the exception is thrown before OnActionExecuted fires. Perhaps there should be a generic way of dealing with this exception? Maybe an OnActionParameterError with a FilterExecutingContext and some container for the parameter errors.
Having posted the question, however, I'm struggling to think of a scenario where this would actually get used. You'd normally do as ricox said and just deal with the error via the application error handler and make sure your application only generated valid links.
tgmdbm
Contributor
4392 Points
883 Posts
ASPInsiders
MVP
Re: Invalid controller parameter error handling
Apr 02, 2008 07:26 PM|LINK
Has no one mentioned Contraints yet? I can't leave you guys alone for 10 minutes can I. ;)
Option 1:
Url = "{controller}/{action}/{id}"
Contraints = new RouteValueDictionary{ new { id = "\d*" } }
that will ensure that only digits are accepted as the id parameter
Then you should have a catchall route
Url = "{*catchall}"
Defaults = new RouteValueDictionary{ new { controller = "Error", action = "NotFound" } }
Then your ErrorController should have a NotFound action which renders a 404 page. so /edit/NaN would render the 404
Option 2:
This would be pretty ugly if you used a regex for dates. e.g. "(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" and that doesn't take into account the number of days in each month or leap years etc.
You could change your action signature to void Edit(string id) and you can do the int.TryParse(id, out value) yourself. This would work similarly for dates. but again you're doing extra work that should be handled by the framework.
Option 3 (not implemented yet)
Unfortunately, the ActionFilterAttirbute suggestion from maartneba won't work because the exception is thrown before the action filters are called.
I've suggested previously, that the parameter resolution should occur after the action filters OnActionExecuting methods have successfully finished. And the That way you can check the RouteData values before your action gets called. You could also change the RouteData values, so you would be able to do your own custom deserialization.
You'd also be able to write an ActionFilterAttribute which caught the InvalidCastException in the OnActionExecuted method. This is exactly what you want.
here's the origibal thread http://forums.asp.net/t/1234914.aspx
So, when they make this change, this is probably your ideal solution. Of course by that time they should have some standard ActionFilterAttributes like an ErrorHandlerFilter so you'll have even less to do. ;)
JontyMC
Member
394 Points
144 Posts
Re: Invalid controller parameter error handling
Apr 03, 2008 01:14 PM|LINK
Nice. I vote for option 3. This should definitely be handled by the framework.