Search code examples
c#asp.nettextbox

"The name "TextBox" does not exist in the current context" errors during a few tutorials


I want to make an ASP.NET web form that sends the text from a TextBox to a SQL database in Visual Studio. I found 2 tutorials for exactly what I wanted, but both of them have the same errors halfway through the tutorials. Under every TextBox in TextBox.Text, there is an error that says:

"CS0103: The name 'TextBox' does not exist in the current context".

Here are the links to the 2 tutorials:

Here is my current code (in WebForm.aspx.cs, not the completed code):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.Net.Mail;
using System.Drawing;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using System.Text;
using System.IO;
public partial class _Default : System.Web.UI.Page 
{
    SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
    protected void Page_Load(object sender, EventArgs e) 
    {
        con.Open();
    }
    protected void Register_Click(object sender, EventArgs e)
    {
        SqlCommand cmd = new SqlCommand("insert into storedatabase values('"+TextBox2.Text+"')")

    }
}

And here is TextBox2 (in WebForm.aspx):

<asp:TextBox ID="TextBox2" runat="server" MaxLength="20"></asp:TextBox>

I am using Visual Studio 2022, and .NET 4.7.2.

I have searched almost everywhere on Google, here are the major things I tried:

  • using Potential Fixes to turn TextBox2 into a variable
  • checked if TextBox2 had "runat="server""
  • checked the spelling

Every other search result either did not have the same problem as me, had the exact same problem as me but the answer was blocked by a paywall or had no answer, had somewhat the same problem as me but the answers did not specify where and how to do it, or was a post where someone had an argument with one of its forum moderators. I have searched so much that every time I search up anything related to my problem, all the links in page 1-2 on Google have turned purple.

Any help is appreciated. Thank you!

Edit: I have created a new project (Aform), but the problem still persists.

Here is the entirety of Aform.aspx.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.Net.Mail;
using System.Drawing;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using System.Text;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);

    protected void Page_Load(object sender, EventArgs e)
    {
        conn.Open();
    }
    protected void Register_Click(object sender, EventArgs e)
    {

        SqlCommand cmd = new SqlCommand("insert into storedatabase values('" + firstNameTxt.Text + "')");

    }
}
And here is Aform.aspx:

<%@ Page Language="C#" AutoEventWireup="True" CodeBehind="AForm.aspx.cs" Inherits="WebApplication4.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>testWebPage</title>
    <style type="text/css">
        .auto-style2 {
            width: 100%;
        }
        .auto-style3 {
            height: 25px;
        }
        .auto-style4 {
            width: 292px;
        }
        .auto-style5 {
            height: 25px;
            width: 292px;
        }
        textarea {
  resize: none;
}
        .auto-style6 {
            height: 64px;
        }
        .auto-style7 {
            margin-right: 0px;
        }
        .auto-style8 {
            width: 292px;
            height: 26px;
        }
        .auto-style9 {
            height: 26px;
        }
        .auto-style10 {
            width: 292px;
            height: 23px;
        }
        .auto-style11 {
            height: 23px;
        }
    </style>
    </head>
<body>
    <form id="form1" runat="server">
        <h1 style="border: 8px outset #336699; background-color: #336699; color: #FFFFFF; font-family: Tahoma;">
            testWebApp</h1>

        <table class="auto-style2">
            <tr>
                <td class="auto-style4">First Name</td>
                <td>
                    <asp:TextBox ID="TextBox2" runat="server" MaxLength="20"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td class="auto-style4" style="color: #33CC33; font-weight: bolder; font-style: normal; font-variant: normal">Message</td>
                <td>
                    <asp:Button ID="Button1" runat="server" BackColor="#00CC00" BorderColor="#00CC00" Font-Bold="True" ForeColor="White" Text="Submit" />
                </td>
            </tr>
        </table>

    </form>
    </body>
</html>

Aform.aspx.cs' is inside Aform.aspx`. Thank you!


