ASP.NET Page does not refresh after running a DELETE SQL Query - c#

I am using VS2005. Currently I have a delete linkButton in my gridview, and if I presses on it to delete a row, the GridView goes empty, and I will have to click on the link again to access the page.
Below is my codefor .aspx:
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" ondatabound="gv_DataBound" OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="UserSelection" OnCheckedChanged="UserSelector_CheckedChanged" runat="server" />
<asp:LinkButton ID="lnkDelete" runat="server" onclick="lnkDelete_Click" Text="Delete" CommandArgument='<%# Eval("Employee") %>' ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Below is my code for .cs
protected void lnkDelete_Click(object sender, EventArgs e)
{
LinkButton lnk = (LinkButton)sender;
string stid = lnk.CommandArgument.ToString();
SqlDataSource1.SelectCommand = "DELETE FROM [UserDB]where Employee like '%"+stid+"%'";
SqlDataSource1.DataBind();
}
I have tried assigning my delete query to SqlDataSource1 and select query to source2, but if that's the case, my delete query would not work.
I have also tried using IsPostBack on my PageLoad method, but the GridView goes empty as well after clicking on the delete button.
Currently both of my queries are assigned to SqlDataSource1, and once the query is deleted, the page just go blank, although the query is deleted.
May I know how can I refresh the page or reload the GridView table after the delete query is ran?
Thank you.
Thanks to the help from you guys, the problem is solved. Currently my working code is as follows:
LinkButton lnk = (LinkButton)sender;
string stid = lnk.CommandArgument.ToString();
SqlConnection conn = new SqlConnection("DATA-SOURCE");
string sql = string.Format("DELETE FROM [UserDB] where Employee like '%{0}%'",stid);
SqlCommand cmd = new SqlCommand(sql,conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
SqlDataSource1.SelectCommand = "SELECT * FROM [UserDB]";
SqlDataSource1.DataBind();
Response.Redirect("/Project/UserList.aspx");
I used a sql connection string for the delete query, and sqldatasource for the select query afterwards, finally refreshed the page by using response.redirect. Hope it helped newbies like me who met this error too.
Great thanks to all who provided help

Why are you assigning a DELETE command to the SelectCommand property ?
Just run the DELETE on a separate SqlCommand instance with ExecuteNonQuery and commit. Another option is to use DeleteCommand of the existing SqlDataSource.
Another point:
The way you build the DELETE SQL is vulnerable to a serious security problem called SQL injection - easiest and best way to avoid that is to use bind parameters!

First you should read up on what databinding in ASP.NET can do for you. (Then you won't have to write any codebehind for this scenario.)
Example: (Not tested in VS)
You should use the SqlDataSource's DeleteCommand to set the delete command and its parameters like this:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="..."
SelectCommand="..."
DeleteCommand="DELETE FROM [UserDB] WHERE Employee=#Employee">
<DeleteParameters>
<asp:Parameter Name="Employee" />
</DeleteParameters>
</asp:SqlDataSource>
And the on the GridView, you should set the DataKeyNames property, and inside the ItemTemplate's Linkbutton you should set the CommandName property to "Delete" as shown below:
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1"
ondatabound="gv_DataBound" DataKeyNames="Employee"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="UserSelection" runat="server"
OnCheckedChanged="UserSelector_CheckedChanged" />
<asp:LinkButton ID="lnkDelete" runat="server"
onclick="lnkDelete_Click" Text="Delete"
CommandArgument='<%# Eval("Employee") %>'
CommandName="Delete" ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Try like this
protected void lnkDelete_Click(object sender, EventArgs e)
{
LinkButton lnk = (LinkButton)sender;
string stid = lnk.CommandArgument.ToString();
SqlConnection conn = new SqlConnection(<put your connectionstring here>);
string sql = string.Format("DELETE FROM [UserDB] where Employee like '%{0}%'",stid);
SqlCommand cmd = new SqlCommand(sql,conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
BindTheGridView();
//or you can use SelectCommand of your SqlDataSource1 and can bind again simply.
}
EDIT:
public void BindTheGridView()
{
SqlConnection conn = new SqlConnection(Connstring);
string sql = "Select * from [UserDB]";
SqlCommand cmd = new SqlCommand(sql, conn);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dtb = new DataTable();
da.Fill(dtb);
conn.Close();
SqlDataSource1.DataSource = dtb;
SqlDataSource1.DataBind();
}
And you can call this for any time to bind the values.

It's wrong to run change operation (DELETE in your example) as a SelectCommand. SelectCommand must be used as it called - only to SELECTs.
Run the DELETE query separately, then run a SELECT command to show the relevant records for the grid.

SqlDataSource1.SelectCommand = "DELETE FROM [UserDB]where Employee like '%"+stid+"%'";
SqlDataSource1.DataBind();
Why are you using Delete query in SelectCommand. The query is open to SqlInjection attack. I would have used a stored procedure and verify the parameter before passing it to the procedure.
Moreover the Grid won't show/bind any data as your code is not return any data back. It is just deleting the data.

I guess you can do a gridview.DataBind() instead of sqlDatasource.databind. The gridviews databind internally performs the sqldatasource databind and also refreshes the gridview.

Related

SQL Select ID from automatically generated rows with C#

Basically whenever i would press a button on my website it would generate some kind of report with the ID and other information. What am trying to do is change one column of the table with SQL statements. I managed to change it but the code changes the column for all the IDs. What am trying to do is change column according to ID, but am still new to C# and SQL so i'm not sure how to get the automatic generated row. Just to highlight that i'm using a button in a gridview to change the value in the column. Below is what i tried:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
string order = Request.QueryString["id"];
SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["RCManiaConnectionString"].ConnectionString;
con.Open();
if (e.CommandName == "received")
{
SqlCommand com = new SqlCommand();
com.Connection = con;
com.CommandText = "UPDATE [Orders] SET Status = 'Received' WHERE [ID] ='" + order + "'";
SqlDataReader data = com.ExecuteReader();
}
}
Using DataKeyNames property of grid view you can pass each record's primary key value, assign the same to the button of the record under CommandArgument. The below code is working code. You can try the same.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"
DataKeyNames="ID" OnRowDataBound="GridView1_RowCommand">
<EmptyDataTemplate>
No Data Found
</EmptyDataTemplate>
<Columns>
<asp:TemplateField HeaderText="Update" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:ImageButton ID="btnUpdate" runat="server" CausesValidation="false" OnClick="btnUpdate_Click" CommandName="Select" ImageUrl="~/Contents/Images/classicPencil.svg" Width="20" Height="20" Text="View" CommandArgument='<%#Eval("ID")%>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
//Using Direct button click event
protected void btnUpdate_Click(object sender, ImageClickEventArgs e)
{
ImageButton btn = sender as ImageButton;
int ID = Convert.ToInt32(btn.CommandArgument);
//Your code of update data process
}
//Using grid row command event.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
int id = Convert.ToInt32(e.CommandArgument.ToString());
//Your code of update data process
}

Asp.Net C# Delete row from dataTable gridview on button click

I'm displaying a datatable that selects a number of elements from the database (IncomingsId, Type, Cost, Frequency) and I'm not sure how to delete a row when a button is clicked.
I've tried many solutions so far but nothing is working.
Here is the button I have within my Grid view
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:button id="DeleteRowButton" text="Delete Record" onclick="DeleteRowButton_Click" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
And here is the code behind this page were I am creating the datatable.
SqlConnection con;
public _Default()
{
con = new SqlConnection(#"MySQLConnection");
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DisplayRecord();
}
}
public DataTable DisplayRecord()
{
string userId = (HttpContext.Current.User.Identity.GetUserId());
SqlDataAdapter Adp = new SqlDataAdapter("select * from Incomings where AspNetUsersId = '" + userId +"'", con);
DataTable Dt = new DataTable();
Dt.AcceptChanges();
Adp.Fill(Dt);
grid1.DataSource = Dt;
grid1.DataBind();
return Dt;
}
public void DeleteRowButton_Click(object sender, EventArgs e)
{
}
Cheers in advance for any help. I'm sure it's a simple resolution
You need a way for your code to know which ID to delete. Here is how I would normally do it:
Replace your button with an ItemTemplate, and add the button in here instead:
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button Text="Delete" runat="server" CommandArgument='<%# Eval("userId") %>' CommandName="Delete" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
When you have the button this way, you now have access to a CommandArgument and CommandName attributes. Notice the argument I am passing is Eval("userId"), the command name (as you will see later) is used to recognize what action you want to execute (this could be anything, is just a name).
Replace the CommandArgument with whatever value(s) you want to pass to the server, using the name that came from the database/datasource (I am guessing it would be userId).
Then, to capture this you need to implement the RowCommand event of the GridView, and intercept the correct CommandName:
public void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
string userId = e.CommandArgument.ToString();
//do something with the id
}
}
Here you have to make sure the CommandName in your button, matches to whatever action you want to execute in the RowCommand. This should do the trick.
Don't forget to bind the event to your GridView:
<asp:GridView OnRowCommand="GridView1_RowCommand" ID="GridView1" runat="server">
...
</asp:GridView>
just use this for the front-end code
<asp:GridView ID="grid1" OnRowDeleting="OnRowDeleting" DataKeyNames="deleteR" runat="server" AutoGenerateColumns="False" CellPadding="4" GridLines="None" style="width:100%" >
<columns>
<asp:TemplateField HeaderText="Delete Row">
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" class="btn btn-primary" Text="Delete" CommandName="Delete" OnRowDataBound="OnRowDataBound" />
</ItemTemplate>
</asp:TemplateField>
And have this in behind it:
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
int deleteR= Convert.ToInt32(grid1.DataKeys[e.RowIndex].Values[0]);
//have a sql statement here that add's the parameter ID for the row you want to delete, something like
SqlCommand com = new SqlCommand ("Delete FROM yourdatabase Where yourID = #yourID"
com.Parameters.AddWithValue("#yourID", yourID)
}
What you're looking for is indeed a simple solution.
You can use a foreach loop to search all DataRows within the DataTable for some kind of ID.Here's an example of what I mean:
String s = "/* IncomingsId for what you want to delete */";
foreach (DataRow r in dt.Rows) {
if (r["IncomingsId"].ToString().Equals(s)) {
dt.Rows.Remove(r);
}
}
Just a quick update for anyone that's helped me, thanks for your advice.
Asp.Net has it's own built in AutoGenerateDeleteButton and I set that to true and ran a bit of code behind it.
A simple solution that really shouldn't have taken me all day to complete!

How do I send email to each user listed in the gridview individually by clicking on the sanction button?

I created a gridview on my approval.aspx page. I am using VS 2014 and SQL Server 2014.
<asp:GridView ID="gv_pending_requests" runat="server" AutoGenerateColumns="False" Width="95%" CellPadding="1" CellSpacing="2">
<Columns>
<asp:BoundField HeaderText="Requested By" DataField="username" />
<asp:BoundField HeaderText="No. of Days" DataField="total_days" />
<asp:BoundField HeaderText="Type of Leave" DataField="leave_type" />
<asp:BoundField HeaderText="Reason" DataField="reason" />
<asp:BoundField HeaderText="Starting" DataField="start_date"/>
<asp:BoundField HeaderText="Ending" DataField="end_date" />
<asp:TemplateField HeaderText="Sanction">
<ItemTemplate>
<asp:Button ID="btn_apprv" Text="Sanction" runat="server" OnClick="btn_apprv" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Deny">
<ItemTemplate>
<asp:Button ID="btn_deny" Text="Deny" runat="server" OnClick="btn_deny"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
//Now, the code from .cs file:
lbl_uid.Text = Convert.ToString(Session["Username"]);
string connectionstring = #"Data Source=server;Integrated Security=true Initial Catalog=E_M_S";
SqlDataReader rdr;
DataTable dt = new DataTable();
dt.Columns.Add("Requested By");
dt.Columns.Add("Type of Leave");
dt.Columns.Add("Reason");
dt.Columns.Add("Starting");
dt.Columns.Add("Ending");
dt.Columns.Add("No. of Days");
DataRow dr;
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand("select leave_type,reason,start_date,end_date from Leave where status='" + lbl_status.Text + "'", conn);
cmd.CommandType = CommandType.Text;
using (conn)
{
conn.Open();
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
dr = dt.NewRow();
dr["Requested By"] = rdr["username"].ToString();
dr["Type of Leave"] = rdr["leave_type"].ToString();
dr["Reason"] = rdr["reason"].ToString();
dr["Starting"] = rdr["start_date"].ToString();
dr["Ending"] = rdr["end_date"].ToString();
dr["No. of Days"] = rdr["total_days"].ToString();
dt.Rows.Add(dr);
dt.AcceptChanges();
gv_pending_requests.DataSource = dt;
gv_pending_requests.DataBind();
conn.Close();
}
}
//Button for sending the E-Mail
protected void btn_apprv(object sender, EventArgs e)
{
Response.Write("<script type='javascript'>alert('The leave has been sanctioned, and mail has been sent to inform the employee of the same.');</script>");
}
Problem1 : It shows below error pointing at the line :- gv_pending_requests.DataSource = dt;
"a field or property with the name 'username' was not found on the selected data source"
Problem 2: I want that a mail be sent to each user according to the button pressed for that row. How do i define an on click event with that mail code?
Please forgive me for missing details,if any. Please help me with this error.
To your Problem 1:
In your SQL-Select-Statement you don't select for the username:
SqlCommand cmd = new SqlCommand("select leave_type,reason,start_date,end_date from Leave where status='" + lbl_status.Text + "'", conn);
Instead this code should be:
SqlCommand cmd = new SqlCommand("select username,leave_type,reason,start_date,end_date from Leave where status='" + lbl_status.Text + "'", conn);
Otherwise - as stated by the errormessage - the DataReader you use cannot find the column username in the result from the database.
You can test this if you go to your database and fire the SQL-statement there directly, you will see that you do not get the usernames back.
Also, you defined your DataTable with the column Requested by.
dt.Columns.Add("Requested By");
But if you look to your BoundField now, you will see that the DataField is defined as "username":
<asp:BoundField HeaderText="Requested By" DataField="username" />
Either you change the column-name in your DataTable to "username" or you change the DataField in the BoundField to "Requested By".
To your second Problem:
Please read the How-To-Ask-FAQ:
Include just enough code to allow others to reproduce the problem. For
help with this, read How to create a Minimal, Complete, Valid Example.
You don't provide any research or a minimal example which shows us that you at least tried to find a solution.
So I will only give you hints for your "problem", if you got any question then regarding a not working code, please post a new question.
Get Cell Value in C# Gridview when Button clicked on row
How to send email in ASP.NET C#
Use the first link to get the user where the E-Mail should be sent to, and the second link provides the logic to send a E-Mail. Good luck!

