tags:

views:

1815

answers:

8

I have a new laptop at work and code that worked earlier in the week does not work today.

The code that worked before is, simplified:

while (dr.Read())
{
    int i = int.Parse(dr.GetString(1))
}

Now it fails when the database value is 0. Sometimes, but not reliably, this will work instead:

while (dr.Read())
{
    int i = Convert.ToInt32(dr["FieldName"]))
}

Am I missing something stupid?

Oddly enough, ReSharper is also having tons of weird errors with the same error message that I am getting with the above code: "input string was not in the correct format." (Starts before I even load a project.)

Any ideas? Anyone having any SP issues? I did try to make sure all my SPs were up-to-date when I got the machine.

EDIT: I understand how to use Try.Parse and error-handling. The code here is simplified. I am reading test cases from a database table. This column has only 0, 1, and 2 values. I have confirmed that. I broke this down putting the database field into a string variable s and then trying int.Parse(s). The code worked earlier this week and the database has not changed. The only thing that has changed is my environment.

To completely simplify the problem, this line of code throws an exception ("input string was not in the correct format"):

 int.Parse("0");

EDIT: Thanks to everyone for helping me resolve this issue! The solution was forcing a reset of my language settings.

+2  A: 

Are you sure it's "0" and not "null"? What exception do you get?

EDIT:

Just out of curiosity, if it is really faulting on int.Parse("0"), can you try int.Parse("0", CultureInfo.InvariantCulture);?

Otherwise, post your query. Any joins?

chris
I'm positive it is zero and not null. The column only has 0, 1, and 2. Only 0 fails.System.FormatException: Input string was not in a correct format.
Leslie
Is 0 is stored as numeric value? What data type is the column in the table.
J.W.
The database field is int.
Leslie
Does the field has "NON NULL" attribute turned on, what is the default value of the field. If it allows the null, I would expect it's a null value.
J.W.
If the database field is int, then have you thought about substituting the retrieval as string and manual parsing for a call to GetInt32? http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getint32.aspx
Quintin Robinson
Does your query contain a join (generating null values)?
chris
Honestly, it isn't my query or error-handling. Yes, it really faults on int.Parse("0").
Leslie
I wish I had tried the InvariantCulture before I fixed it, just to see what happened.
Leslie
+2  A: 

Edit:
@Mike's response made me think that is extremely odd behavior and a simple google search yielded this result: int.Parse weird behavior

An empty string would also cause this issue.

You could check for dbnull before parsing, also it is good to validate parsed data.

You could use a default value and TryParse..

int i = -1;
if(!int.TryParse(dr["MyColumn"] as string, out i))
   //Uh Oh!

Edit:
I posted this as a comment in @Chris' answer, but if the sql datatype is int then why not just use the GetInt32 method on the DataReater instead of retrieving it as a string and manual parsing it out?

Quintin Robinson
I think had problems with that too, but I don't remember what they were now. I've been wrestling with this all day.
Leslie
Thanks for adding that edit! That's EXACTLY what I was looking for. I have no idea how long it must have taken them to find that one :) I appreciate you finding the right link to look at.
Mike
@Mike, No problem when you said that you had the same problem I had to look into it, I'm really glad it was helpful.
Quintin Robinson
OK, I remember now, I changed the field in the database back and forth from int to varchar while I was troubleshooting. The original database field was varchar when it was working the first time. Now that it is int and my environment is functional, I will use GetInt32.
Leslie
Good news, glad everything is finally leveling out.
Quintin Robinson
+3  A: 

I think it's generally not considered a good idea to call Convert.ToInt32 for the value reading out of database, what about the value is null, what about the value cannot be parsed. Do you have any exception handling code here.

  1. Make sure the value is not null.
  2. Check the value can be parsed before call Int32.Parse. Consider Int32.TryParse.
  3. consider use a nullable type like int? in this case.

HTH.

J.W.
A: 

are you checking for null ?

if(!dr.IsNull("FieldName")){
   int i = Convert.ToInt32(dr["FieldName"]))
}
Mcbeev
+1  A: 

you should check dr["FieldName"] != DBNull.Value and you should use TryParse if it passes the DBNull test...

if ( dr["FieldName"] != DBNull.Value )
{
    int val = 0;
    if ( int.TryParse( dr["FieldName"], out val ) )
    {
        i = val;
    }
    else
    {
        i = 0; // or some default value
    }
}
Muad'Dib
+1  A: 

I have seen this issue crop up with .NET Double class, parsing from string "0" as well.

Here's the really wacky part: you can get past the issue by using a different user account to run the program, and sometimes if you destroy and re-create the current user account on the machine, it will run fine.

I have yet to track this down, but you might get past it this way at least.

Mike
Thank you for something besides error-handling to try!!! I know how to check for nulls. :)
Leslie
+18  A: 

A possible explanation:

Basically, the problem was the sPositiveSign value under HKEY_CURRENT_USER\Control Panel\International being set to 0, which means the positive sign is '0'. Thus, while parsing the "positive sign 0" is being cut off and then the rest of the string ("") is parsed as a number, which doesn't work of course. This also explains why int.Parse("00") wasn't a problem. Although you can't set the positive sign to '0' through the Control Panel, it's still possible to do it through the registry, causing problems. No idea how the computer of the user in the post ended up with this wrong setting...

Better yet, what is the output of this on your machine:

Console.WriteLine(System.Globalization.NumberFormatInfo.GetInstance(null).PositiveSign);

I'm willing to bet yours prints out a 0... when mine prints out a + sign.

I suggest checking your Control Panel > Regional and Language Options settings... if they appear normal, try changing them to something else than back to whatever language you're using (I'm assuming English).

John Rasch
Wouldn't that give an Octal 0 instead?
chris
Thanks, I'll check into this in a bit after I let the dogs out, LOL.
Leslie
@chris - no (try it out with "010", you still get 10), but even so an octal 0 is still 0 :)
John Rasch
Thank you so much! After confirming with your test, I changed to French and back to English and all is well!
Leslie
Impressive psychic debugging! +1
erikkallen
I'd downvote, but I'm afraid he'd use his psychic powers to hunt me down and kill me. Just kidding, +1. lol
Samuel
Impressive and awesome, but not psychic, just thought-ful!
Leslie
+1  A: 

This is way out of left field, but check your localization settings. I had a number of "input string was not in a correct format" when I moved a web site to a Canadian server. The problem was in a DateTime.Parse method, and was fixed by setting the culture to "en-US".

Yes, your situation is different — but hey, you never know.

harpo
Yes, it was localization. It said it was on US-EN, but changing it to French and back to English solved the problem. Thanks!
Leslie