Session Variables not being seen/used - c#

I have an aspx page that displays a gridview of questions waiting on review with 10 questions shown per page. If a question is selected it is opened in a new page where the reviewer can either submit a review or cancel and return to the list of questions needing review.
Currently this works fine, but have a request from the reviewers so that if they are on page 4 of the gridview when they go to a question, they get returned to page 4 if they hit cancel and return to the list of questions (currently they are returned to page 1).
So I am setting a couple session variables to capture the question selected and to capture the pageindex of the gridview control for future use. Trying to use the session variable for the questionId on the page load of the detail page, but it is not being passed. On returning to the Review List page the pageindex that is being set on the gridview is always 0, not the session variable.
Updated Gridview control (note two controls, one hyperlink(which should go away once the other linkbutton control works):
<asp:GridView ID="GridView1" runat="server" Caption="Questions Awaiting Review" AllowSorting="True" PagerSettings-Mode="NumericFirstLast" OnPageIndexChanging="GridView1_PageIndexChanging"
CaptionAlign="Top" EmptyDataText="No Questions Pending Review." PageSize="10" AllowPaging="true" PagerStyle-HorizontalAlign="Center" PagerStyle-Font-Size="Large" DataKeyNames="QuestionID"
AutoGenerateColumns="false" AlternatingRowStyle-BackColor="#cccccc">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="QuestionID" runat="server" Text='<%# Eval("QuestionID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="KeyObjective" HeaderText="Key Objective" ItemStyle-Width="250" />
<asp:BoundField DataField="SubmitDate" HeaderText="Submitted Date" ItemStyle-Width="60" />
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="Details" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") +"&PageIndex=" + GridView1.PageIndex %>'>View Question</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Details2" runat="server" Text="Session" OnClick="Session_OnClick"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
OnClick Event for the second button:
protected void Session_OnClick(object sender, EventArgs e)
{
Session["PageIndex"] = GridView1.PageIndex;
Session["QuestionId"] = GridView1.SelectedDataKey;
Response.Redirect("~/Review/ReviewDetail.aspx", false;
}
Connection string on the detail page which is now not getting a value for the parameter "QuestionID"; ):
SqlCommand command = new SqlCommand("QuestionDetail", Conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#QuestionID", SqlDbType.BigInt));
command.Parameters["#QuestionID"].Value = Convert.ToInt64(Session["QuestionId"]);
Conn.Open();
SqlDataReader reader = command.ExecuteReader();
PageLoad and gridview binding on the ReviewList page that should be using session variable to set page of grid control, but is always going to default of page 0:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bindGridView();
}
else
{
if (Convert.ToInt32(Session["PageIndex"]) !=0)
{
GridView1.PageIndex = Convert.ToInt32(Session["PageIndex"]);
bindGridView();
}
}
}
private void bindGridView()
{
string connectionString = WebConfigurationManager.ConnectionStrings["CS1"].ConnectionString;
string selectSQL = String.Format("Select QuestionID, KeyObjective, SubmitDate from Questions where Author <> '{0}' and QuestionID not in(Select QuestionID from Review where Reviewer = '{0}')", User.Identity.Name);
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(selectSQL, con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds, "Review");
GridView1.DataSource = ds;
GridView1.DataBind();
}

Your error probably means that Request["Id"] is empty or does not exists. Always check if QueryStrings exist and do the conversions of user inputs that are likely to fail inside a try-catch block.
protected void Page_Load(object sender, EventArgs e)
{
long QuestionID = -1;
//check if the Id QueryString exists
if (Request.QueryString["Id"] != null)
{
//try to convert to int64
try
{
QuestionID = Convert.ToInt64(Request.QueryString["Id"]);
}
catch
{
}
}
//if valid QuestionID
if (QuestionID >= 0)
{
using (SqlConnection connection = new SqlConnection(Common.connectionString))
using (SqlCommand command = new SqlCommand("QuestionDetail", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#QuestionID", SqlDbType.BigInt).Value = QuestionID;
//try to execute the stored procedure
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//handle sql error
Literal1.Text = ex.Message;
}
}
}
}
And why do you do a PostBack on the first button? That is not needed just to redirect to a different url. Change it to:
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") %>'>View Question</asp:HyperLink>
Or with the Page Index also in the QueryString:
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") + "&Page=" + GridView2.PageIndex %>'>View Question</asp:HyperLink>
UPDATE
If you really want to do a PostBack to set the Sessions you can use the OnRowCommand:
<asp:LinkButton ID="LinkButton1" CommandArgument='<%# Eval("QuestionID") %>' runat="server" CommandName="viewQuestion">View Question</asp:LinkButton>
CS
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "viewQuestion")
{
Session["PageIndex"] = GridView1.PageIndex;
Session["QuestionId"] = e.CommandArgument.ToString();
Response.Redirect("~/Review/ReviewDetail.aspx?Id=" + Convert.ToString(Session["QuestionId"]));
}
}