Solution

  • First up, we actually need to see more of the page markup.

    Next up, no, people here are not going to watch some video on some link you posted on YouTube.

    OK, keep in mind that prior to great systems like the .net framework, then it was often standard fair to open a connection, to the database, and then scope that connection global to your application, and keep the connection open.

    However, with new tools, then a "connection pool" is created for you, and your job as a developer then is to open such connections, but you are to let the system dispose and close the connection for you!

    Then, if later on, you want to do more database operations then the system will check the "pool" of connections, and re-use + re-cycle such connections for you. This thus eliminates from you the developer having to "try" and keep open or maintain such connections.

    Thus, it makes VERY little sense to attempt to JUST open a connection in the page load event. And keep in mind that the page load event fires each and every time for any post-back (such as a button click) and THEN your button code stub will run.

    Next up, you really want to use SQL parameters, since with web land, then you run the high risk of SQL injection. However, just as bad is attempting to "remember" the SQL rules for strings (you surround the text with quotes). For numbers (no surrounding quotes required), and for dates, once again you require surrounding quotes. So, by adopting SQL parameters, and not using string concatenation, you find the amount of code you write is about the same, but a HUGE DROP in SQL syntax errors will occur. In other words, less skill, less brain power, and less chance of making a mistake in your SQL code exists by adopting parameters. Often, at most, you wind up with maybe 1 extra line of code, but the resulting code is far easier to read, far easier to maintain, and of course far more reliable, and the bonus points is your code is SQL injection safe.

    Also, you don't mention if this is a master web page with a child web page, or this is a simple web form without a master page. And also keep in mind that textbox (or any control) placed inside of data aware controls such as a GridView, Repeater, ListView etc. do NOT allow a direct reference to the control (such as your text box) on the page, since there could be one row of data, or 20 rows of data, and hence when you reference a text box, what row of data are you referring to?

    So, the simplest example with simple markup would the text box as you have (but, as I stated, leaving out additional details such as having used a Repeater, or GridView etc. means the following example would not work.

    Hence, assuming a simple textbox on your page, then the full-page markup would look like this:

    <%@ Page Language="C#" 
        AutoEventWireup="true" 
        CodeBehind="SimpleInsert1.aspx.cs" 
        Inherits="CSharpWebApp.Test7.SimpleInsert1" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
    
    
                <asp:TextBox ID="TextBox2" runat="server" MaxLength="20">
                </asp:TextBox>
                <br />
                <asp:Button ID="Button1" runat="server" Text="Insert Data"
                    OnClick="Button1_Click"
                    />
    
                <br />
                <br />
                <br />
                <asp:Label ID="Label1" runat="server" Text="">
                </asp:Label>
    
    
            </div>
        </form>
    </body>
    </html>
    

    Now, of course when you created the blank new web form page, then all of the above markup would be created for you, and ONLY markup we added would be the text we added inside of the starting and ending form tag.

    Hence, the code behind now becomes this:

        protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    
        protected void Button1_Click(object sender, EventArgs e)
        {
            string strSQL =
                "insert into storedatabase (MyColumnName) values(@MyValue)";
    
            using (SqlConnection con = 
                new SqlConnection(ConfigurationManager.ConnectionStrings["TEST4"].ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand(strSQL, con))
                {
                    con.Open();
                    cmd.Parameters.Add("@MyValue", SqlDbType.NVarChar).Value = TextBox2.Text;
                    cmd.ExecuteNonQuery();
                }
            }
        }
    

    Note closely, in your SQL you REALLY (but really to avoid world poverty and suffering for years to come), want to specify the column(s) you are to use for the values you are to insert.

    And it tends to be a convention to name the SQL parameter(s) the same as the column name, but prefixed with a "@".

    Hence, assuming your column name in the database for this column value was say "FirstName", then suggested code would be:

            string strSQL =
                "insert into storedatabase (FirstName) values(@FirstName)";
    
            using (SqlConnection con = 
                new SqlConnection(ConfigurationManager.ConnectionStrings["TEST4"].ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand(strSQL, con))
                {
                    con.Open();
                    cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar).Value = TextBox2.Text;
                    cmd.ExecuteNonQuery();
                }
            }
    

    So, while we did wind up writing that one extra line of code (the cmd.Parameters.Add), we GAIN by NOT having to use messy string concatenations with "'" and all kinds of messy junk. Such junk gives rise to very flaky and difficult to read strings in your code.

    And of course this eliminates SQL injection issues. So, with string concatenations, then one missed ' (quote), one missed "," or whatever, and all your code and efforts will go sideways. It is super easy to mess up such code intermixed with SQL and then intermixed with some textbox control. Don't do it else you spend hours and hours trying to make simple code work.

    Also, note VERY closely in above, we did not write code to close the connection. That's the purpose of the "using blocks". So, we are to open the connection, but no need to write code to close the connection (and your example code by the way was and is missing the code to close the connection you opened. You don't want to open a database connection, and then forget to close it. But, with complex code, errors etc., this becomes VERY difficult for the developer, and hence we adopted the using block of code - which thus automatic handles the closing and disposing of the open connection for us, but HUGE BONUS points is that now the .net system will recycle and manage the connection pool for you!!!

    You thus don't have to close the connection - the system will do this for you! And better bonus points is if a open connection exists, the system will re-cycle and re-use them for you. In other words, are you now 100% free to always open a connection in code, but if a existing "pooled" connection exists, then it will be re-used, and the performance hit of opening the database from scratch is 100% limited.

    So, the new design pattern is that you are free to (and should) open the connection each time you need it, even in one small code stub, since as noted, the connection pool will be used. As noted, bonus points is if you code has some errors(s), then you not wind up with stray un-closed connections, and that can become a huge mess for a web site or even desktop application in which connections you create are then not managed or disposed of. You start to chew up memory, and start to see errors like too many database connections open etc. But, with the above using blocks, then this issue of attempted management by the developer is simply not required anymore.

    And last but not least, when you write a SQL insert statement, include the column names surrounded by (), and then follow the statement with the values().

    And for adding parameters, do NOT use the .addwith of the SQL command object, but use add, and use strong typed parameters using sqldbType as per the above example.

    Edit: With the provided markup

    Ok, so the provided markup is now this:

        <h1 style="border: 8px outset #336699; background-color: #336699; color: #FFFFFF; font-family: Tahoma;">
            testWebApp</h1>
    
        <table class="auto-style2">
            <tr>
                <td class="auto-style4">First Name</td>
                <td>
                    <asp:TextBox ID="TextBox2" runat="server" MaxLength="20"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td class="auto-style4" style="color: #33CC33; font-weight: bolder; font-style: normal; font-variant: normal">Message</td>
                <td>
                    <asp:Button ID="Button1" runat="server" 
                        BackColor="#00CC00" BorderColor="#00CC00" Font-Bold="True" ForeColor="White" 
                        Text="Submit"
                        OnClick="Button1_Click"
                        
                        />
                </td>
            </tr>
        </table>
    

    Looking at above, there is NOT ANY text box called firstNameTxt, but there is most certainly a text box called TextBox2.

    Hence, code behind can freely reference the textbox, but ONLY the one called TextBox2.

    Hence, assuming we add a button click event to button1, then we have this markup:

        <h1 style="border: 8px outset #336699; background-color: #336699; color: #FFFFFF; font-family: Tahoma;">
            testWebApp</h1>
    
        <table class="auto-style2">
            <tr>
                <td class="auto-style4">First Name</td>
                <td>
                    <asp:TextBox ID="TextBox2" runat="server" MaxLength="20"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td class="auto-style4" style="color: #33CC33; font-weight: bolder; font-style: normal; font-variant: normal">Message</td>
                <td>
                    <asp:Button ID="Button1" runat="server" 
                        BackColor="#00CC00" BorderColor="#00CC00" Font-Bold="True" ForeColor="White" 
                        Text="Submit"
                        OnClick="Button1_Click"
                        
                        />
                </td>
            </tr>
        </table>
    

    And now code behind can do this:

        protected void Button1_Click(object sender, EventArgs e)
        {
            string MyTextBox2Value = TextBox2.Text;
    
            Debug.Print("Text box 2 value = " + MyTextBox2Value);
        }
    

    So, in your sample markup, there is no firstNameTxt, but there is most certainly a textbox called Textbox2.

    I would also of course do a re-build all, since intel-sense can go sideways if you have a bunch of existing errors, and thus Visual Studio will often report a lot of extra errors until such time you remove any and all build errors.