简体   繁体   中英

Tuple keeps crashing on sql stored procedure because it has too many arguments specified

In c# asp.net I have a function tuple where I give the Username and Password with. The function checks if it's in a sqldatabase using a stored procedure. But if I call the function tuple twice, first to get the 1st value, and next the 2nd value I get an error that the Procedure has too many arguments specified. I am just new in the world of function tuple, thanks alot!

protected void btnLogin_Click(object sender, EventArgs e)
    {
        LoginGebruikersNaam = txtGebruikersNaam.Text;
        LoginWachtwoord = txtWachtwoord.Text;
        lblMessage.Text = (B.Inloggen(LoginGebruikersNaam, LoginWachtwoord)).Item1;
        Ingelogd = (B.Inloggen(LoginGebruikersNaam, LoginWachtwoord)).Item2;

    }

public Tuple<string, bool> Inloggen(string LoginGebruikersNaam, string LoginWachtwoord)
    {
        bool Ingelogd = false;
        string Message = String.Empty;
        string Voornaam = String.Empty, Naam = String.Empty;
        _LoginGebruikersNaam = LoginGebruikersNaam;
        _LoginWachtwoord = LoginWachtwoord;

        cmdInloggen.Connection = cnn;
        cmdInloggen.CommandType = System.Data.CommandType.StoredProcedure;
        cmdInloggen.CommandText = "SPInloggen";
        cmdInloggen.Parameters.AddWithValue("@LoginGebruikersNaam", _LoginGebruikersNaam);
        cmdInloggen.Parameters.AddWithValue("@LoginWachtwoord", _LoginWachtwoord);

        cnn.Open();
        drInloggen = cmdInloggen.ExecuteReader();
        while (drInloggen.Read())
        {
            Voornaam = drInloggen[0].ToString();
            Naam = drInloggen[1].ToString();
        }
        cnn.Close();

        if (Voornaam == String.Empty || Naam == String.Empty)
        {
            Message = "De logingegevens kloppen niet! Controleer de gegevens en probeer het opnieuw!";
        }
        else
        {
            Message = "Welkom " + Voornaam + " " + Naam + "! U bent succesvol ingelogd.";
            Ingelogd = true;
        }


        return new Tuple<string, bool>(Message, Ingelogd);
    }

In your original code, you are calling B.Inloggen twice.

protected void btnLogin_Click(object sender, EventArgs e)
{
    LoginGebruikersNaam = txtGebruikersNaam.Text;
    LoginWachtwoord = txtWachtwoord.Text;
    var response = B.Inloggen(LoginGebruikersNaam, LoginWachtwoord);
    lblMessage.Text = response.Item1;
    Ingelogd = response.Item2;
}

public Tuple<string, bool> Inloggen(string LoginGebruikersNaam, string LoginWachtwoord)
{
    bool Ingelogd = false;
    string Message = String.Empty, Voornaam = String.Empty, Naam = String.Empty;

    using(SqlCommand cmdInLoggen = new SqlCommand("SPInloggen", cnn))
    {
        cmdInloggen.CommandType = System.Data.CommandType.StoredProcedure;
        cmdInloggen.Parameters.AddWithValue("@LoginGebruikersNaam", _LoginGebruikersNaam);
        cmdInloggen.Parameters.AddWithValue("@LoginWachtwoord", _LoginWachtwoord);

        try
        {
            cnn.Open();
            using (var drInloggen = cmdInloggen.ExecuteReader())
            {
                if (drInloggen.Read())
                {
                    Voornaam = drInloggen[0].ToString();
                    Naam = drInloggen[1].ToString();
                }

                if (Voornaam == String.Empty || Naam == String.Empty)
                {
                    Message = "De logingegevens kloppen niet! Controleer de gegevens en probeer het opnieuw!";
                }
                else
                {
                    Message = "Welkom " + Voornaam + " " + Naam + "! U bent succesvol ingelogd.";
                    Ingelogd = true;
                }
            }
        }
        finally
        {
            // Enforce the connection is closed even when exception is raised
            if (cnn.State != System.Data.ConnectionState.Closed) cnn.Close();
        }
    }

    return new Tuple<string, bool>(Message, Ingelogd);
}

Also, the SQL stored procedure is expected to return one record, so, I have removed the while loop.

a: you're calling the stored procedure twice...

once here:

lblMessage.Text = (B.Inloggen(LoginGebruikersNaam, LoginWachtwoord)).Item1;

and then again here:

Ingelogd = (B.Inloggen(LoginGebruikersNaam, LoginWachtwoord)).Item2;

b: you appear to be reusing a command object (not a good idea, frankly), and not clearing the parameters; so by calling it twice, the first time it'll have 2 parameters, and the second time it'll have 4.

So... don't do that!

Frankly, your ADO.NET code needs ... quite a bit of work; right now there's a lot of problems with it. I don't mean that negatively - ADO.NET is hard to get right, but ... because it is hard to get right, there are tools like "dapper" that will really help you, making it much easier to default to success, rather than failure. I strongly recommend using them.

Problems right now:

  • reusing a command (casually)
  • possible thread-safety on the command and connection
  • an unclosed reader
  • multiple IDisposable problems
  • failure to consider null parameters (as opposed to DBNull )

etc

I hope you have got answer why you are getting that error too many argument specified and do not need to call twice that function to get those two values. You can call once. Anyway I have also just modified your code with using block. To connect SQL and retrieve data you are using ADO .net but that is un managed code that does not manage by CLR. For that I have used Using block, it implements IDisposable so we do not need explicitly dispose of the objects in code. Also we do not need to close the connection because once its out of scope of using block it automatic close the connection.

protected void btnLogin_Click(object sender, EventArgs e)
    {
        LoginGebruikersNaam = txtGebruikersNaam.Text;
        LoginWachtwoord = txtWachtwoord.Text;
        var tupleDetails = B.Inloggen(LoginGebruikersNaam, LoginWachtwoord);
        lblMessage.Text = tupleDetails.Item1;
        Ingelogd = tupleDetails.Item2;

    }

public Tuple Inloggen(string LoginGebruikersNaam, string LoginWachtwoord) {

        bool Ingelogd = false;
        string Message = String.Empty;
        string Voornaam = String.Empty, Naam = String.Empty;
        var _LoginGebruikersNaam = LoginGebruikersNaam;
        var _LoginWachtwoord = LoginWachtwoord;
        try
        {
            using (SqlConnection sqlConnection = new SqlConnection(cnn))
            {
                using (SqlCommand cmdInloggen = new SqlCommand("SPInloggen", sqlConnection))
                {
                    cmdInloggen.CommandType = CommandType.StoredProcedure;
                    cmdInloggen.Parameters.AddWithValue("@LoginGebruikersNaam", _LoginGebruikersNaam);
                    cmdInloggen.Parameters.AddWithValue("@LoginWachtwoord", _LoginWachtwoord);

                    sqlConnection.Open();
                    using (SqlDataReader drInloggen = cmdInloggen.ExecuteReader())
                    {
                        while (drInloggen.Read())
                        {
                            Voornaam = drInloggen[0].ToString();
                            Naam = drInloggen[1].ToString();
                        }
                    }
                }
            }
        }

        catch (Exception ex)
        {
            Message = ex.ToString();               
        }

        if (Voornaam == String.Empty || Naam == String.Empty)
        {
            Message = "De logingegevens kloppen niet! Controleer de gegevens en probeer het opnieuw!";
        }
        else
        {
            Message = "Welkom " + Voornaam + " " + Naam + "! U bent succesvol ingelogd.";
            Ingelogd = true;
        }


        return new Tuple<string, bool>(Message, Ingelogd);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM