How to pass data between ASP.net, sql server and c# - c#

I'm trying to develop a web site that receives data from SQL server, then show info on listbox and textbox, and when user select an option then insert data to a table in the database.
My ASP.NET controls are:
<asp:ListBox ID="ListBox1" ClientIDMode="static" runat="server"></asp:ListBox>
<asp:Button ID="btnInsert" runat="server" Text="Start" OnClick="btnInsert_Click" />
I need the data loaded to a listbox, but not sure how to do directly. To retrieve the info and see if its working I did this:
protected void Page_Load(object sender, EventArgs e){
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader reader = cmd.ExecuteReader();
GridView2.DataSource= reader;
GridView2.DataBind();
con.Close();
var nProject = GridView2.Rows.Count;
for (int b = 0; b < nProject ; b++)
{
ListBox1.Items.Add(GridView2.Rows[b].Cells[0].Text);
}
}
Then I tried to set the selected info to a textbox, but nothing happens (because I managed to insert data from textbox to a SQL Server INSERT) :
protected void ListBox1_OnSelectedIndexChanged(object sender, System.EventArgs e)
{
TextBox2.Text = ListBox1.SelectedValue;
Response.Write("ListBox selectedIndexChanged");
}
The info is send back to the database with a button click:
protected void btnInsert_Click(object sender, EventArgs e)
{
var IP = "111.111.11";
txtStatus.Text = "Start";
txtProject.Text = "PR-02";
var indice = 0;
// This always returns "0"
if (ListBox1.SelectedItem != null)
{
indice = ListBox1.SelectedIndex;
}
txtProject.Text = indice.ToString();
// Sql INSERT works fine, but only with info manually created. I can't get the real info to work
SqlConnection con = new SqlConnection("****");
SqlCommand cmd = new SqlCommand(#"INSERT INTO [dbo].[table3]
([project]
,[user_task]
,[status]
,[ip]
,[location])
VALUES
('" + txtProject.Text + "', '" + txtUser.Text + "', '" + txtStatus.Text + "', '" + txtIP.Text + "', '" + txtLocation.Text + "')", con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}

The Page_Load is one of the first events to run every time there is a call to the server, this means that it runs before the btnInsert_Click event.
This means that you are repopulating the ListBox1 before checking the SelectedItem, this is why it always returns "0"
You have to consider this and use something like
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack || Page.IsCallback) return;
(...)
}
It is hard to understand what you want to do, but I think the ListBox1_OnSelectedIndexChanged is useless if you correct the Page_Load event.
Side notes:
You should really start by putting using statements where you can (on SqlConnection and SqlCommand)
Watch out for Sql Injections, may be a simple test program, but you should NEVER, EVER do this: #"INSERT INTO (...) VALUES ('" + txtProject.Text + "'"
use parameters instead:
using(SqlConnection con = new SqlConnection("****"))
using(SqlCommand cmd = new SqlCommand("INSERT INTO [dbo].[table3] ([project]) values (#project)", con))
{
cmd.Parameters.AddWithValue("#project", txtProject.Text);
}
It seems you are using .Net Framework with aspx pages, you should really consider using newer technologies (.net core).

Related

Need to update a column in SQL with WHERE using comma separated values from textbox

