where am i going wrong ? Controlling gridview column value - c#

<asp:HyperLinkField DataNavigateUrlFields="runId" DataTextField="Percent" ControlStyle-CssClass="hlink" HeaderText="% SEEN" ItemStyle-Width="6%" DataNavigateUrlFormatString="run.aspx?runId={0}" ItemStyle-Font-Underline="true"/>
The above is a column from my grid view.Lets call this column 'x'.
I am trying to control the value of x in .cs file as below:
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.Cells[8].Text.Equals("0"))
{
e.Row.Cells[13].Text = "0%";
return;
}
int p,q;
GridViewRow item = e.Row;
SqlConnection con = new SqlConnection(connectionstring.ToString());
string selectSQL = " SELECT COUNT(*) AS 'Count' FROM Analysed WHERE runId =#myvar group by runId";
SqlCommand cmd = new SqlCommand(selectSQL, con);
cmd.Parameters.AddWithValue("#myvar", item.Cells[0].Text);
SqlDataReader reader;
try
{
con.Open();
Int32.TryParse(item.Cells[8].Text, out p);
reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
Int32.TryParse( reader["Count"].ToString(),out q);
item.Cells[13].Text =(q/p).ToString() + "%";
}
reader.Close();
}
}
I get an exception saying "An exception of type 'System.ArgumentOutOfRangeException' occurred in System.Web.dll but was not handled in user code Additional information: Specified argument was out of the range of valid values".This occurs in the lines :
if (e.Row.Cells[8].Text.Equals("0"))
{
e.Row.Cells[13].Text = "0%";
return;
}
Can anyone help ?
EDIT :
GridView Code :
<asp:GridView ID = "GridView2" runat = "server" HorizontalAlign="Center"
DataSourceID = "source" AutoGenerateColumns = "False" AllowPaging="True" OnRowDataBound="GridView2_RowDataBound">
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="runId" DataTextField="runId" HeaderText = "RUN ID" ControlStyle-CssClass="hlink" DataNavigateUrlFormatString="runanalysis.aspx?runId={0}" ItemStyle-Width="5%" ItemStyle-Font-Underline="true" />
<asp:HyperLinkField DataField="link" HeaderStyle-ForeColor="White" HeaderStyle-Font-Underline="true" ItemStyle-Width="10%" ItemStyle-Font-Underline="true"/>
<asp:BoundField DataField="Family" HeaderText="Product Family" ItemStyle-Width="7%" />
<asp:BoundField DataField = "Date" DataFormatString="{0:MM/dd/yy}" ItemStyle-Width="7%"/>
<asp:BoundField DataField = "Number" ItemStyle-Width="5%"/>
<asp:BoundField DataField = "Total" ItemStyle-Width="7%" />
<asp:BoundField DataField="Pass" ItemStyle-Width="7%" HeaderText="Pass Percent" DataFormatString="{0}%" />
<asp:BoundField DataField="pass" ItemStyle-Width="7%"/>
<asp:BoundField DataField="fail" ItemStyle-Width="7%"/>
<asp:BoundField DataField="Owner" ItemStyle-Width="7%"/>
<asp:BoundField DataField="Lang" ItemStyle-Width="5%"/>
<asp:BoundField DataField="Plat" ItemStyle-Width="7%"/>
<asp:BoundField DataField="Flavor" ItemStyle-Width="7%"/>
<asp:HyperLinkField DataNavigateUrlFields="runId" DataTextField="Percent" ControlStyle-CssClass="hlink" HeaderText="% SEEN" ItemStyle-Width="6%" DataNavigateUrlFormatString="run.aspx?runId={0}" ItemStyle-Font-Underline="true"/>
<asp:BoundField DataField="AutomationType" HeaderText ="Automation Type" ItemStyle-Width="7%"/>
</Columns>
</asp:GridView>

