Question

Could anyone notice what could be wrong with the following function:

public string Login(string username, string password)
    {
        string result = "";
        string select = "SELECT user_id FROM [user] WHERE username = @username AND password = @password";
        SqlConnection conn = new SqlConnection(connectionString);
        SqlCommand cmd = new SqlCommand(select, conn);
        cmd.Parameters.AddWithValue("username", username);
        cmd.Parameters.AddWithValue("password", password);
        int userID = 0;
        try
        {
            conn.Open();
            userID = (int)cmd.ExecuteScalar();
            if(userID > 0)
            {
                result = addSession(userID);
            }
        }
        catch(Exception ex)
        {
            string sDummy = ex.ToString();
        }
        return result;
    }

Don't know why the line `userID = (int)cmd.ExecuteScalar(); throws an exception.

Thanks

Was it helpful?

Solution

Most likely there is no row in the table with that user/password. The docs for ExecuteScalar say that it returns null if the result set is empty, and you can't cast null to int.

OTHER TIPS

Is it possible that the scalar is null if the supplied credentials are not found in the database?

You should consider modifying this segment of code:

try
{
    conn.Open();
    userID = (int)cmd.ExecuteScalar();
    if(userID > 0)
    {
        result = addSession(userID);
    }
 }
 catch(Exception ex)
 {
    string sDummy = ex.ToString();

 }
 finally // add this to ensure the connection is closed!
 {
     if (conn != null)
       conn.Close();
 }

Not sure, but you might need the "@" for the parameter names:

...AddWithValue("@username", username);

I was having this same problem working with SqlCE. The solution I found, (AFTER I started inputting my password CORRECTLY... >.> ), was to collect the ExecuteScalar result as an object first, and convert second. Litterally, using

Object o = cmd.ExecuteScalar(); 
int id = Convert.ToInt32(o); 

instead of

int id = (int) cmd.ExecuteScalar(); 

was the difference between a working and crashing. I have no idea why that is though...

I don't see any hashbytes function but here it goes:

Convert password input to binary array if you are using hashbytes function on the backend SQL server. Hashbytes returns varbinary. So, if you pass the null terminator, the hash won't be the same. like in SQL hashbytes('SHA2_512,'stuff') is like hashing 's','t', till 'f'. There are no '\0' at the end. But if you parameterize as string in the sqlcommand object it will add '\0' at the end and the SQL will compute that zero. So if you convert using Encoding class to binary array, the parameter will be just the string without the null terminator. I got a similar problem and I resolved in that way to use addwithvalue and its value as binary.

But, you know that executescalar returns an object. If the query returns zero rows, the object will be NULL and you can't cast or convert a NULL object to anything. So in the if statement say "if returningobject == null then you are not authed. else...."

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top