Just to let you guys know I'm not a programmer # all but I can manage to get code to work sometimes but I'm stumped now. I have a c# web-based project that I finally figured out how to pass comma-separated values from a single textbox to return a result in Datagrid when I click search. The code looks like this:
{
String str = "select row_number() OVER (ORDER BY [sequenceid]) #,[JobNumber],[Item],Quantity,Bay,Trailer,Sequenceid, Produced from vwcabsandcountersbyjob ";
String str1 = "select SUM([Quantity])AS [Items Remaining to Be Loaded] from vwcabsandcountersbyjob";
//CODE THAT ALLOWS MULTIPLE ORDER NUMBERS TO BE ENTERED IN A SINGLE TEXTBOX
if (!string.IsNullOrEmpty(TextBox1.Text.Trim()))
{
List<string> search = new List<string>();
char[] characters = { ',', '\n' };
string[] ids = TextBox1.Text.Trim().Split(characters, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < ids.Length; i++)
{
search.Add(ids[i].Trim());
}
str += " WHERE (jobnumber IN ('" + string.Join("','", search.ToArray()) + "') and loaded is null) ORDER BY ITEM DESC";
}
//CODE THAT ALLOWS MULTIPLE ORDER NUMBERS TO BE ENTERED IN A SINGLE TEXTBOX
if (!string.IsNullOrEmpty(TextBox1.Text.Trim()))
{
List<string> search = new List<string>();
char[] characters = { ',', '\n' };
string[] ids = TextBox1.Text.Trim().Split(characters, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < ids.Length; i++)
{
search.Add(ids[i].Trim());
}
str1 += " WHERE (jobnumber IN ('" + string.Join("','", search.ToArray()) + "') and loaded is null) ";
}
SqlCommand xp = new SqlCommand(str, vid);
SqlCommand xp1 = new SqlCommand(str1, vid);
//xp.Parameters.Add("#search", SqlDbType.NVarChar).Value = TextBox1.Text;
xp.Parameters.Add("#search", SqlDbType.NVarChar, 20).Value = TextBox1.Text;
xp1.Parameters.Add("#search", SqlDbType.NVarChar).Value = TextBox1.Text;
vid.Open();
xp.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = xp;
DataSet ds = new DataSet();
da.Fill(ds, "[jobnumber]");
GridView1.DataSource = ds;
GridView1.DataBind();
vid.Close();
vid.Open();
xp1.ExecuteNonQuery();
SqlDataAdapter da1 = new SqlDataAdapter();
da1.SelectCommand = xp1;
DataSet ds1 = new DataSet();
da1.Fill(ds1, "[jobnumber]");
GridView2.DataSource = ds1;
GridView2.DataBind();
vid.Close();
}
Now i have a second button that I want to update a field when they press "mark complete". It works fine with a single entry and here is the code:
protected void Button2_Click(object sender, EventArgs e)
{
vid.Open();
SqlCommand xp = new SqlCommand("Update [Job_Master] SET [Completed] = GETDATE() WHERE [job number] =#search", vid);
SqlCommand xp3 = new SqlCommand("Update [Countertops] SET [Completed] = GETDATE() WHERE [jobnumber] =#search", vid);
xp.Parameters.Add("#search", SqlDbType.VarChar).Value = TextBox1.Text;
xp3.Parameters.Add("#search", SqlDbType.NChar).Value = TextBox1.Text;
xp.ExecuteNonQuery();
xp3.ExecuteNonQuery();
vid.Close();
string message = "This job has been marked complete!";
string script = "window.onload = function(){ alert('";
script += message;
script += "')};";
ClientScript.RegisterStartupScript(this.GetType(), "SuccessMessage", script, true);
}
The problem is it only works for one value. I've tried a million different things but nothing works mainly because I don't know what I'm doing. This is the closest I've come (i added a 3rd button because i didn't want to break button 2 that works for single value):
Protected void Button3_Click(object sender, EventArgs e)
{
String str3 = "Update [Job_Master] SET [Completed] = GETDATE()";
if (!string.IsNullOrEmpty(TextBox1.Text.Trim()))
{
List<string> search = new List<string>();
char[] characters = { ',', '\n' };
string[] ids = TextBox1.Text.Trim().Split(characters, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < ids.Length; i++)
{
search.Add(ids[i].Trim());
}
str3 += " WHERE [job number] IN ('" + string.Join("','", search.ToArray()) + "')";
}
SqlCommand xp4 = new SqlCommand(str3, vid);
vid.Open();
xp4.Parameters.Add("#search", SqlDbType.VarChar).Value = TextBox1.Text;
xp4.ExecuteNonQuery();
vid.Close();
string message = "This job has been marked complete!";
string script = "window.onload = function(){ alert('";
script += message;
script += "')};";
ClientScript.RegisterStartupScript(this.GetType(), "SuccessMessage", script, true);
}
and it doesn't work. It only updates when I have a single entry. My question is how do use those same values from that textbox work in an update statement? I hope I'm being clear but will try my best to answer any questions but please remember my vocabulary is very limited when it comes to programming. Thanks!
It would be wise if you just divide your code into smaller parts, group them by their role and responsibility. This would make things much easier to maintain and also to work with.
if you see repetitive code, then it's a flag of moving it to a separate method.
A few notes that I've found in your code :
you should use using clause when possible, like using it with SqlConnection, SqlCommand, and SqlDataAdapter.
Multiple unneeded SqlCommand are used.
Providing SqlParamter while the query doesn't have any parameter.
using string concatenation is not optimal, instead use StringBuilder.
Your business logic should have its own methods or classes, and can be recalled inside any event.
Split returns Array, so no need to convert Array to another Array.
Always, each portion of the code, should be scoped to that portion role only. For instance, OnClick event, should handle the click event only, and not handling the update records. The update part should be declared and handled outside the event, and you only recall it from inside the event.
I have updated the code, which would give you a better view on the above notes:
protected void SearchButton_OnClick(object sender, EventArgs args)
{
//CODE THAT ALLOWS MULTIPLE ORDER NUMBERS TO BE ENTERED IN A SINGLE TEXTBOX
if (!string.IsNullOrWhiteSpace(TextBox1.Text))
{
SearchAndBind(TextBox1.Text);
}
}
protected void Button2_Click(object sender, EventArgs e)
{
var textValue = TextBox1.Text.Trim();
if(!string.IsNullOrWhiteSpace(textValue))
{
UpdateRecords("UPDATE [Job_Master] SET [Completed] = GETDATE() WHERE [job number] = #search", "#search", textValue);
UpdateRecords("UPDATE [Countertops] SET [Completed] = GETDATE() WHERE [jobnumber] = #search", "#search", textValue);
CompletedJobNotification();
}
}
protected void Button3_Click(object sender, EventArgs e)
{
string inClause = GetInClause(TextBox1.Text);
if(!string.IsNullOrWhiteSpace(inClause))
{
StringBuilder query = new StringBuilder("Update [Job_Master] SET [Completed] = GETDATE()");
query.Append(" WHERE [job number] ").Append(inClause);
UpdateRecords(query.ToString());
CompletedJobNotification();
}
}
private void PopulateData(string query, string srcTable, GridView gridView)
{
if (!string.IsNullOrWhiteSpace(query))
{
using(SqlConnection connection = new SqlConnection(connectionString))
using(SqlDataAdapter adapter = new SqlDataAdapter(query, connection))
{
adapter.Open();
DataSet ds = new DataSet();
da.Fill(ds, srcTable);
gridView.DataSource = ds;
gridView.DataBind();
}
}
}
private string GetInClause(string text)
{
if(!string.IsNullOrWhiteSpace(text))
{
char[] characters = { ',', '\n' };
var ids = text.Trim().Split(characters, StringSplitOptions.RemoveEmptyEntries);
return "IN ('" + string.Join("','", ids) + "')";
}
return string.Empty;
}
private void SearchAndBind(string search)
{
//CODE THAT ALLOWS MULTIPLE ORDER NUMBERS TO BE ENTERED IN A SINGLE TEXTBOX
if (!string.IsNullOrWhiteSpace(search))
{
string inClause = GetInClause(search);
if(!string.IsNullOrWhiteSpace(inClause))
{
var searchWhere = $" WHERE jobnumber loaded IS NULL AND {inClause} ";
StringBuilder str = new StringBuilder("SELECT ROW_NUMBER() OVER (ORDER BY [sequenceid]) #,[JobNumber],[Item],Quantity,Bay,Trailer,Sequenceid, Produced FROM vwcabsandcountersbyjob");
StringBuilder str1 = new StringBuilder("SELECT SUM([Quantity]) AS [Items Remaining to Be Loaded] FROM vwcabsandcountersbyjob");
str.Append(searchWhere).Append(" ORDER BY ITEM DESC ");
str1.Append(searchWhere);
PopulateData(str.ToString(), "[jobnumber]", GridView1);
PopulateData(str1.ToString(), "[jobnumber]", GridView2);
}
}
}
private void UpdateRecords(string query, string parameterName = null,string parameterValue = null)
{
using(var connection = new SqlConnection(connectionString))
using(var command = new SqlCommand(query))
{
if(!string.IsNullOrWhiteSpace(parameterName) && !string.IsNullOrWhiteSpace(parameterValue))
{
command.Parameters.AddWithValue(parameterName, parameterValue);
}
connection.Open();
command.ExecuteNonQuery();
}
}
private void ShowJavaScriptAlert(string message)
{
if(!string.IsNullOrWhiteSpace(inClause))
{
ClientScript.RegisterStartupScript(this.GetType(), "SuccessMessage", $" window.onload = function(){{ alert('{message}')}}; ", true);
}
}
private void CompletedJobNotification()
{
ShowJavaScriptAlert("This job has been marked complete!");
}
Ok, first up, we are writing too much code here.
Next up, we can MOST certainly have a list of parameters, and they can be optional, and we NEVER concatenate user input into the SQL string - we don't have to.
Now, I don't have the users data, lets do this:
I can type in a city, or several. I will display some hotels, and then ONE button to confirm the hotels and update the database with the confirm date.
(the same as what you are doing).
Ok, so a text box, and a button. Like this:
Search: <asp:TextBox ID="txtPromptCity" runat="server" Height="17px" Width="336px"></asp:TextBox>
<asp:Button ID="cmdSearch" runat="server" Text="Search City" Style="margin-left:20px" />
So, you can type in one city, or several (with a , in between). Same as what you need/are doing.
Ok, so when you type in and hit search, we send the results to a grid view.
So, we have this code for the button:
DataTable rstHotels = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
rstHotels = (DataTable)ViewState["rstHotels"];
}
protected void cmdSearch_Click(object sender, EventArgs e)
{
string[] strChoices;
strChoices = txtPromptCity.Text.Split(',');
using (SqlCommand cmdSQL = new SqlCommand("",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
string strSQL = "";
int i = 1;
foreach (string strCity in strChoices)
{
if (strSQL != "")
strSQL += ",";
i += 1;
strSQL += "#" + i;
cmdSQL.Parameters.Add("#" + i, SqlDbType.NVarChar).Value = strCity;
}
cmdSQL.CommandText = "SELECT * from tblHotels WHERE City IN (" + strSQL + ")";
cmdSQL.Connection.Open();
rstHotels.Rows.Clear();
rstHotels.Load(cmdSQL.ExecuteReader());
ViewState["rstHotels"] = rstHotels;
GridView1.DataSource = rstHotels;
GridView1.DataBind();
}
}
note how I keep/have the data table - I persist it at the class level.
So, our output is now this
Ok, so we now have the parameter issue working.
Now, all you have to do is check box the ones to approve, and then send the data back to the table - along with the approved visit date.
That code NOW becomes dead simple.
We can use this:
protected void cmdConfirm_Click(object sender, EventArgs e)
{
foreach (GridViewRow gvRow in GridView1.Rows)
{
CheckBox chkVisit = (CheckBox)gvRow.FindControl("chkVisit");
if (chkVisit.Checked)
// update Visit date in table
rstHotels.Rows[gvRow.RowIndex]["VistDate"] = DateTime.Today;
// now send table changes back to database.
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblHotels where ID = 0",
new SqlConnection(My.Settings.TEST4)))
{
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daUpate = new SqlCommandBuilder(da);
da.Update(rstHotels);
}
}
}
So, note how we send the grid choices back to the table, and then send the table back to the database. This makes the whole process easy, and VERY much less code.
And I would probably add a 2-3 lines more code in the Row bound event, and set the checkbox if the row has a date already. And we could I suppose even check if we un-check the checkbox, and again null out the date column row.
All of these are VERY dead easy with the above approach.
So, persisting the table as per above - makes this REALLY easy. And note the data Keys setting - we can use/get/grab the primary key of each row and not have to display it - but this example does not see to need this ability anyway.
The markup I used for above is this:
Search: <asp:TextBox ID="txtPromptCity" runat="server" Height="17px" Width="336px"></asp:TextBox>
<asp:Button ID="cmdSearch" runat="server" Text="Search City" Style="margin-left:20px" OnClick="cmdSearch_Click" />
<div style="width:45%;margin-top:20px;margin-left:20px">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" CssClass="table table-hover">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="VistDate" HeaderText="Visit Date" DataFormatString="{0:yyyy-MM-dd}" />
<asp:TemplateField HeaderText="Confirm Visit" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="chkVisit" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="cmdConfirm" runat="server" Text="Confirm Vists" Width="143px" CssClass="btn-info" OnClick="cmdConfirm_Click" />
<br />
</div>
Thanks for all of the help from everyone. The actual was that my aspx code was pointing to OnClick="Button2_Click" and not OnClick="Button3_Click". Once i fixed that and put in the original code it worked. Having said that you guys have pointed out some great points that i'm going to try and fix. Again, i'm not a programmer and sure appreciate you guys helping. Thanks.
First of all, good job getting as far as you did. I think the only thing left is just a simple mistake. I'll provide this which removes a little of the code you don't need
Protected void Button3_Click(object sender, EventArgs e)
{
String str3 = "Update [Job_Master] SET [Completed] = GETDATE()";
// ** This is a little dangerous. If the TextBox is EMPTY, you will be
// ** Updating ALL rows in the table. I assume that is not what you want.
// ** You should return an error if text box is empty.
if (!string.IsNullOrEmpty(TextBox1.Text.Trim()))
{
char[] characters = { ',', '\n' };
char[] invalid = { ',',';',' ','\'','"','\\','\t' };
string[] ids = TextBox1.Text.Trim().Split(characters, StringSplitOptions.RemoveEmptyEntries);
//
// ** You don't really need to copy into a list.
// ** If you want to trim each entry, you can just
// ** replace in the original array.
for (int i = 0; i < ids.Length; i++)
{
ids[i] = ids[i].Trim();
// ** Add a check here to make sure id is safe
// ** to prevent SQL injection.
if (ids[i].IndexOfAny( invalid ) != -1)
{
return; // should give error, probably.
}
}
// *** figure out if it is job_number or jobnumber or (unlikely) job number
str3 += " WHERE [job_number] IN ('" + string.Join("','", ids) + "')";
}
else {
return; // empty string. Should give error.
}
// ** OPEN FIRST
vid.Open();
SqlCommand xp4 = new SqlCommand(str3, vid);
// ** #search not needed
// xp4.Parameters.Add("#search", SqlDbType.VarChar).Value = TextBox1.Text;
xp4.ExecuteNonQuery();
vid.Close();
string message = "This job has been marked complete!";
string script = "window.onload = function(){ alert('";
script += message;
script += "')};";
ClientScript.RegisterStartupScript(this.GetType(), "SuccessMessage", script, true);
}
Now, if the IDs are not supposed to be numeric, you have a little more difficulty preventing SQL injection. You'd want to create a parameter for each one (#1, #2, #3, etc...) and add each as a parameter.
Or, of course, you could run a separate SQL statement for each ID. Not super efficient but probably fast enough.

