views:

62

answers:

4

There seems to be a lot of confusion around converting strings (usually) to their appropriate datatype, whilst validating it on the fly as well. Wherever I look - blogs, articles, code samples, forums.. a few people seem to have a preferred way of dealing with these scenarios.

The case is usually a string/object that comes from an unknown source, such as QueryString, Session/Viewstate, WebService, and so on...

I've seen many different examples:

Say we're trying to get the id= Query String and use it in our code as an integer. But someone tampered with our URL and changed it to

http://www.example.com/page.aspx?id=sometextvalue

One way

int id = Convert.ToInt32(Request["id"]);
// "Input string was not in a correct format"

Another way

int id = (int)Request["id"];
// "Input string was not in a correct format"

Yet another way

int id = int.Parse(Request["id"]);
// "Input string was not in a correct format"

I have ever seen this (And it kind of makes sense to throw an exception and notify the user)

int id = 0;
try {
    id = Convert.ToInt32(Request["id"]);
}
catch(Exception ex) {
    lblError.Text = ex.Message;
}
if(id > 0) { ... }

Lastly, and the one I personally use

int id = 0;
int.TryParse(Request["id"], out id);

// make sure it's not 0
if(id > 0) { // live a happy life }

This goes for all the other types, bool, double, decimal and so on..

Please help me understand what the correct way is, as I find myself using this on a day-to-day basis.

+5  A: 

Well, for starters you should be using:

int id;
if(!int.TryParse(Request["id"], out id)
    //notify the user, or handle it someother way

instead of checking for id > 0. int.TryParse(string, out int) returns true if the parse succeeded, false otherwise.

MSDN Documentation for int.TryParse(string, out int)

Wesley Wiser
Thanks @wawa, I didn't know TryParse returns a boolean.
Marko
A: 

I don't think any of these would actually be considered "Correct". I like to use Convert.ToInt32() because I can get some specific exceptions that I can check for to see if its valid input.

JoelHess
`Convert.ToInt32` generates the same exceptions as `int.Parse`.
Gabe
And you should instead rely on boolean-returning TryParse methods since exceptions should not drive your program flow.
James Dunne
A: 

Correct: Answer is, it depends. You should learn the difference between typecasting, parsing. Use them appropriately.

stackunderflow
Well I think I've explained the scenario...
Marko
But there is no blanket answer to all of your scenarios.
stackunderflow
+3  A: 

The System.ComponentModel namespace contains a well-designed framework for doing exactly these types of conversions.

Inspect the namespace for yourself, but this will get you going for starters:

targetType newValue = (targetType) System.ComponentModel.TypeDescriptor.GetDescriptor(typeof(sourceType))
    .ConvertTo((object)value, typeof(targetType))

You get the basic type conversions for free in one centralized type-agnostic place rather than having to search through the unfortunately inconsistent X.Parse or X.TryParse methods found on the primitive types.

On top of the basics, you get an extensible framework where you can write your own type converters among other things. The ASP.NET MVC framework makes use of this namespace heavily to handle its type conversions for things like query-string value conversions to method parameters.

James Dunne
This looks really interesting @James, I'll try find some more information on it.
Marko
+1, I am sure it is just a typo, newValue should be of targetType and likewise the cast of the result of ConvertTo()
Chris Taylor
@Chris Talyor: correct. The post has been updated. Thanks.
James Dunne