The number of cells in GridView2 are probably less than the cell you are trying to access. I think the number of cells (columns) are 13 and you have to use index,12 instead of 13. Its better to check the number of cells before accessing one of those.
if (e.Row.Cells.Count > 12 && e.Row.Cells[8].Text.Equals("0"))
{
e.Row.Cells[12].Text = "0%";
return;
}
Edit based on OP comments
You are trying to access the value that is not yet being assigned in RowDataBound event. In this event you can access the data item and parse it instead of parsing the control/cells.
Change
Int32.TryParse(item.Cells[8].Text, out p);
To
p = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "ColumnFromDatabase"));
Note: Same goes for other columns values.

Related

Unable to cast object of type 'System.String' to type 'System.Byte[]' ASP.NET web application

Hi i was just making a web application in asp.net to perform CRUD operations which include image file operations too. This web application consume a web service to perform the database operations.
When running on IIS i am stuck at following error.
" Unable to cast object of type 'System.String' to type 'System.Byte[]' "
Could you please help?. The same application code was working without any issues when the web service wasn't used.
Error:
enter image description here
Code for image view in FilmGrid.aspx.cs file
FilmService.FilmCrud objFCRUD = new FilmService.FilmCrud();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Refreshdata();
}
}
//To display entire film database as gridview
protected void Refreshdata()
{
DataSet dTbl = new DataSet();
XmlElement exelement = objFCRUD.SelectRecord(0);
if (exelement != null)
{
XmlNodeReader nodeReader = new XmlNodeReader(exelement);
dTbl.ReadXml(nodeReader, XmlReadMode.Auto);
gvMovies.DataSource = dTbl;
gvMovies.DataBind();
}
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView dr = (DataRowView)e.Row.DataItem;
string imageUrl = "data:image/jpg;base64," + Convert.ToBase64String((byte[])dr["poster"]);
(e.Row.FindControl("Image1") as Image).ImageUrl = imageUrl;
}
}
My FilmGrid.aspx file
<asp:GridView ID="gvMovies" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" runat="server" BorderWidth="2px" CellPadding="4" OnRowDataBound="OnRowDataBound" AutoGenerateColumns="false" Height="217px" Width="1491px">
<Columns>
<asp:BoundField DataField="film_id" HeaderText ="Film Id" />
<asp:BoundField DataField="film_name" HeaderText ="Film Name" />
<asp:BoundField DataField="actor" HeaderText ="Actor" />
<asp:BoundField DataField="actress" HeaderText ="Actress" />
<asp:BoundField DataField="pub_date" HeaderText ="Published Date" />
<asp:BoundField DataField="director" HeaderText ="Director" />
<asp:BoundField DataField="producer" HeaderText ="Producer" />
<asp:BoundField DataField="prod_cost" HeaderText ="Production Cost" />
<asp:BoundField DataField="dist_cost" HeaderText ="Distribution Cost" />
<asp:BoundField DataField="category" HeaderText ="Category" />
<asp:BoundField DataField="cert_category" HeaderText ="Certified Category" />
<asp:TemplateField><ItemTemplate><asp:Image ID="Image1" HeaderText ="Poster" runat="server" Width="122px" Height="148px"/></ItemTemplate></asp:TemplateField>
<asp:TemplateField><ItemTemplate><asp:LinkButton ID="lnkedit" runat="server" Text="Edit" PostBackUrl='<%# "~/AddFilm.aspx?film_id="+Eval("film_id") %>'/></ItemTemplate></asp:TemplateField>
</Columns>
</asp:GridView>
Looks like dr["poster"] returns a string and you can't directly cast (which here means using (your_type_here)) convert a string to a byte[]. Look at Piotr Szuflicki's solution for how to properly convert a string to a byte[].
You cannot directly cast string to byte[].
You have to use, for example Encoding class.
byte[] array = Encoding.ASCII.GetBytes("Your string");
https://www.c-sharpcorner.com/article/c-sharp-string-to-byte-array/
Or you can try taking char array from the string and then cast each char to byte.

How do I solve get wrong 'input string was not in a correct format.'?