Cannot insert item from dropdown menu into my database

I am new to C# and i am trying to insert some values to my database i created inside visual studio.
-I am creating a recipe application-
So in the form i have some components such as text boxes(For title,ingredients,description), a dropdown item(combobox) to specify if it's food or sweet and a button to insert all these data into my database.
When i am pressing the button i can add everything(all the text boxes) to the database except the dropdown value.
Here is the code inside the button_click
private void addItemButton_Click(object sender, EventArgs e)
{
string dat = "Insert into [Table](Title,Category,Ingredients,Description) Values('" + titleTextBox.Text + "','" + dropdownCategory.SelectedValue + "','" + addIngredientTextBox.Text + "','" + addDescriptionTextBox.Text + "')";
SqlConnection sqlCon = new SqlConnection(connectionString);
SqlCommand sqlCmd = new SqlCommand(dat, sqlCon);
sqlCon.Open();
sqlCmd.ExecuteNonQuery();
sqlCon.Close();
}
I make a code example, which can insert the combobox value to the database successfully.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string dat = string.Format("Insert into [Sample](Title,Category,Ingredients,Description)values('{0}','{1}','{2}','{3}')", textBox1.Text, comboBox1.SelectedItem,textBox2.Text,textBox3.Text);
string connectionString = #"connectionstring";
SqlConnection sqlCon = new SqlConnection(connectionString);
SqlCommand sqlCmd = new SqlCommand(dat, sqlCon);
sqlCon.Open();
sqlCmd.ExecuteNonQuery();
sqlCon.Close();
MessageBox.Show("success");
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.Items.AddRange(new object[] { "basketball","football", "volleyball" });
}
}
I would try to look into content of string dat.
It might contain invalid data if "dropdownCategory.SelectedValue" returns something
that you don't expect.
Other than that, order of Open(), ExecuteNonQuery() and Close() methods might be incorrect. Try to read docs of these methods.
Another thing that you should look into is error message that is returned(if there is one). They are usually pretty informative.
Ok i don't know if it's correct or not but it worked on me.
I changed
dropdownCategory.SelectedValue
to
dropdownCategory.Text
and it worked.