Related

Skip row in gridview asp.net

I have a gridview showing academy name and a dropdown list. The dropdown list have value of 0-13, 0 is the "Please select option". I want when the save button it skip those row where there is no selection in the dropdown therefore 0.
Here is my code for the gridview:
<asp:GridView ID="gdvAcadSelec" runat="server" AutoGenerateColumns="False"
DataKeyNames="acad_Id"
DataSourceID="srcAcademy"
OnRowDataBound="gdvAcadSelec_RowDataBound"
CssClass="table table-striped table-bordered"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="acad_Id" HeaderText="Id" />
<asp:BoundField DataField="acad_name" HeaderText="Academy" />
<asp:TemplateField HeaderText="Choice">
<ItemTemplate>
<asp:DropDownList ID="ddlPref" OnTextChanged="ddlPref_TextChanged" AutoPostBack="true" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="btnsubmit" CssClass="btn btn-info" OnClick="btnsubmit_Click" runat="server" Text="Submit" />
<asp:ObjectDataSource ID="srcAcademy"
TypeName="dataAccessLayer"
SelectMethod="getAcademy"
runat="server" />
The code behind for the binding of item for the column Choice:
protected void gdvAcadSelec_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Find the DropDownList in the Row
DropDownList ddlCountries = (e.Row.FindControl("ddlPref") as DropDownList);
ddlCountries.Items.Insert(0, new ListItem("Please select"));
ddlCountries.Items.Insert(1, new ListItem("1"));
ddlCountries.Items.Insert(2, new ListItem("2"));
ddlCountries.Items.Insert(3, new ListItem("3"));
ddlCountries.Items.Insert(4, new ListItem("4"));
ddlCountries.Items.Insert(5, new ListItem("5"));
ddlCountries.Items.Insert(6, new ListItem("6"));
ddlCountries.Items.Insert(7, new ListItem("7"));
ddlCountries.Items.Insert(8, new ListItem("8"));
ddlCountries.Items.Insert(9, new ListItem("9"));
ddlCountries.Items.Insert(10, new ListItem("10"));
ddlCountries.Items.Insert(11, new ListItem("11"));
ddlCountries.Items.Insert(12, new ListItem("12"));
ddlCountries.Items.Insert(13, new ListItem("13"));
}
On click save button:
protected void btnsubmit_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in gdvAcadSelec.Rows)
{
DropDownList ddlorder = (DropDownList)row.FindControl("ddlPref");
string acadID = row.Cells[0].Text;
string order = ddlorder.SelectedValue.ToString();
SqlCommand scmd = new SqlCommand();
scmd.CommandType = CommandType.Text;
scmd.CommandText = "Insert into tblAcademy_Selection (acad_Id,stud_Id,order_preference) values (#acad,#stud,#order)";
scmd.Connection = con;
scmd.Parameters.AddWithValue("#acad", acadID);
scmd.Parameters.AddWithValue("#stud", 60);
scmd.Parameters.AddWithValue("#order", order);
con.Open();
scmd.ExecuteNonQuery();
con.Close();
}
}
The problem with this code is when it is saving to the database ,those dropdowns list who have value "please select" is also being save and this crash my website.
What can I do to skip those dropdown that do not have value selected?
Thank you in advance.
(Edited per request from OP)
Simply use an if() statement to skip the values you don't want to insert.
string order = ddlorder.SelectedIndex.ToString();
if (order != "0") { // Some may argue that it should be !order.equals("0") but in C# it doesn't matter.
SqlCommand scmd = new SqlCommand();
scmd.CommandType = CommandType.Text;
.
.
}
And if you're a prudent (and paranoid) programmer, you won't trust anything sent from the browser, you'll check to make sure the variable order is the appropriate type and is within the range of values you expect as well.