My apsx
<section class="sec1" style="height:100vh;">
<link href="../Css/masterStyle.css" rel="stylesheet" />
<link href="../Css/cartStyle.css" rel="stylesheet" />
<h1>Cart</h1>
<p class="sec1_p1">Your Food</p>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" EnableTheming="True" ShowFooter="True" OnRowDeleting="GridView1_RowDeleting" >
<Columns>
<asp:BoundField DataField="sno" HeaderText="sno" Visible="False" />
<asp:BoundField DataField="restaurantID" HeaderText="restaurantID" Visible="False" />
<asp:BoundField DataField="foodID" HeaderText="foodID" Visible="False">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:BoundField DataField="foodName" HeaderText="Name">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:BoundField DataField="foodPrice" HeaderText="Price">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:BoundField DataField="quantity" HeaderText="Quantity">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:BoundField DataField="totalPrice" HeaderText="Total ">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:CommandField DeleteText="Remove" ShowDeleteButton="True" />
</Columns>
<HeaderStyle BackColor="#52E770" ForeColor="White" />
</asp:GridView>
<asp:Label ID="test" runat="server" Text="Label"></asp:Label>
</section>
My .cs
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
DataTable dt = new DataTable();
dt = (DataTable)Session["buyitems"];
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
int sr;
int sr1;
string qdata;
string dtdata;
sr = Convert.ToInt32(dt.Rows[i]["sno"].ToString());
TableCell cell = GridView1.Rows[e.RowIndex].Cells[0];
qdata = cell.Text;
dtdata = sr.ToString();
sr1 = Int32.Parse(qdata); //fixed
if (sr == sr1)
{
dt.Rows[i].Delete();
dt.AcceptChanges();
//Label1.Text = "Item Has Been Deleted From Shopping Cart";
break;
}
}
for (int i = 1; i <= dt.Rows.Count; i++)
{
dt.Rows[i - 1]["sno"] = i;
dt.AcceptChanges();
}
Session["buyitems"] = dt;
Response.Redirect("AddToCart.aspx");
}
I have use Add Wacth in Visual Studio, and i get this result
1.$exception {"Input string was not in a correct format."} System.FormatException
2.qdata = cell.Text This expression causes side effects and will not be evaluated
3.TableCell cell = GridView1.Rows[e.RowIndex].Cells[0]; error CS1073: Unexpected token 'cell'
Instead of sr1 = Int32.Parse(qdata);
use TryParse as below (and you can combine condition in single if):
if (int.TryParse(qdata, out sr1) && sr == sr1)
{
dt.Rows[i].Delete();
dt.AcceptChanges();
//Label1.Text = "Item Has Been Deleted From Shopping Cart";
break;
}
UPDATE:
Based on aspx code, I believe you are trying to read sno using the code:
TableCell cell = GridView1.Rows[e.RowIndex].Cells[0];
But since that column's (or cell's) visible property is set to false, you will need to handle it differently. One of the ways is using DataKeyNames Property of GridView as shown below:
<asp:GridView ID="GridView1"
runat="server"
AutoGenerateColumns="False"
EnableTheming="True"
ShowFooter="True"
OnRowDeleting="GridView1_RowDeleting"
DataKeyNames = "sno" >
and in code behind, please remove the lines
TableCell cell = GridView1.Rows[e.RowIndex].Cells[0];
qdata = cell.Text;
and directly replace with below condition :
if (int.TryParse(GridView1.DataKeys[e.RowIndex].Value, out sr1) && sr == sr1)
{
// code to hanlde this case goes here
}
or since you know sno is int, you could directly cast to int. But it throws excpetion if its not int.
int sno = (int) GridView1.DataKeys[e.RowIndex].Value; // since Value is [object datatype][1]
If you want to use Cells property, then an option is update the visiable property of "sno" on GridView Row Creation event. If you want to go with this option, you need to remove visible=false from asp:BoundField definition as you will be setting it dynamically in Row Creation event.
This error means your string is not in a valid int format.
As pointed by Dai, you need to use TryParse:
var value = "test";
int number;
if (Int32.TryParse(value, out number))
{
Console.WriteLine("Converted '{0}' to {1}.", value, number);
}
else
{
Console.WriteLine("Attempted conversion of '{0}' failed.",
value ?? "<null>");
}
You can also refer to Microsoft documentation here to have more details
You can get rid of the error by using Int32.TryParse
if(!Int32.TryParse(qdata, out sr1)){
MessageBox.Show(qdata + "is invalid number");
}