How can I use multiple forms of the same event using windows forms?

I asked this same question on SO-pt but no one seemed to understand the question, though I made it clear.
I have a form that I'll use to
Register customers in the database.
Alter any of the registers.
Show the registers.
Here I'm instantiating this form:
private void mnuRegister_Click(object sender, EventArgs e)
{
var frmRegister = new frmRegisterScreen();
frmRegister.Show();
}
As you can see, I'm calling the form from within a ToolStripMenuItem called mnuRegister.
Now, there are a number of properties from this form that I'm customizing at the Load` event, that'll make it more specific for registering the customers.
Below is the code:
private void frmRegisterScreen_Load(object sender, EventArgs e)
{
//set the database connection and the Sql command to be used
string conString = "Server = .\\sqlexpress; trusted_connection = yes; database=he_dados;";
SqlConnection con = new SqlConnection(conString);
string sel = "SET DATEFORMAT dmy;\n" //set date format to dd//mm/yyyy
+ "Insert into Customer(" +
"Name,IDCard,Phone,Address,Observation)" +
"values(" +
"'" + txtName.Text +
"','" + mskIDCard.Text +
"','" + mskPhone.Text +
"','" + txtAddress.Text +
"','" + txtObs.Text + "');";
SqlCommand selCmd = new SqlCommand(sel, con);
//set the form properties relate to the customer registration
lblMain.Text = "Register Customer";
tsbSave.Text = "Save Changes";
}
As you can see, this code is obviously intended to insert data in a table.
Now, what I want to do is to call another instance of this form:
private void mnuViewRegister_Click(object sender, EventArgs e)
{
var frmViewRegister = new frmRegisterScreen();
frmViewRegister.Show();
}
Then I want to set specific properties, required for me to make a simple query using the same form, for example:
private void frmRegisterScreen_Load(object sender, EventArgs e)
{
//set the database connection and the Sql command to be used
string conString = "Server = .\\sqlexpress; trusted_connection = yes; database=he_dados;";
SqlConnection con = new SqlConnection(conString);
string sel = "Select * from Customer;";
SqlCommand selCmd = new SqlCommand(sel, con);
//set the form properties relate to the customer registration
lblMain.Text = "View Customer Registers";
tsbSave.Text = "View";
}
In other words, I would like to have event calls specific to the instance of the form, instead of having one event that's valid for any of the instances.
Is that possible?
If you find yourself configurating a great deal of UI elements, then just create separate Forms. It's not like they cost you anything, and they'll be easier to maintain. But it looks like you're only changing a couple of UI elements (like the label), so that's not too bad.
Either move the configuration logic into two separate methods on the Form, like ConfigureForRegistration and ConfigureForViewingRegistration, and then call the appropriate one when you instantiate the Form:
var frmRegister = new frmRegisterScreen();
frmRegister.ConfigureForRegistration();
frmRegister.Show();
Or you could create an enumeration for each possible view, and pass a value in when you instantiate the Form:
public enum ScreenOption
{
Register,
AlterRegister,
ViewRegister
}
public class frmRegisterScreen
{
public frmRegisterScreen(ScreenOption option)
{
switch (option)
{
case ScreenOption.ViewRegister:
//set the database connection and the Sql command to be used
string conString = "Server = .\\sqlexpress; trusted_connection = yes; database=he_dados;";
SqlConnection con = new SqlConnection(conString);
break;
...
}
}
}
var frmRegister = new frmRegisterScreen(ScreenOption.ViewRegister);
frmRegister.Show();