Unable to Fire onItemCommand event

I am unable to guess the issue here , as the event of grid item command is not executing .I also changes the pageevent validation state but of no use.
I am pasting .aspx code as well as
The grid is binded perfectly
<telerik:RadGrid ID="frds" runat="server" OnItemCommand="go_frd" AutoGenerateColumns="false" >
<MasterTableView>
<Columns>
<telerik:GridTemplateColumn>
<ItemTemplate>
<asp:Button ID="bt" runat="server" CommandArgument='<%#Eval("frd_ID") %>' Text="test" />
</ItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
The event is this
protected void go_frd(object o, GridCommandEventArgs e)
{
if (e.CommandName == "frd_go")
{
Response.Redirect("Profiling.aspx?uid=" + e.CommandArgument);
}
if (e.CommandName == "add_frd")
{
db_accessDataContext db = new db_accessDataContext();
Frd_request req = new Frd_request();
db.AddFriend(Int64.Parse(cur_mem_id), Int64.Parse(e.CommandArgument.ToString()));
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("dbo.addFriend", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(#"memID", Int64.Parse(cur_mem_id));
cmd.Parameters.Add(#"frdID", Int64.Parse(e.CommandArgument.ToString()));
try
{
con.Open();
cmd.ExecuteNonQuery();
}
catch (Exception ex) { }
}
}
I tried many approaches but unable to fire the event for button in grid
I checked it by putting a break point as well ,the trouble is it don't even start execution of the event
Binding COde
string query = "my query containing the frd_id ,works fine in query builder and it also is shown grid view ";
try { SqlConnection con = new SqlConnection(connectionString);
SqlDataAdapter adapter = new SqlDataAdapter(query, con);
adapter.Fill(d0); con.Close();
} catch (Exception ex) { }
frds.DataSource = d0;
frds.DataBind();
You need to set the CommandName:
<asp:Button ID="bt" runat="server"
CommandName="frd_go"
CommandArgument='<%#Eval("frd_ID") %>' Text="test" />
I had a similar issue today.
In my radgrid I had the code to build the sql and populate the radgrid in the page_load event, but I forgot to add
if (!IsPostBack) { }
around this code, so on every page load the grid was being rebuilt and the onitemcommand method was not working. The page seemed to be was posting back on button click or rowclick, but the event was just not firing. Try adding the if (!isPostback) code around your databinding and you might find it works for you.
You will need to set EnablePostBackOnRowClick property to true for ClientSettings. However this will cause a full post back.
.
.
.
</MasterTableView>
<ClientSettings EnablePostBackOnRowClick="true">
</ClientSettings>
</telerik:RadGrid>
You may want to check this thread on Telerik forums

set checkbox in gridview based on datatable value

I have a gridview control with a checkbox field and several bound fields. The checkbox field does not directly map to a field in the database. Rather, i want to read a value from a field in the database and "check" some of the checkboxes.
For example, given the following data from the database -> datatable
PROCESSED NAME DATE
Y Mickey Mouse 11/15/2011
N Donald Duck 4/01/2012
Y James Bond 5/02/2011
I would like the gridview to display a checkbox and set the value of boxes to UNCHECKED where PROCESSED = N and for PROCESSED = Y either have an uneditable checkbox or no checkbox at all.
PROCESSED NAME DATE
[/] Mickey Mouse 11/15/2011
[ ] Donald Duck 4/01/2012
[/] James Bond 5/02/2011
To populate the gridview, a SQL stmt is run against a database, and the result of the SQL query is stored in a datatable. Before binding the datatable to the gridview, i would like to check the "processed" field and set the checkbox based on that value.
Here is the gridview control (shortened for clarity):
<asp:GridView ID="gridview_all_applicants" runat="server" AllowPaging="True">
<Columns>
<asp:TemplateField HeaderText="Complete">
<ItemTemplate>
<asp:CheckBox ID="process_flag" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="lastname" HeaderText="Last Name" ReadOnly="True" SortExpression="lastname" />
Here is what i have so far in the code behind
SqlCommand cmd = new SqlCommand(sql query here);
SqlDataAdapter da = new SqlDataAdapter();
DataTable dt = new DataTable();
da.SelectCommand = cmd;
// Save results of select statement into a datatable
da.Fill(dt);
foreach (DataRow r in dt.Rows)
{
// do some processing of data returned from query
// read the char value from the returned data and set checkbox
procflag = r["process_flag"].ToString().ToLower();
CheckBox chkbox = new CheckBox();
if (procflag == null || procflag == "n")
{
// SET CHECKBOX TO "NOT CHECKED"
}
else
{
// SET CHECKBOX TO "CHECKED" AND MAKE IT UNCLICKABLE
// ----OR---- DO NOT DISPLAY CHECKBOX AT ALL.
}
} // end for each
gridview_all_applicants.DataSource = dt;
gridview_all_applicants.DataBind();
any help is greatly appreciated.
You can do it like this:
First in sql server:
SELECT
CAST(CASE PROCESSED WHEN 'Y' THEN 1 ELSE 0 END AS BIT) AS PROCESSED
NAME
DATE
FROM ExampleTable
in c# code:
SqlCommand cmd = new SqlCommand(sql query here);
SqlDataAdapter da = new SqlDataAdapter();
DataTable dt = new DataTable();
da.SelectCommand = cmd;
// Save results of select statement into a datatable
da.Fill(dt);
gridview_all_applicants.DataSource = dt;
gridview_all_applicants.DataBind();
and finally in aspx:
<asp:TemplateField HeaderText="Complete">
<ItemTemplate>
<asp:CheckBox ID="process_flag" runat="server" Checked='<%# bool.Parse(Eval("PROCESSED").ToString()) %>' Enable='<%# !bool.Parse(Eval("PROCESSED").ToString()) %>'/>
</ItemTemplate>
How about a database agnostic solution, just on the off chance you are using a non sqlserver database ;)
<asp:CheckBox ID="process_flag_check" runat="server"
Checked='<%# Eval("process_flag").ToString() == "Y" ? "True": "False" %>'
Enabled="false"/>
</asp:Content>
<asp:CheckBox ID="process_flag_check" runat="server"
Checked='<%# bool.Parse(Eval("process_flag").ToString() == "Y" ? "True": "False") %>'
Enabled="false"/>
</asp:CheckBox>
This one Perfectly Works.I have modified using Kevin and marco Code.
Thank u Kevinv and Marco

Categories