C# asp.net Gridview navigate to url in gridview row

I'm currently working on an in house project, I've created a GridView connected to a SQL table which looks like this:
GridView1
I created the view content buttons using the following code:
<Columns>
<asp:ButtonField ButtonType="Button" Text="View Content" CommandName="Select" />
<asp:BoundField DataField="ContentID" HeaderText="ContentID" InsertVisible="False" ReadOnly="True" SortExpression="ContentID" />
<asp:BoundField DataField="Code" HeaderText="Code" SortExpression="Code" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:BoundField DataField="URL" HeaderText="URL" Visible="true" SortExpression="URL" />
</Columns>
But this is where I am now stuck. I would like to click on the view content button and have it navigate to the URL on the selected row.
The URL comes from the SQL Table and there is a string so I'd imagine, it would need to be converted first but I could be wrong.
I started to put my code in the following:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewCommandEventArgs x = (GridViewCommandEventArgs)e;
if (x.CommandName == "Select")
{
GridViewRow row = GridView1.SelectedRow;
}
}
Add your code in GridView1_RowCommand event of gridview:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
GridViewRow row = (GridViewRow)(((BoundField)e.CommandSource).NamingContainer);
int index = row.RowIndex;
string url = (GridView1.Rows[index].FindControl("URL") as BoundField).Text;
Response.Redirect(url); // url can be from your sql table
}
}
Note: Don't forget to add OnRowCommand event in GrindView <asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand" >
GridViewRow row = (GridViewRow)(((BoundField)e.CommandSource).NamingContainer);
int index = row.RowIndex;
string url = (GridView1.Rows[index].FindControl("URL") as BoundField).Text;
Response.Redirect(url); // url can be from your sql table
So i made the change. Unfortunately, BoundField does not contain a definition for NamingContainer.
Also, GridView1.Rows[index].FindControl("URL") as BoundField fails due to the following error, cannot convert type 'system.web.ui.control' to 'system.web.ui.webcontrols.boundfield' via a reference conversion, boxing conversion, unboxing conversion or null type conversion.

Showing a dynamic grid view from SQL select statement

On my webform for ASP.Net I display a table from SQL Server. However, what I would like to do is offer the user of the web page the ability to check some boxes and only show those particular columns once I refresh the page.
Here is the aspx html:
<div style="width: 1250px; height: 300px; overflow: auto">
<asp:GridView ID="GridView1" HeaderStyle-BackColor="Black" HeaderStyle-ForeColor="Silver" RowStyle-BackColor="#EEEEEE" AlternatingRowStyle-BackColor="White"
AlternatingRowStyle-ForeColor="#000" runat="server" AutoGenerateColumns ="false" AllowPaging="false" OnPageIndexChanging="OnPageIndexChanging" AllowSorting="True">
<Columns>
<asp:BoundField DataField ="WeekEndingDate" HeaderText="Week Ending Date" ItemStyle-Width="150px" dataformatstring="{0:MM-dd-yyyy}" />
<asp:BoundField DataField ="Week_Number" HeaderText="Week Number" ItemStyle-Width="150px" />
<asp:BoundField DataField ="Class" HeaderText="Class" ItemStyle-Width="150px" />
<asp:BoundField DataField ="Animal" HeaderText="Animal" ItemStyle-Width="150px" />
<asp:BoundField DataField ="North_Island" HeaderText="North Island" ItemStyle-Width="150px" DataFormatString="{0:F2}" />
<asp:BoundField DataField ="South_Island" HeaderText="South Island" ItemStyle-Width="150px" DataFormatString="{0:F2}" />
<asp:BoundField DataField ="New_Zealand" HeaderText="New Zealand" ItemStyle-Width="150px" DataFormatString="{0:F2}" />
</Columns>
</asp:GridView>
</div>
Here is the bindgrid method:
private void BindGrid()
{
string strConnString = "server= N-1077; Trusted_Connection=yes; database=Slaughter; connection timeout=30";
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlCommand cmd = new SqlCommand("SELECT CONVERT(date, Week_Ending_Date) AS WeekEndingDate," +
"Week_Number, Class, North_Island = CAST(North_Island as float), South_Island = CAST(South_Island as float)," +
"(CAST(North_Island as float)) + (CAST(South_Island as float)) AS New_Zealand," +
"Animal = (CASE WHEN Class = 'Sheep' OR Class = 'Lamb' THEN 'Ovine' WHEN Class = 'Calf' THEN 'Calf' ELSE 'Bovine' END)" +
"FROM Slaughter ORDER BY WeekEndingDate DESC"))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
}
}
Is there a simple way to select particular columns and only show these? i.e. if they were only interested in week_number, class and south_island it would only display the data for those three columns? I don't mind building the SQL query based on the user inputs but it's how I change the boundfield Datafields to reflect on those columns that were selected in that query.
This is one way of doing it with the Visible property.
protected void RefreshSQLDisplay(object sender, EventArgs e)
{
foreach (BoundField col in GridView1.Columns)
{
if (col.DataField == "WeekEndingDate")
{
col.Visible = false;
break;
}
}
}
The disadvantage is that the columns will be still in memory and the sql query will retrieve the data. So it's better to change the sql query after all for performance reasons.
Update: I edited the code as you asked