dropdownlist not fetching values from table on OnSelectedIndexChanged

am trying to fetch values from database table on dropdownlist value change and display them in textbox. While selecting any value from the dropdownlist the page is refreshing but no values are displaying in the textbox and following are the codes:
Default.aspx
<asp:DropDownList ID="DropDownList1" runat="server" AppendDataBoundItems="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" AutoPostBack="true">
<asp:ListItem Text="<Select Subject>" Value="0" />
</asp:DropDownList>
Default.aspx.cs
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
string ddl2value = DropDownList1.SelectedValue.ToString();
// fillDropdown3(ddl3, ddl2value);
SqlConnection objConn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
SqlCommand objCmd2;
SqlDataReader objRdr2;
// String strCmd2;
objConn2.Open();
objCmd2 = new SqlCommand("SELECT code, rank, address FROM agen_mast WHERE name = " +
"'" + ddl2value.ToString() + "'", objConn2);
objRdr2 = objCmd2.ExecuteReader();
while (objRdr2.Read())
{
TextBox9.Text = (string)objRdr2["code"].ToString();
TextBox8.Text = (string)objRdr2["address"].ToString().ToUpper();
TextBox10.Text = (string)objRdr2["rank"].ToString().ToUpper();
}
objRdr2.Close();
objConn2.Close();
// Response.Write(ddl2value.ToString());
}
You could try something like this:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if(DropDownList1.SelectedValue !="-1"){
string ddl2value = DropDownList1.SelectedValue.ToString();
SqlConnection objConn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
SqlCommand objCmd2;
SqlDataReader objRdr2;
objConn2.Open();
objCmd2 = new SqlCommand("SELECT code, rank, address FROM agen_mast WHERE name = " +
"'" + ddl2value + "'", objConn2);
objRdr2 = objCmd2.ExecuteReader();
while (objRdr2.Read())
{
TextBox9.Text = (string)objRdr2["code"].ToString();
TextBox8.Text = (string)objRdr2["address"].ToString().ToUpper();
TextBox10.Text = (string)objRdr2["rank"].ToString().ToUpper();
}
objRdr2.Close();
objConn2.Close();
}
}
And add a dummy ListItem with Value -1 as the first item in the DropDownList1 in the .aspx side. By the way, make sure you are sending the correct parameter to SqlCommand. Right now you are looking for a record with Name = 0. Also, ddl2Value is already of type string so you don't need to call ToString() inside SqlCommand