LinkButton Redirection with Query String

I'm trying to make some simple code to increate a number in a DataBase with a repeater onitemcommand that sends a id & a commandname.
The code to increase the int in the Database works fine, but when I then try to add a redirection to "The Article page" where you can read the whole article.
So my question how can I redirect with a LinkButton & make Query Strings in the redirection as shown below in a <a> (HTML5) tag inside the linkbutton // If I add the <a> (HTML5) tag it doesn't update the int in database // if I remove the <a> (HTML5) tag it will update the database int but won't redirect with the Query Strings.
<asp:Repeater ID="Repeater_Frontpage" OnItemCommand="Repeater_Frontpage_ItemCommand" DataSourceID="SqlDataSource1" runat="server">
<ItemTemplate>
<asp:LinkButton CommandName="Visit" CommandArgument='<%# Eval("news_id") %>' runat="server">Read More</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
protected void Repeater_Frontpage_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Visit")
{
SqlConnection conn = new SqlConnection(Helpers.ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
int userId = int.Parse(e.CommandArgument.ToString());
cmd.CommandText = "UPDATE News SET news_visits = news_visits + 1 WHERE news_id =" + userId;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
You can set ItemIndex as a CommandArgument
CommandArgument='<%# Container.ItemIndex %>'
And then you can get the row from the Repeater DataSource
protected void repeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Visit")
{
var rowIndex = (int)e.CommandArgument;
//Here I am assuming that your data source is a DataTable
var row = ((DataTable)repeater.DataSource).Rows[0];
var newsID = row.Field<int>("newsID");
var categoriesID = row.Field<int>("fk_categories_id");
Response.Redirect($"Article.aspx?category_id={categoriesID}& amp;news_id={categoriesID}");
Response.Write($"Do something with {e.CommandArgument}");
}
}

Populating Gridview inside Listview ItemTemplate On Web User Control from Code Behind

I have what I think is a simple question, however it might be more complex..
I have spent a few days looking for the answer on google and various questions on this site but cannot seem to come right.
What I am trying to do is to bind to a Gridview on the User Control ascx page from the Default.aspx.cs on the Page Load event.
User Control markup is as follows:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="VulnerabilityExternalIP.ascx.cs" Inherits="VulnerabilityAssesment.Controls.VulnerabilityExternalIP" %>
<asp:Table runat="server" CellPadding="1" CellSpacing="2">
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityName" runat="server" Text="Vulnerability Name:" CssClass="itemName"></asp:Label>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityNameText" runat="server" Text='<%# Eval("MainVulnerabilityName") %>'></asp:Label>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityCategory" runat="server" Text="Category:" CssClass="itemName"></asp:Label>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityCategoryText" runat="server" Text='<%# Eval("Category") %>'></asp:Label>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityPopularity" runat="server" Text="Popularity:" CssClass="itemName"></asp:Label>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityPopularityText" runat="server" Text='<%# Eval("Popularity") %>'></asp:Label>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityRisk" runat="server" Text="Risk:" CssClass="itemName"></asp:Label>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="blVulnerabilityRiskText" runat="server" Text='<%# Eval("RiskFactor") %>'></asp:Label>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
<br />
<asp:Label ID="lblHostsAffected" runat="server" Text="Hosts Affected:" CssClass="itemName"></asp:Label>
<br />
<asp:TextBox ID="txtHostsAffected" runat="server" TextMode="MultiLine" Width="700px" ReadOnly="true" BroderWidth="0px" Text='<%# Eval("HostNamePort") %>'></asp:TextBox>
<asp:GridView ID="gvHostsAffected" runat="server" AutoGenerateColumns="False" AutoGenerateEditButton="True">
</asp:GridView>
I am referencing the User Control on the Default.aspx as follows:
<%# Register Src="~/Controls/VulnerabilityExternalIP.ascx" TagName="VulnerabilityExternalIP" TagPrefix="uc1" %>
Within the default.asxp I have the following defined:
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:ListView ID="lvVulnerabilityExternalIP" runat="server">
<ItemTemplate>
<uc1:VulnerabilityExternalIP Template="<%# Container.DataItem %>" runat="server" ID="vulnerabilityExtIP" name="vulnext" />
</ItemTemplate>
</asp:ListView>
</asp:Content>
The code behind on Default.aspx.cs is as follows:
namespace VulnerabilityAssesment
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
string HostNamePort = "";
string VulnerabilityDesc = "";
string VulnerabilitySummary = "";
string VulnerabilitySolution = "";
string VulnerabilityCVE = "";
string VulnerbilityLink = "";
// Use connection string from Web.Config
string connection = ConfigurationManager.ConnectionStrings["csVulnerabilityAssesment"].ConnectionString;
//Create new SQL Connection
SqlConnection conn = new SqlConnection(connection);
//Create Stored Procedure Command and Declare Parameters
SqlCommand vulnerabilityHeader = new SqlCommand("[dbo].[_spGet_VulnerabilityHeader]", conn);
vulnerabilityHeader.CommandType = CommandType.StoredProcedure;
vulnerabilityHeader.Parameters.Add("#VulnerabilityReport", SqlDbType.VarChar).Value = "External IP Ranges";
//Create Data Adapter and Data Set
SqlDataAdapter sdaVulnerabilityHeader = new SqlDataAdapter(vulnerabilityHeader);
DataSet dsVulnerabilityHeader = new DataSet();
//Open Connection
conn.Open();
//Fill Data Adapter
sdaVulnerabilityHeader.Fill(dsVulnerabilityHeader);
//Fill in template
List<VulnerabilityTemplate> Template = new List<VulnerabilityTemplate>();
if (dsVulnerabilityHeader.Tables != null)
if (dsVulnerabilityHeader.Tables[0].Rows.Count == 0)
{
}
else
if (dsVulnerabilityHeader.Tables.Count > 0)
{
foreach (DataRow dr in dsVulnerabilityHeader.Tables[0].Rows)
{
string GroupID = dr["GroupSequence"].ToString();
//Declare Stored Procedue for Vulnerability Details and set Parameters
SqlCommand vulnerabilityDetail = new SqlCommand("[dbo].[_spGet_VulnerabilityDetail]", conn);
vulnerabilityDetail.CommandType = CommandType.StoredProcedure;
vulnerabilityDetail.Parameters.Add("#VulnerabilityReport", SqlDbType.VarChar).Value = "External IP Ranges";
vulnerabilityDetail.Parameters.Add("#GroupSequence", SqlDbType.VarChar).Value = GroupID;
// Declare SQL Data Adapter for Vulnerability Detail
SqlDataAdapter sdaVulnerabilityDetail = new SqlDataAdapter(vulnerabilityDetail);
DataSet dsVulnerabilityDetail = new DataSet();
// Fill Data Adapter
sdaVulnerabilityDetail.Fill(dsVulnerabilityDetail);
// Declare Stored Procedure for Vulnerability Summary and Set Paramters
SqlCommand vulnerabilitySummary = new SqlCommand("[dbo].[_spGet_VulnerabilitySummary]", conn);
vulnerabilitySummary.CommandType = CommandType.StoredProcedure;
vulnerabilitySummary.Parameters.Add("#VulnerabilityReport", SqlDbType.VarChar).Value = "External IP Ranges";
vulnerabilitySummary.Parameters.Add("#GroupSequence", SqlDbType.VarChar).Value = GroupID;
// Declare SQL Data Adapter for Vulnerability Detail
SqlDataAdapter sdaVulnerabilitySummary = new SqlDataAdapter(vulnerabilitySummary);
DataSet dsVulnerabilitySummary = new DataSet();
// Fill Data Adapter
sdaVulnerabilityDetail.Fill(dsVulnerabilityDetail);
sdaVulnerabilitySummary.Fill(dsVulnerabilitySummary);
foreach (DataRow row in dsVulnerabilityDetail.Tables[0].Rows)
{
if (HostNamePort != "")
HostNamePort += Environment.NewLine;
HostNamePort += row["HostnamePort"].ToString();
}
foreach (DataRow vulnerabilitySummaryRow in dsVulnerabilitySummary.Tables[0].Rows)
{
VulnerabilityDesc += vulnerabilitySummaryRow["VulnerabilityDesc"].ToString();
VulnerabilitySummary += vulnerabilitySummaryRow["VulnerabilitySummary"].ToString();
VulnerabilitySolution += vulnerabilitySummaryRow["VulnerabilitySolution"].ToString();
}
//myGrid.DataSource = dsVulnerabilityDetail.Tables[0];
//GridView myGrid = (GridView)lvVulnerabilityExternalIP.Items.FindControl("gvHostsAffected");
// Always returns null :(
GridView myGrid = (GridView)lvVulnerabilityExternalIP.FindControl("gvHostsAffected");
Template.Add(new VulnerabilityTemplate
{
MainVulnerabilityName = dr["MainVulnerabilityName"].ToString(),
Category = dr["Category"].ToString(),
Popularity = dr["Popularity"].ToString(),
Riskfactor = dr["RiskFactor"].ToString(),
HostNamePort = HostNamePort
//VulnerabilityDesc = VulnerabilityDesc,
//VulnerabilitySolution = VulnerabilitySolution,
//VulnerabilitySummary = VulnerabilitySummary
}
);
myGrid.DataBind();
}
}
lvVulnerabilityExternalIP.DataSource = Template;
lvVulnerabilityExternalIP.DataBind();
conn.Close();
}
// Below Does not work
protected void ListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
DataTable table = (DataTable)e.Item.DataItem;
GridView myGrid = (GridView)e.Item.FindControl("gvHostsAffected");
myGrid.DataSource = table;
myGrid.DataBind();
}
}
}
}
I cannot seem to find the gvHostsAffected grid view to bind it to the dsVulnerabilityDetail.Tables[0] value (which should be a single column called HostsAffected, this result could return 1 or more rows.
I have included two things that I have tried denoted by the comment //Below does not work.
The Template.Add method does work and it populates necessary information on the user control.
Is there any way I can find the Gridview control during the iteration and populate it with the results from the dsVulnerabilityDetail data set?
Thank you in advance.
Update 10 April 2017
Below is the Code Behind for the WebControl, I see I forgot to include it in the original Question.
namespace VulnerabilityAssesment.Controls
{
public partial class VulnerabilityExternalIP : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public GridView myGridView
{
get
{
return gvHostsAffected;
}
set
{
gvHostsAffected = value;
}
}
}
}
The markup for Web Control include the answer by VDWWD.
First, add a public GridView property to the User Control
public partial class WebUserControl1 : System.Web.UI.UserControl
{
public GridView myGridView
{
get
{
return GridView1;
}
set
{
GridView1 = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
Then you can access it like yo would a GridView on the same page. The only thing left to do is to use FindControl to find the User Control inside the ListView
protected void Button1_Click(object sender, EventArgs e)
{
WebUserControl1 control = lvVulnerabilityExternalIP.Items[2].FindControl("vulnerabilityExtIP") as WebUserControl1;
control.myGridView.DataSource = mySource;
control.myGridView.DataBind();
}

Why am I receiving "Input string not in correct format" while retreiving Gridview row index

I am receiving the error "Input string was not in a correct format" on the line:
int index = Convert.ToInt32(e.CommandArgument);
My goal is to get the ID (both letters and numbers) from my Gridview (Cell 1 of the selected row), for processing the records in the DB associated with that ID.
Most of the pages that I found said to use the above code to find the row number for gridview.
My aspx page:
<asp:gridview ID="gridview1" runat="server" DataKeyNames="ID" AutoGenerateColumns="false" OnRowCommand="gridview1_RowCommand">
<columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="btn_select" runat="server" Text="Select" CommandName="Select" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Record_ID" DataField="ID" />
<asp:BoundField HeaderText="Record_Date" DataField="Date" />
</Columns>
</asp:gridview>
My Code Behind:
SqlCommand cmd = new SqlCommand();
protected void Page_Load(object sender, EventArgs e)
{
//code stuff
final();
}
protected void final()
{
//code stuff for populating the gridview. Gridview populates as expected.
}
protected void gridview1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
int index = Convert.ToInt32(e.CommandArgument);//where I receive the error.
string id = gridview1.Rows[index].Cells[1].Text;
using (SqlConnection connection string)
{
try
{
cmd = new SqlCommand("DBSP", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#id", SqlDbType.Char).Value = id;
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
final();
}
catch (Exception ex)
{
//code stuff
}
}
}
}
A couple of other things I have tried are from:
Accessing GridView Cells Value
How to get cell value in GridView (WITHOUT using cell index)
Get the cell value of a GridView row
Getting value from a Gridview cell
as well as others.
You should assign the ID value to the CommandArgument of the LinkButton:
<asp:LinkButton ... CommandName="Select" CommandArgument='<%# Eval("ID") %>' />
The following line would give you the ID value, without having to get the text of the cell:
string ID = e.CommandArgument.ToString();
Alternatively, you could use the DataKeys to retrieve the ID value:
protected void gridview1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
GridViewRow row = (e.CommandSource as Control).NamingContainer as GridViewRow;
string ID = gridView1.DataKeys[row.RowIndex].Values["ID"].ToString();
...
}
}

