0

I have a login form. Where my query runs through my database and cross checks if the entered parameters match the ones in the database then redirect you to a page. I put in a condition in my code to catch exceptions when the connection is open or its closed. I have tried looking up solutions like this one and others.

I have done the following.

  • Including usings

However its still showing this error at run time

ExecuteReader requires an open and available Connection. The connection's current state is closed.

This is my code:

public void LWAPLogin(string username, string password)
    {
        string wrongCredentials = "Username does not exist. Or password is incorrect";
        string query = "Select Username, Password from LWAP where Username=@user AND Password=@password;";
        using (SqlCommand command = new SqlCommand(query, Connect.con))
        {
            command.Parameters.Add("@user", SqlDbType.VarChar, 50).Value = username;
            command.Parameters.Add("@password", SqlDbType.VarChar, 50).Value = password;

            try
            {
                if (connection.con.State == ConnectionState.Open)
                {
                    using (SqlDataReader dr = command.ExecuteReader())
                    {
                        if (dr.Read())
                            Response.Redirect("LWAPHome.aspx");
                        else
                            ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + wrongCredentials + "');", true);

                        dr.Close();
                    }
                    connection.con.Close();
                }


                else if (connection.con.State == ConnectionState.Closed)
                {
                    connection.con.Open();


                    using (SqlDataReader dr = command.ExecuteReader())
                    {
                        if (dr.Read())
                            Response.Redirect("LWAPHome.aspx");
                        else
                            ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + wrongCredentials + "');", true);
                        dr.Close();
                    }
                    connection.con.Close();

                }
            }
            finally
            {
                //connection.con.Open();
            }
        }

    }

After getting advise from fellow programmers. I changed my code and the problem is fixed. However now l have a new problem. It is suppose to redirect to new page when all is well but it is not. The just changes the pages url to the desired page but stays on the login page.

Below is my edited code :

public void LWAPLogin(string username, string password)
    {
        using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["tlcString"].ConnectionString))
        {
            string wrongCredentials = "Username does not exist. Or password is incorrect";
            string query = "Select Username, Password from LWAP where Username=@user AND Password=@password;";
            using (SqlCommand command = new SqlCommand(query, con))
            {

                command.Parameters.Add("@user", SqlDbType.VarChar, 50).Value = username;
                command.Parameters.Add("@password", SqlDbType.VarChar, 50).Value = password;

                con.Open();

                using (SqlDataReader dr = command.ExecuteReader())
                {
                    if (dr.Read())
                        Response.Redirect("LWAPHome.aspx");
                    else
                        ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + wrongCredentials + "');", true);

                    dr.Close();
                }
                //connection.con.Close();
            }
            con.Close();

        }
    }

Please see image for the error it is now showing. I tried using different browsers but they all do the same thing.

Kelvin Nkomo
  • 27
  • 1
  • 5
  • Why you reuse the `SqlConnection` at all? That causes such issues. Instead use the `using`-statement to create and intiliaze it in every method. Probably related: [ExecuteReader requires an open and available Connection. The connection's current state is Connecting](https://stackoverflow.com/questions/9705637/executereader-requires-an-open-and-available-connection-the-connections-curren) – Tim Schmelter Oct 20 '17 at 10:59
  • You are probably running into a timming issue your connection could be closing ... so its not closed .. – BugFinder Oct 20 '17 at 10:59
  • So l should use a using and declare the connection within the using? And should I still condition my query or it'll become unnecessary? – Kelvin Nkomo Oct 20 '17 at 11:02
  • It's web application it seems and you store connection in some static field probably. So when one request comes in, checks if connection is open and try to execute command - another request might close connection in between. As said above - never do this, create new connection every time (it will not really create new connection to database because connections are stored in a pool). – Evk Oct 20 '17 at 11:02
  • @Evk so how do I go about it? – Kelvin Nkomo Oct 20 '17 at 11:03
  • 1
    Its also strange that you have two connnections: 1) `Connect.con` 2) `connection.con`. However, both should **not** be static! Otherwise my above link is not related but a duplicate. – Tim Schmelter Oct 20 '17 at 11:04
  • Well in web application you might share one connection for single request, but if you are not sure how to do that - just create new connection every time you need it and dispose (close) it when you are done. All connections are (by default) stored in a pool, so when you do `new SqlConnection` it does not mean it necessary will create new database connection - there can be one available in the pool and it will be used without perfomance cost of creating new connection to database (link in above comment describes this by the way). – Evk Oct 20 '17 at 11:06
  • @TimSchmelter I just looked at your link and l feel like its almost the same but my question is how to condition the method to catch it whenever the connection is closed. – Kelvin Nkomo Oct 20 '17 at 11:08
  • Just use a new connection every time and open it. Then you do not need to check if it is open. – oerkelens Oct 20 '17 at 11:09
  • @Evk l saw the link and it helped with the connection however l still want to condition my method and catch it when the connection is closed. – Kelvin Nkomo Oct 20 '17 at 11:10
  • @KelvinNkomo: the solution is the same as what i've posted in the other answer, throw your DB-Connection-Class to the garbage can and create,open,use,close,dispose ado.net objects where you need them. Don't reuse the connection instance and don't make it `static`(especially in ASP.NET which uses multiple threads). All other "fixes" are just race conditions waiting to fail. – Tim Schmelter Oct 20 '17 at 11:10
  • @oerkelens l do use a new connection every time. I created a class to create a new connection. Hence the connection.con.Open(); – Kelvin Nkomo Oct 20 '17 at 11:11
  • Then maybe you should have a look at the difference between `Connect.con` and `connection.con` because your command uses the first and you're checking (and opening) the second! – oerkelens Oct 20 '17 at 11:12
  • @TimSchmelter so l should create a new connection for each of the conditiion? – Kelvin Nkomo Oct 20 '17 at 11:12
  • One connection per method, created with the using statement. – Tim Schmelter Oct 20 '17 at 11:14
  • You are using the Connect.con in statement using (SqlCommand command = new SqlCommand(query, Connect.con)), but in the body of that using code, you are using another instance of connection connection.con.State, so the problem is you are open one connection and use another instead of the connection which you opened before. – Kay Oct 20 '17 at 11:14
  • @TimSchmelter I have resolved the Connect.con problem and used the same connection. I will now try and use the using for each method and ll get back to you. Give me like 30 mins – Kelvin Nkomo Oct 20 '17 at 11:16
  • @TimSchmelter please recheck my code – Kelvin Nkomo Oct 20 '17 at 11:56
  • @KelvinNkomo: now it seems to work and your next problem is something different. Don't ask follow up questions in the same stackoverflow questions. Instead ask a new. – Tim Schmelter Oct 20 '17 at 11:59

1 Answers1

1

You are creating a new SqlCommand(query, Connect.con)) specifying Connect.con as the connection to use, whereas you're checking the state of connection.con, a different SqlConnection instance. If you really do want to check anything, make sure you're checking the right thing.

rrozema
  • 325
  • 1
  • 7
  • No, the problem didn't persist. The question originally raised was answered. You have other problems as well in your code. Stack overflow isn't about getting your code fully debugged, it's about answering a question in such a way others may benefit from the question and it's answers. By altering the question you obscure the original question and defeat this purpose. As Tim Schmelter indicated, please mark this question as answered and create a new one for you next problem. – rrozema Oct 20 '17 at 13:15