ASP.NET: Records in database don't get updated

I'm trying to update my database records, but no changes are made and no error messages. I checked the syntax, the values I'm sending, everything is just fine ..
any suggestions?
This is my code which executed when [save] button is clicked:
ds.UpdateCommand = "UPDATE Users
SET Fullname='" + fname.Text + "',
Permission='" + per.SelectedValue + "',
Email='" + email.Text + "',
phone='" + phone.Text + "'
WHERE UserID=" + Session["userID"].ToString();
ds.Update();
I'm reading values from form filled by the user
ds is an SqlDataSource
If I have to add more details let me know
EDITS:
This page is for user to update his/her information
I'm setting the form values on Page_Load depending on the users information already exist in database.
the user edits his/her info and click [Save]
after setting braekpoints, I found that query string is taking the default values not the new ones. what should I do?
The entire code:
protected void Page_Load(object sender, EventArgs e)
{
Session["userID"] = Request.QueryString["id"];
SqlConnection cn = new SqlConnection();
cn.ConnectionString = ds.ConnectionString;
cn.Open();
SqlCommand cm = new SqlCommand();
cm.Connection = cn;
cm.CommandText = "select * from Users where UserID='" + Session["userID"].ToString() + "'";
SqlDataReader dr;
dr = cm.ExecuteReader();
if (dr.Read())
{
uname.Text = dr["username"].ToString();
fname.Text = dr["Fullname"].ToString();
per.SelectedValue = dr["Permission"].ToString();
email.Text = dr["Email"].ToString();
phone.Text = dr["phone"].ToString();
}
else Response.Redirect("Default.aspx");
dr.Close();
cn.Close();
}
protected void Button3_Click(object sender, EventArgs e)
{
ds.UpdateCommand = "update Users set Fullname='" + fname.Text + "', Permission='" + per.SelectedValue + "', Email='" + email.Text + "', phone='" + phone.Text + "' where UserID=" + Session["userID"].ToString();
ds.Update();
Response.Redirect("control_pan.aspx");
}
Basically, if you have a DataSet and you want to use that to update your database, you need to:
define the UpdateCommand as shown in the MSDN documentation to reference the columns from the DataTable which will be used to update
update an existing row in one of your DataTables inside the DataSet
once you've done that, then you can call .Update() on the data set (or data table) to execute the update - ADO.NET will check for updates to any of the rows of the DataTable, and if an update is found, then the UpdateCommand will be executed, with the parameters bound to the values of the DataTable's row in question
I would also recommend to read up on how the ADO.NET data model and using DataSets and DataTables works in detail - e.g. here Update Data Using .NET DataSets
The alternative, of course, would be to create a SqlConnection and a SqlCommand, using a parametrized query to do the insert yourself, without all the hassle and effort involved with DataSets and DataTables. But in that case, make sure to ALWAYS use parameterized queries (and NEVER just concatenate together your SQL statement including values straight from user input .....) - see why here
I suspect the Session["UserID"] is null. To check this set break point on ds.Update(); by putting the cursor on it then pressing F9.
To see the result query hover your mouse pointer over ds.UpdateCommand when break point pauses operation.
Update: put the code in the page load to be executed only once that is when first the page loads
if(!IsPostBack)
{
//put your code here
}
Update
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
Session["userID"] = Request.QueryString["id"];
SqlConnection cn = new SqlConnection();
cn.ConnectionString = ds.ConnectionString;
cn.Open();
SqlCommand cm = new SqlCommand();
cm.Connection = cn;
cm.CommandText = "select * from Users where UserID='" + Session["userID"].ToString() + "'";
SqlDataReader dr;
dr = cm.ExecuteReader();
if (dr.Read())
{
uname.Text = dr["username"].ToString();
fname.Text = dr["Fullname"].ToString();
per.SelectedValue = dr["Permission"].ToString();
email.Text = dr["Email"].ToString();
phone.Text = dr["phone"].ToString();
}
else Response.Redirect("Default.aspx");
dr.Close();
cn.Close();
}
}
I seriously doubt you've provided enough details here to resolve the issue.
That type is UserID? Does the value need to be enclosed in quotes?
Are you setting the right value in your WHERE clause, and does that value existing in the database? You need to look at the resulting query string and then run it manually to determine what might be wrong.
Also, shouldn't you have the # character prefix for your string so that newlines are part of your string? Is this really what your code looks like?
Of course, without knowing more about the code, it's hard to say what else it might be as well.

Categories

Resources