How to delete row in gridview using rowdeleting event?

This is my .cs code :
protected void Gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
Gridview1.DeleteRow(e.RowIndex);
Gridview1.DataBind();
}
and this is markup,
<asp:gridview ID="Gridview1" runat="server" ShowFooter="true"
AutoGenerateColumns="false" OnRowDeleting="Gridview1_RowDeleting">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Column Name">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<%-- <asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>--%>
<asp:TemplateField HeaderText="Data Type">
<ItemTemplate>
<asp:DropDownList ID="ddldatatype" runat="server">
<asp:ListItem>varchar</asp:ListItem>
<asp:ListItem>int</asp:ListItem>
<asp:ListItem>numeric</asp:ListItem>
<asp:ListItem>uniqueidentifier</asp:ListItem>
<asp:ListItem>char</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row" OnClick="ButtonAdd_Click"/>
<asp:Button ID="ButtonDel" runat="server" Text="Delete Row" OnClick="ButtonDel_Click" />
<input type="hidden" runat="server" value="0" id="hiddencount" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkdelete" runat="server" CommandName="Delete" >Delete</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
Please sugegest me. I have done this much.. but still not deleting row...
protected void Gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//Gridview1.DeleteRow((int)Gridview1.DataKeys[e.RowIndex].Value);
//Gridview1.DeleteRow(e.RowIndex);
//Gridview1.DataBind();
foreach(DataRow dr in dt.Rows)
{
dt.Rows.Remove(dr);
dt.Rows[e.RowIndex].Delete();
}
Gridview1.DeleteRow(e.RowIndex);
// dt = (DataTable)Gridview1.DataSource;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
GridViewRow row = (GridViewRow)GridView1.Rows[e.RowIndex];
SqlCommand cmd = new SqlCommand("Delete From userTable (userName,age,birthPLace)");
GridView1.DataBind();
}
Make sure to create a static DataTable object and then use the following code:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
dt.Rows.RemoveAt(e.RowIndex);
GridView1.DataSource = dt;
GridView1.DataBind();
}
Try This Make sure You mention Datakeyname which is nothing but the column name (id) in your designer file
//your aspx code
<asp:GridView ID="dgUsers" runat="server" AutoGenerateSelectButton="True" OnDataBound="dgUsers_DataBound" OnRowDataBound="dgUsers_RowDataBound" OnSelectedIndexChanged="dgUsers_SelectedIndexChanged" AutoGenerateDeleteButton="True" OnRowDeleting="dgUsers_RowDeleting" DataKeyNames="id" OnRowCommand="dgUsers_RowCommand"></asp:GridView>
//Your aspx.cs Code
protected void dgUsers_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int id = Convert.ToInt32(dgUsers.DataKeys[e.RowIndex].Value);
string query = "delete from users where id= '" + id + "'";
//your remaining delete code
}
Your delete code looks like this
Gridview1.DeleteRow(e.RowIndex);
Gridview1.DataBind();
When you call Gridview1.DataBind() you will populate your gridview with the current datasource. So, it will delete all the existent rows, and it will add all the rows from CustomersSqlDataSource.
What you need to do is delete the row from the table that CustomersSqlDataSource querying.
You can do this very easy by setting a delete command to CustomersSqlDataSource, add a delete parameter, and then execute the delete command.
CustomersSqlDataSource.DeleteCommand = "DELETE FROM Customer Where CustomerID=#CustomerID"; // Customer is the name of the table where you take your data from. Maybe you named it different
CustomersSqlDataSource.DeleteParameters.Add("CustomerID", Gridview1.DataKeys[e.RowIndex].Values["CustomerID"].ToString());
CustomersSqlDataSource.Delete();
Gridview1.DataBind();
But take into account that this will delete the data from the database.
The easiest way is to create your GridView with some data source in ASP and call that data source in Row_Deletinng Event. For example if you have SqlDataSource1 as your GridView data source, your Row_Deleting event would be:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int ID = int.Parse(GridView1.Rows[e.RowIndex].FindControl("ID").toString());
string delete_command = "DELETE FROM your_table WHERE ID = " + ID;
SqlDataSource1.DeleteCommand = delete_command;
}
See the following code and make some changes to get the answer for your question
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void CustomersGridView_RowDeleting
(Object sender, GridViewDeleteEventArgs e)
{
TableCell cell = CustomersGridView.Rows[e.RowIndex].Cells[2];
if (cell.Text == "Beaver")
{
e.Cancel = true;
Message.Text = "You cannot delete customer Beaver.";
}
else
{
Message.Text = "";
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>GridView RowDeleting Example</title>
</head>
<body>
<form id="form1" runat="server">
<h3>
GridView RowDeleting Example
</h3>
<asp:Label ID="Message" ForeColor="Red" runat="server" />
<br />
<asp:GridView ID="CustomersGridView" runat="server"
DataSourceID="CustomersSqlDataSource"
AutoGenerateColumns="False"
AutoGenerateDeleteButton="True"
OnRowDeleting="CustomersGridView_RowDeleting"
DataKeyNames="CustomerID,AddressID">
<Columns>
<asp:BoundField DataField="FirstName"
HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="City" HeaderText="City"
SortExpression="City" />
<asp:BoundField DataField="StateProvince" HeaderText="State"
SortExpression="StateProvince" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="CustomersSqlDataSource" runat="server"
SelectCommand="SELECT SalesLT.CustomerAddress.CustomerID,
SalesLT.CustomerAddress.AddressID,
SalesLT.Customer.FirstName,
SalesLT.Customer.LastName,
SalesLT.Address.City,
SalesLT.Address.StateProvince
FROM SalesLT.Customer
INNER JOIN SalesLT.CustomerAddress
ON SalesLT.Customer.CustomerID =
SalesLT.CustomerAddress.CustomerID
INNER JOIN SalesLT.Address ON SalesLT.CustomerAddress.AddressID =
SalesLT.Address.AddressID"
DeleteCommand="Delete from SalesLT.CustomerAddress where CustomerID =
#CustomerID and AddressID = #AddressID"
ConnectionString="<%$ ConnectionStrings:AdventureWorksLTConnectionString %>">
<DeleteParameters>
<asp:Parameter Name="AddressID" />
<asp:Parameter Name="CustomerID" />
</DeleteParameters>
</asp:SqlDataSource>
</form>
</body>
</html>
In Grid use this code having ID as your Primary Element so to uniquely identify each ROW
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="Hf_ID" runat="server" Value='<%# Eval("ID") %>' />
</ItemTemplate>
</asp:TemplateField>
and to search the uique ID use the code in C# code behind (basically this is searching hidden field and storing it in a var)
protected void Grd_Registration_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
var ID = (HiddenField)Grd_Registration.Rows[e.RowIndex].FindControl("ID");
//Your Delete Logic Goes here having ID to delete
GridBind();
}
The solution is somewhat simple; once you have deleted the row from the datagrid (Your code ONLY removes the row from the grid and NOT the datasource) then you do not need to do anything else.
As you are doing a databind operation immediately after, without updating the datasource, you are re-adding all the rows from the source to the gridview control (including the row removed from the grid in the previous statement).
To simply delete from the grid without a datasource then just call the delete operation on the grid and that is all you need to do... no databinding is needed after that.
Add the below line in Page load,
ViewState["GetRecords"] = dt;
then try this,
protected void DeleteRows(object sender, GridViewDeleteEventArgs e)
{
dt = ViewState["GetRecords"] as DataTable;
dt.Rows.RemoveAt(e.RowIndex);
dt.AcceptChanges();
ViewState["GetRecords"] = dt;
BindData();
}
If you Still have any problem, send the code in BindData() method
I think you are doing same mistake of rebinding as mentioned in this link
How to delete row from gridview?
If I remember from your previous questions, you're binding to a DataTable. Try this:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
DataTable sourceData = (DataTable)GridView1.DataSource;
sourceData.Rows[e.RowIndex].Delete();
GridVie1.DataSource = sourceData;
GridView1.DataBind();
}
Essentially, as I said in my comment, grab a copy of the GridView's DataSource, remove the row from it, then set the DataSource to the updated object and call DataBind() on it again.
Here is a trick with what you want to achieve. I was also having problem like you.
Its hard to get selected row and data key in RowDeleting Event But it is very easy to get selected row and datakeys in SelectedIndexChanged event. Here's an example-
protected void gv_SelectedIndexChanged(object sender, EventArgs e)
{
int index = gv.SelectedIndex;
int vehicleId = Convert.ToInt32(gv.DataKeys[index].Value);
SqlConnection con = new SqlConnection("-----");
SqlCommand com = new SqlCommand("DELETE FROM tbl WHERE vId = #vId", con);
com.Parameters.AddWithValue("#vId", vehicleId);
con.Open();
com.ExecuteNonQuery();
}
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int index = GridView1.SelectedIndex;
int id = Convert.ToInt32(GridView1.DataKeys[index].Value);
SqlConnection con = new SqlConnection(str);
SqlCommand com = new SqlCommand("spDelete", con);
com.Parameters.AddWithValue("#PatientId", id);
con.Open();
com.ExecuteNonQuery();
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
I know this is a late answer but still it would help someone in need of a solution.
I recommend to use OnRowCommand for delete operation along with DataKeyNames, keep OnRowDeleting function to avoid exception.
<asp:gridview ID="Gridview1" runat="server" ShowFooter="true"
AutoGenerateColumns="false" OnRowDeleting="Gridview1_RowDeleting" OnRowCommand="Gridview1_RowCommand" DataKeyNames="ID">
Include DataKeyNames="ID" in the gridView and specify the same in link button.
<asp:LinkButton ID="lnkdelete" runat="server" CommandName="Delete" CommandArgument='<%#Eval("ID")%>'>Delete</asp:LinkButton>
protected void Gridview1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
int ID = Convert.ToInt32(e.CommandArgument);
//now perform the delete operation using ID value
}
}
protected void Gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//Leave it blank
}
If this is helpful, give me +
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
MySqlCommand cmd;
string id1 = GridView1.DataKeys[e.RowIndex].Value.ToString();
con.Open();
cmd = new MySqlCommand("delete from tableName where refno='" + id1 + "'", con);
cmd.ExecuteNonQuery();
con.Close();
BindView();
}
private void BindView()
{
GridView1.DataSource = ms.dTable("select * from table_name");
GridView1.DataBind();
}
//message box before deletion
protected void grdEmployee_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
foreach (DataControlFieldCell cell in e.Row.Cells)
{
foreach (Control control in cell.Controls)
{
LinkButton button = control as LinkButton;
if (button != null && button.CommandName == "Delete")
button.OnClientClick = "if (!confirm('Are you sure " +
"you want to delete this record?')) return false;";
}
}
}
}
//deletion
protected void grdEmployee_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
conn.Open();
int empid = Convert.ToInt32(((Label)grdEmployee.Rows[e.RowIndex].Cells[0].FindControl("lblIdBind")).Text);
SqlCommand cmdDelete = new SqlCommand("Delete from employee_details where id=" + empid, conn);
cmdDelete.ExecuteNonQuery();
conn.Close();
grdEmployee_refreshdata();
}

Categories

Resources