Changing Value to DataGrid cell

I have a function in my code-behind that sets a datagrid. I create a new blank column and add it to my datagrid and I want to add a value to the column for only one row that matches an object id. For some reason the cell doesn't store the text I set it to though. Any thoughts?
public void SetContacts(IEnumerable<User> contactList, User reqUser)
{
BoundColumn reqColumn = new BoundColumn();
reqColumn.HeaderText = "";
dgExistingContacts.Columns.Add(reqColumn);
dgExistingContacts.DataSource = contactList;
foreach (DataGridItem row in dgExistingContacts.Items)
{
if (row.Cells[0].Text == reqUser.id.ToString())
row.Cells[6].Text = "Requestor";
}
dgExistingContacts.DataBind();
}
Here's my datagrid if that helps:
<asp:DataGrid runat="server" ID="dgExistingContacts" AutoGenerateColumns="false" CssClass="styledGray" HeaderStyle-CssClass="head" CellSpacing="1" CellPadding="4" GridLines="None" AlternatingItemStyle-CssClass="even" ItemStyle-CssClass="odd">
<Columns>
<asp:BoundColumn DataField="Id" Visible="false" />
<asp:BoundColumn DataField="Title" HeaderText="Role" />
<asp:BoundColumn DataField="LastName" HeaderText="Last Name" ItemStyle-Wrap="false" />
<asp:BoundColumn DataField="FirstName" HeaderText="First Name" ItemStyle-Wrap="false" />
<asp:BoundColumn DataField="Phone" HeaderText="Phone" DataFormatString="{0:(###) ###-####}" />
<asp:BoundColumn DataField="EmailAddress" HeaderText="Email" ItemStyle-Wrap="false" />
</Columns>
</asp:DataGrid>
I feel like it should be simple but I can't figure out why it's not binding.
Try handling the GridView's RowDataBound event and adding the value there.
As I see you are adding a column to dgExistingContacts and then assign contactList as DataSource of dgExistingContacts that means you first add column and then reset DaraGrid to former DataSource in this code:
dgExistingContacts.Columns.Add(reqColumn);
dgExistingContacts.DataSource = contactList;
I think when you assign a DataSource to GridView,any thing that you changed in it will be reseted.so maybe by deleting dgExistingContacts.DataSource = contactList;from codes, your problem will be solved.
I figured out that you have to bind the data before trying to change the contents. I ended up with this:
public void SetContacts(IEnumerable<User> contactList, User reqUser)
{
BoundColumn reqColumn = new BoundColumn();
reqColumn.HeaderText = "";
dgExistingContacts.Columns.Add(reqColumn);
dgExistingContacts.DataSource = contactList;
dgExistingContacts.DataBind();
foreach (DataGridItem row in dgExistingContacts.Items)
{
if (row.Cells[0].Text == reqUser.id.ToString())
row.Cells[6].Text = "Requestor";
}
}

Categories