Hi I have a problem with my code, I am implementing a rating application. I have connected a access database to my website. I then added in the ajax control and gridview etc..
this is my code so far..
<cc1:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</cc1:ToolkitScriptManager>
<asp:GridView ID="gvwMake" runat="server" DataKeyNames="MachineID"
BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px"
CellPadding="3" AllowPaging="True"
OnSelectedIndexChanged="gvwMake_SelectedIndexChanged">
<FooterStyle BackColor="White" ForeColor="#000066" />
<HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
<RowStyle ForeColor="#000066" />
<SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#F1F1F1" />
<SortedAscendingHeaderStyle BackColor="#007DBB" />
<SortedDescendingCellStyle BackColor="#CAC9C9" />
<SortedDescendingHeaderStyle BackColor="#00547E" />
<Columns>
<asp:BoundField DataField="Make" HeaderText="Make" />
<asp:ImageField DataImageUrlField="Image"></asp:ImageField>
<asp:TemplateField HeaderText="Machine Rating">
<ItemTemplate>
<cc1:Rating ID="Rating1"
AutoPostBack="true" OnChanged="OnRatingChanged" runat="server"
StarCssClass="Star" WaitingStarCssClass="WaitingStar"
EmptyStarCssClass="Star"
FilledStarCssClass="FilledStar"
CurrentRating='<%# Eval("Rating") %>'>
</cc1:Rating>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
That all seems to be working fine however the problem is with the code behind.
using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.OleDb;
using System.Configuration;
using System.Data.SqlClient;
using AjaxControlToolkit;
public partial class rate : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataSet ds = MachineClass.getMachine();
gvwMake.DataSource = ds.Tables["dtMachine"];
gvwMake.DataBind();
}
}
protected void gvwMake_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvwMake.PageIndex = e.NewPageIndex;
DataSet ds = MachineClass.getMachine();
gvwMake.DataSource = ds.Tables["dtMachine"];
gvwMake.DataBind();
}
protected void gvwMake_SelectedIndexChanged(object sender, EventArgs e)
{
string strID = gvwMake.SelectedRow.Cells[2].Text;
Session["TID"] = strID;
Response.Redirect("~/Result.aspx");
}
protected void btnSearch_Click(object sender, EventArgs e)
{
DataSet ds = MachineClass.getMachine(txtSearch.Text);
gvwMake.DataSource = ds.Tables["dtMachine"];
gvwMake.DataBind();
}
private void ShowData()
{
using (OleDbDataAdapter da = new OleDbDataAdapter(
"SELECT TOP 20 Products.ProductID, Products.ProductName," +
" Products.UnitPrice, Products.SupplierID, " +
"Products.CustomerRating FROM Products",
new OleDbConnection(
ConfigurationManager.ConnectionStrings["comac.mdb.accdb"].ToString())))
{
DataTable dt = new DataTable();
da.SelectCommand.Connection.Open();
da.Fill(dt);
this.gvwMake.DataSource = dt;
this.gvwMake.DataBind();
}
}
protected void Rating1_Changed(object sender,
AjaxControlToolkit.RatingEventArgs e)
{
AjaxControlToolkit.Rating myRating =
(AjaxControlToolkit.Rating)sender;
System.Text.RegularExpressions.Regex rexLineNo =
new System.Text.RegularExpressions.Regex("ctl\\d+");
this.updateRating(this.MachineId(
rexLineNo.Match(myRating.UniqueID).ToString()), e.Value);
}
private string MachineId(string LineNo)
{
foreach (GridViewRow r in this.gvwMake.Rows)
{
Label lblMachineId = (Label)r.FindControl("lblMachineId");
if (lblMachineId.UniqueID.Contains(LineNo))
{
return lblMachineId.Text;
}
}
return string.Empty;
}
private void updateRating(string MachineId, string Rating)
{
OleDbParameter paramRating = new OleDbParameter("#Rating", Rating);
OleDbParameter paramMachineId =
new OleDbParameter("#MachineId", MachineId);
using (OleDbCommand cmd = new OleDbCommand(
"UPDATE Machines SET CustomerRating " +
"= #Rating WHERE Machines.MachineID=#MachineId",
new OleDbConnection(
ConfigurationManager.ConnectionStrings["comac.mdb.accdb"].ToString())))
{
cmd.Parameters.Add(paramRating);
cmd.Parameters.Add(paramMachineId);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
}
}
}
This is my first time using the ajax rating control and not sure if the codes suitable for it when i run the webpage i get an error message
'ASP.rate_aspx' does not contain a definition for 'OnRatingChanged' and no extension method 'OnRatingChanged' accepting a first argument of type 'ASP.rate_aspx' could be found (are you missing a using directive or an assembly reference?)
What I could see from the below part of your code:
<ItemTemplate>
<cc1:Rating ID="Rating1"
AutoPostBack="true" OnChanged="OnRatingChanged" runat="server"
StarCssClass="Star" WaitingStarCssClass="WaitingStar"
EmptyStarCssClass="Star"
FilledStarCssClass="FilledStar"
CurrentRating='<%# Eval("Rating") %>'>
</cc1:Rating>
</ItemTemplate>
is the place where you use the Rating Control, you are assigning OnChanged Event to a Code behind method OnRatingChanged (mentioned as OnChanged="OnRatingChanged"in your code) and since your code behind does not have any method named OnRatingChanged the error is thrown saying 'ASP.rate_aspx' does not contain a definition for 'OnRatingChanged'.
So if you are really not using this event then remove the event (remove the part: OnChanged="OnRatingChanged" from your code) or in case if you are using this then include an appropriate 'OnRatingChanged' method in your code behind.
Okay here is the C# code. You will have to import the following namespaces:
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using AjaxControlToolkit;
//the page_onload add the following code
if (!IsPostBack)
{
gvFruits.DataSource = GetData("SELECT FruitId, FruitName, ISNULL((SELECT AVG(Rating) FROM Fruit_Ratings WHERE FruitId = Fruits.FruitId), 0) Rating FROM Fruits");
gvFruits.DataBind();
}
private static DataTable GetData(string query)
{
DataTable dt = new DataTable();
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
}
}
return dt;
}
}
//and here is the code full functioning app for rating.[Full functioning rating app code][1]
[1]: http://www.aspsnippets.com/Articles/Using-ASPNet-AJAX-Rating-Control-inside-GridView-TemplateField-ItemTemplate.aspx
Okay Try the demo from this website probably you will find it usefull>
http://www.aspsnippets.com/Articles/Using-ASPNet-AJAX-Rating-Control-inside-GridView-TemplateField-ItemTemplate.aspx
first add ajax toolkit from your ajax toolbox and then apply followin coding with css.
<style type="text/css">
.Star
{
background-image: url(Images/rsz_star-deselect.png);
height: 17px;
width: 17px;
}
.WaitingStar
{
/*background-image: url(images/WaitingStar.gif);*/
height: 17px;
width: 17px;
}
.FilledStar
{
background-image: url(Images/rsz_star-select.png);
height: 17px;
width: 17px;
}
</style>
<ItemTemplate>
<cc1:Rating ID="Rating1" AutoPostBack="true" runat="server"
StarCssClass="Star" WaitingStarCssClass="WaitingStar" EmptyStarCssClass="Star"
FilledStarCssClass="FilledStar" CurrentRating='<%# Eval("Rating") %>'>
</cc1:Rating>
</ItemTemplate>
Related
I am using asp.net webforms application and listing products on page load. I want to sort data when i am selecting a value from dropdownlist. If i use static DataSet i can sort data using dropdownlist but it's not useful when you have visitors more then one.
I don't want to use Session variable for sorting products. What's the alternative to sorting data using dropdownlist? I am listing products on the page, just want to sort. When i click on the dropdown list for sorting, DataSet returns "null" But i can see products on the page in repeater. It doesn't disappear.
Dropdown listing code:
protected DataSet data {get;set;}
protected void dropdown_sort_SelectedIndexChanged(object sender, EventArgs e)
{
if(data != null)
{
ds.Tables[0].DefaultView.Sort = "product_id asc"
}
}
Any suggestion?
Well, we assume then a drop down list to select the column to sort, and then say a gridview.
So, say this markup:
Sort Data by:
<asp:DropDownList ID="DropDownList1" runat="server" Width="120px"
AutoPostBack="true"
OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" >
</asp:DropDownList>
<br />
<asp:GridView ID="GridView1" runat="server" CssClass="table"
AutoGenerateColumns="False" DataKeyNames="ID"
ShowHeaderWhenEmpty="true" Width="40%">
<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="Description" HeaderText="Description" />
</Columns>
</asp:GridView>
Ok, code to load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadCombo();
LoadGrid();
}
}
void LoadCombo()
{
string OrderList = "Select Order,HotelName,City,FirstName,LastName";
foreach (string sOrder in OrderList.Split(','))
{
DropDownList1.Items.Add(sOrder);
}
}
void LoadGrid(string OrderBy = "")
{
string strSQL = "SELECT * FROM tblHotelsA";
if ( (OrderBy != "") & (OrderBy != "Select Order") )
strSQL += " ORDER BY " + OrderBy;
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
DataTable rstData = new DataTable();
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstData;
GridView1.DataBind();
}
}
}
And we now have this:
Now, code for the drop down list (note the autopostback=true).
We have this code:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
LoadGrid(DropDownList1.Text);
}
So, say we select this from the drop down:
We now see this:
While implementing a Calendar into asp.net, I originally had text showing up on certain dates, pulling data from a DB. However, now, after changing nothing (to my knowledge), the text no longer appears, but the date box color does still change. Any help would be great. I am also new to asp.net, so it could be a simple mistake.
asp.net code:
<asp:Calendar ID="Calendar" runat="server" OnDayRender="Calendar1_DayRender" BackColor="White" BorderColor="White" BorderWidth="1px" Font-Names="Verdana" Font-Size="9pt" ForeColor="Black" Height="300px" NextPrevFormat="FullMonth" Width="500px" >
<DayHeaderStyle Font-Bold="True" Font-Size="8pt" />
<NextPrevStyle Font-Bold="True" Font-Size="8pt" ForeColor="#333333" VerticalAlign="Bottom" />
<OtherMonthDayStyle ForeColor="#999999" />
<SelectedDayStyle BackColor="#333399" ForeColor="White" />
<TitleStyle BackColor="White" BorderColor="Black" BorderWidth="4px" Font-Bold="True" Font-Size="12pt" ForeColor="#333399" />
<TodayDayStyle BackColor="#CCCCCC" />
</asp:Calendar>
C# code behind:
public partial class HomePageStudent : System.Web.UI.Page
{
SqlConnection c = new SqlConnection(ConfigurationManager.ConnectionStrings["Lab3"].ConnectionString);
String sqlQuery;
Dictionary<string, string> importantDates = new Dictionary<string, string>();
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
c.Open();
DateTime day;
sqlQuery = #"SELECT * From Internships";
try
{
SqlCommand cmd = new SqlCommand(sqlQuery, c);
SqlDataReader rd;
rd = cmd.ExecuteReader();
while (rd.Read())
{
day = (DateTime)rd["DateStart"];
if (day == e.Day.Date)
{
e.Cell.Controls.Add(new LiteralControl("<p>" + "Application Due:\n" + rd["InternshipTitle"] + "<p>"));
e.Cell.BackColor = System.Drawing.Color.Purple;
e.Cell.ForeColor = System.Drawing.Color.Goldenrod;
e.Cell.Font.Bold = true;
}
}
}
catch (Exception ex)
{
}
c.Close();
}
}
I tried removing formatting and changing around the code a little bit, to no avail.
Of course I solve it a couple minutes after posting...
After renaming the dayrender method, that seemed to fix everything... somehow.
I currently have a nested datagrid. The top-level grid gets data from a stored procedure. The nested grid gets data from a stored procedure based on the column value of each row.
Here is my ASPX code
<%# Page Language="C#" Async="true" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="CS" Debug="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style type="text/css">
* {
margin:0;
padding: 0;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$("[src*=plus]").live("click", function () {
$(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>")
$(this).attr("src", "images/minus.png");
});
$("[src*=minus]").live("click", function () {
$(this).attr("src", "images/plus.png");
$(this).closest("tr").next().remove();
});
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:GridView ID="gvCustomers" runat="server" AutoGenerateColumns="false" CssClass="Grid"
DataKeyNames="ID" OnRowDataBound="OnRowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<img alt = "" width="25px" style="cursor: pointer" src="images/plus.png" />
<asp:Panel ID="pnlOrders" runat="server" Style="display: none">
<asp:GridView ID="gvOrders" runat="server" AutoGenerateColumns="false" CssClass = "ChildGrid">
<Columns>
<asp:BoundField ItemStyle-Width="135px" DataField="Label" HeaderText="Label" />
<asp:BoundField ItemStyle-Width="150px" DataField="IDs" HeaderText="IDs" />
<asp:BoundField ItemStyle-Width="150px" DataFormatString="${0:###,###,###.00}" DataField="Total" HeaderText=Total" />
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField ItemStyle-Width="150px" DataField="Source" HeaderText="Source" />
<asp:BoundField ItemStyle-Width="150px" DataField="Label" HeaderText="Label" />
<asp:BoundField ItemStyle-Width="150px" DataFormatString="${0:###,###,###.00}" DataField="Total20" HeaderText="Total20" />
<asp:BoundField ItemStyle-Width="150px" DataFormatString="${0:###,###,###.00}" DataField="Total1" HeaderText="Total1" />
<asp:BoundField ItemStyle-Width="150px" DataFormatString="{0:P1}" DataField="Average_Fee_PCT" HeaderText="Average Fee" />
</Columns>
</asp:GridView>
</form>
</body>
</html>
Here is C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public partial class CS : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("<script>console.log('Page Loaded');</script>");
if (!IsPostBack)
{
gvCustomers.DataSource = GetData("exec ReturnData '" + DateTime.Now.ToString("yyyy-MM-dd") + "'");
gvCustomers.DataBind();
}
}
private static DataTable GetData(string query)
{
using (SqlConnection con = new SqlConnection("Data Source=SQLSERVER;Initial Catalog=DBNAME;User Id=user;Password=pass"))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = query;
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataSet ds = new DataSet())
{
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
}
}
}
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
Response.Write("<script>console.log('Next Column...." + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "');</script>");
if (e.Row.RowType == DataControlRowType.DataRow)
{
Response.Write("<script>console.log('Pulling data...." + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "');</script>");
string ID = gvCustomers.DataKeys[e.Row.RowIndex].Value.ToString();
GridView gvOrders = e.Row.FindControl("gvOrders") as GridView;
gvOrders.DataSource = GetData(string.Format("exec ReturnDataSingle '" + ID + "', '"+ DateTime.Now.ToString("yyyy-MM-dd") + "'"));
gvOrders.DataBind();
Response.Write("<script>console.log('Pulled data...." + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "');</script>");
}
}
}
Currently, after each top-level row is created, it runs a stored procedure and returns the data as a nested gridview.
Each time the stored procedure runs for the nested grid view, it takes 200ms for it to return the data. The issue is that with 3 or 4 rows it is pretty fast. But when I have 300 rows, it will take 1 minute for the page to fully load.
Are there any ways I can change it so it won't wait until the current row is completed before moving onto the next row?
I am newbie to the ASP.Net world and have a confusion on how to approach the below scenario.
In my application I have to fetch the data from the database when page is loaded and show this in a GridView. The table currently has around 1000 records with about 7 columns. But the data will keep growing.
Here is the code of how I am binding the data to the grid.
protected void Page_Load(object sender, EventArgs e)
{
var data = new AppsAuthData().GetAllUsers();
gridUsersInfo.DataSource = data;
gridUsersInfo.DataBind();
}
I came to know that on every post back above code is getting executed (which obviously is not good). So I added the following to that start of the function
if (IsPostBack)
return;
var data = new AppsAuthData().GetAllUsers();
gridUsersInfo.DataSource = data;
gridUsersInfo.DataBind();
Page Markup
<%# Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.Master" CodeBehind="RemoveUsers.aspx.cs" Inherits="AppsAuth.Authencations.RemoveUsers" %>
This again has an issue that after Postbacks, GridView has nothing to show. So next I saved my results to the ViewState and on each post back i was retrieving/updating the ViewState.
But since data can be huge in some scenarios, so what are best options available to deal with such issues?
GridView snippet
<asp:GridView ID="gridUsersInfo" runat="server" Width="100%" ForeColor="#333333" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="false" OnSorting="UserInfo_Sorting" OnRowEditing="gridUsersInfo_RowEditing"
OnPageIndexChanging="gridUsersInfo_PageIndexChanging" AutoGenerateEditButton="True">
> <Columns>
<asp:BoundField DataField="USER_ID" ReadOnly="True" HeaderText="ID" SortExpression="USER_ID" />
<asp:BoundField DataField="USER_NAME" ReadOnly="False" HeaderText="User Name" SortExpression="USER_NAME" />
</Columns>
</asp:GridView>
protected void gridUsersInfo_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gridUsersInfo.PageIndex = e.NewPageIndex;
gridUsersInfo.DataBind();
}
Instead of putting everything on PageLoad. You can put a button and write the code to populate GridView in the click event of that button.
Using the asp.net control Gridview with pagination enabled will do this for you.
Check the following example:
HTML
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" AllowPaging="true"
OnPageIndexChanging="OnPageIndexChanging" PageSize="10">
<Columns>
<asp:BoundField ItemStyle-Width="150px" DataField="CustomerID" HeaderText="Customer ID" />
<asp:BoundField ItemStyle-Width="150px" DataField="ContactName" HeaderText="Contact Name" />
<asp:BoundField ItemStyle-Width="150px" DataField="City" HeaderText="City" />
<asp:BoundField ItemStyle-Width="150px" DataField="Country" HeaderText="Country" />
</Columns>
</asp:GridView>
CodeBehind
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.BindGrid();
}
}
private void BindGrid()
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("SELECT CustomerId, ContactName, City, Country FROM Customers"))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
}
}
Implementing Pagination
The event handler is called when the page is changed inside the GridView.
The value of the PageIndex of the Page which was clicked is present inside the NewPageIndex property of the GridViewPageEventArgs object and it is set to the PageIndex property of the GridView and the GridView is again populated by calling the BindGrid function.
protected void OnPaging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridView1.DataBind();
}
Source : http://www.aspsnippets.com/Articles/Paging-in-ASPNet-GridView-Example.aspx
What you have to do is just bind bind gridview when !IsPostback in page_load
if(!IsPostBack)
{ var data = new AppsAuthData().GetAllUsers();
ViewState["UserData"] = data;
gridUsersInfo.DataSource = data;
gridUsersInfo.DataBind();
}
Hear is an example : Asp.Net Bind Grid View
In .aspx file
<form runat="server" onload="Page_Load">
<asp:GridView runat="server" ID="gridEvent" AutoGenerateColumns="False" BackColor="White"
BorderStyle="None" BorderWidth="0px" class="table mb-0"
>
<RowStyle BackColor="White" />
<Columns>
<asp:BoundField DataField="EventId" HeaderText="#" />
<asp:BoundField DataField="Title" HeaderText="Event Title" />
<asp:BoundField DataField="EventDate" HeaderText="Event Date" />
<asp:BoundField DataField="Location" HeaderText="Venue" />
<asp:BoundField DataField="RegisteredUsers" HeaderText="Registred User(s)" />
<asp:CommandField ShowEditButton="True" />
<asp:CommandField ShowDeleteButton="True" />
</Columns>
<FooterStyle BackColor="#99CCCC" ForeColor="#003399" />
<PagerStyle BackColor="#99CCCC" ForeColor="#003399" HorizontalAlign="Left" />
<SelectedRowStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" />
<HeaderStyle BackColor="#FBFBFB" Font-Bold="True" ForeColor="#5A6169" />
</asp:GridView>
</form>
in the .aspx.designer.cs
public partial class Default
{
/// <summary>
/// txtLocation control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.GridView gridEvent;
}
in the .aspx.cs file
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
// Enable the GridView paging option and
// specify the page size.
gridEvent.AllowPaging = true;
gridEvent.PageSize = 15;
// Initialize the sorting expression.
ViewState["SortExpression"] = "EventId ASC";
// Enable the GridView sorting option.
gridEvent.AllowSorting = true;
BindGrid();
}
}
private void BindGrid()
{
// Get the connection string from Web.config.
// When we use Using statement,
// we don't need to explicitly dispose the object in the code,
// the using statement takes care of it.
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["sqlConn"].ToString()))
{
// Create a DataSet object.
DataSet dsPerson = new DataSet();
// Create a SELECT query.
string strSelectCmd = "SELECT * FROM EventsList";
// Create a SqlDataAdapter object
// SqlDataAdapter represents a set of data commands and a
// database connection that are used to fill the DataSet and
// update a SQL Server database.
SqlDataAdapter da = new SqlDataAdapter(strSelectCmd, conn);
// Open the connection
conn.Open();
// Fill the DataTable named "Person" in DataSet with the rows
// returned by the query.new n
da.Fill(dsPerson, "EventsList");
// Get the DataView from Person DataTable.
DataView dvPerson = dsPerson.Tables["EventsList"].DefaultView;
// Set the sort column and sort order.
dvPerson.Sort = ViewState["SortExpression"].ToString();
// Bind the GridView control.
gridEvent.DataSource = dvPerson;
gridEvent.DataBind();
}
}
//Implementing Pagination
protected void OnPaging(object sender, GridViewPageEventArgs e)
{
gridEvent.PageIndex = e.NewPageIndex;
gridEvent.DataBind();
}
I am trying to make the upload control upload multiple files, but it is only uploading one and I am not sure why. Also I want to call the stored proc if, and only if, all required files have successfully been uploaded. Any suggestions would be helpful as I am at a loss. im sure its something im doing wrong within my foreach loop but I am unsure what exactly it is.
My markup:
<%# Page Title="" Language="C#" MasterPageFile="~/Admin/AdminMaster.master" AutoEventWireup="true" CodeFile="addFont.aspx.cs" Inherits="Admin_addFont" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server"></asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="RightCol" runat="Server">
<h1>Fonts</h1>
<h2>Currently available fonts</h2>
<div><asp:Label ID="lblFontGrd" runat="server"></asp:Label>
<asp:GridView ID="grdFonts" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False"
OnPageIndexChanging="grdFonts_PageIndexChanging">
<AlternatingRowStyle BackColor="White" ForeColor="#284775"></AlternatingRowStyle>
<Columns>
<asp:TemplateField AccessibleHeaderText="ID" FooterText="ID" HeaderText="ID">
<ItemTemplate>
<asp:Label ID="fontId" runat="server" Text='<%# Eval("FontId") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField AccessibleHeaderText="Font Name" FooterText="Font Name" HeaderText="Font Name">
<ItemTemplate>
<asp:Label ID="lblfontName" runat="server" Text='<%# Eval("FontName") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:Label ID="lblfontNameEdit" runat="server" Text='<%# Eval("FontName") %>'></asp:Label>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField AccessibleHeaderText="Example" FooterText="Example" HeaderText="Example">
<ItemTemplate>
<asp:Label id="lblfontExample" runat="server" Font-Size="Large" Font-Names='<%# BuildFont(Eval("FontFamily").ToString()) %>' ><h3>This is an example of the font</h3></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField AccessibleHeaderText="Discontinued?" HeaderText="Discontinued?" FooterText="Discontinued?">
<ItemTemplate>
<asp:CheckBox ID="Discontinued" runat="server" Checked='<%# Eval("Discontinued") %>' Enabled="false" />
</ItemTemplate>
<EditItemTemplate>
<asp:CheckBox ID="Discontinued" runat="server" Checked='<%# Eval("Discontinued") %>' Enabled="true" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Edit">
<ItemTemplate>
<span onclick="return confirm('Are you sure you want to delete?')">
<asp:LinkButton ID="btnDelete" Text="Delete" runat="server" CommandName="Delete" />
</span>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EditRowStyle BackColor="#999999"></EditRowStyle>
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White"></FooterStyle>
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White"></HeaderStyle>
<PagerStyle HorizontalAlign="Center" BackColor="#284775" ForeColor="White"></PagerStyle>
<RowStyle BackColor="#F7F6F3" ForeColor="#333333"></RowStyle>
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333"></SelectedRowStyle>
<SortedAscendingCellStyle BackColor="#E9E7E2"></SortedAscendingCellStyle>
<SortedAscendingHeaderStyle BackColor="#506C8C"></SortedAscendingHeaderStyle>
<SortedDescendingCellStyle BackColor="#FFFDF8"></SortedDescendingCellStyle>
<SortedDescendingHeaderStyle BackColor="#6F8DAE"></SortedDescendingHeaderStyle>
</asp:GridView>
</div>
<div>
<h2>Add a new font</h2>
<asp:Label ID="lblUpload" runat="server" ForeColor="Red"></asp:Label>
<p>In order to add a new font to the library please follow the steps laid out below:</p>
<p><strong>Step 1: </strong> The first, and most important, thing to do is make sure you have the appropriate license to use your font for print and web.</p>
<p><strong>Step 2: </strong> Next you need to convert your font file into multple formats to ensure browser compatability.
To do so please follow <a target="_blank" href="http://www.fontsquirrel.com/tools/webfont-generator">this</a> link.
Select OPTIMAL and upload your file. Unzip the files generated by the tool.</p>
<p><strong>Step 3: </strong> Now you need open the file that ends with '.css', a simple text editor such as notepad will do just fine.</p>
<p><strong>Step 4: </strong> Find the font-family property(see image below)</p><br />
<asp:Image ID="imgFontCssEx" runat="server" ImageUrl="~/Images/fontCssImg.png" /><br />
<p><strong>Step 5: </strong> Make sure you copy the font-family value exactly as shown in the css into the text box below, marked Font Name.</p>
<asp:TextBox ID="txtFontFam" runat="server"></asp:TextBox>
<asp:Label ID="lblFontFam" runat="server" Text="Font Family"></asp:Label>
<br />
<p><strong>Step 6: </strong> Enter a display name for your font.</p>
<asp:TextBox ID="txtFontName" runat="server"></asp:TextBox>
<asp:Label ID="lblFontName" runat="server" Text="Display Name" ></asp:Label>
<br />
<p><strong>Step 7: </strong> Now you need to upload the files specified below:</p><br />
<asp:FileUpload ID="flupFonts" runat="server" AllowMultiple="true" />
<asp:Label ID="lblCss" runat="server" AssociatedControlID="flupFonts" Text="Upload file with files ending: .css, .ttf, .svg, .eot, .woff, .woff2"></asp:Label>
<p><strong>Finally: </strong> Click the button below and the font will be made available.</p>
<br />
<asp:Button ID="btnUploadFont" runat="server" Text="Add Font" OnClick="btnUploadFont_Click" />
</div>
My code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Web.Configuration;
using System.IO;
using System.Data;
public partial class Admin_addFont : System.Web.UI.Page
{
private string fontUploadDirectory;
private string connectionString =
WebConfigurationManager.ConnectionStrings["bncConn"].ConnectionString;
protected void Page_Load(object sender, EventArgs e)
{
// ensure files are uploaded to the right folder
fontUploadDirectory = Server.MapPath(#"~\fonts\");
if (!this.IsPostBack)
{
BindGrid();
}
}
protected void BindGrid()
{
// define ado.net objects
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("ProductDetails.bnc_Fonts", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
// define parameters
cmd.Parameters.Add(new SqlParameter("#status", SqlDbType.VarChar, 50));
cmd.Parameters["#status"].Value = "Display";
// attempt to connect to db, read data, fill dataset and bind gridview. Catch exceptions and close the connection.
try
{
con.Open();
DataSet ds = new DataSet();
adapter.Fill(ds, "Fonts");
grdFonts.DataSource = ds;
grdFonts.DataBind();
}
catch (Exception err)
{
lblFontGrd.Text = err.Message;
}
finally
{
con.Close();
}
}
protected void grdFonts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grdFonts.PageIndex = e.NewPageIndex;
BindGrid();
}
public static string[] BuildFont(string font)
{
string[] array = new string[1];
array[0] = font;
return array;
}
protected void btnUploadFont_Click(object sender, EventArgs e)
{
string[] validFileTypes = { "eot", "ttf", "svg", "woff", "woff2", "css" };
bool isValidFile = false;
// check files are being submitted
if (flupFonts.HasFiles == false)
{
lblUpload.Text = "No files have been selected.";
}
else
{
HttpFileCollection fileCollection = Request.Files;
if (fileCollection.Count == 6)
{
string serverFileName = Path.GetFileName(flupFonts.PostedFile.FileName);
string ext = Path.GetExtension(serverFileName).ToLower();
string fullUploadPath = Path.Combine(fontUploadDirectory, serverFileName);
try {
foreach (HttpPostedFile uploadedFont in flupFonts.PostedFiles)
{
for (int i = 0; i < validFileTypes.Length; i++)
{
if (ext == "." + validFileTypes[i])
{
isValidFile = true;
if (!File.Exists(fullUploadPath))
{
try
{
flupFonts.PostedFile.SaveAs(fullUploadPath);
break;
}
catch (Exception err)
{
lblUpload.Text = err.Message;
}
}
}
}
if (!isValidFile)
{
lblUpload.Text += "Invalid File. Please upload a File with extension " + string.Join(",", validFileTypes);
}
}
fontDbInfo();
BindGrid();
}
catch (Exception err)
{
lblUpload.Text = "Error: " + err.Message;
}
}
else
{
if (fileCollection.Count < 6)
{
lblUpload.Text = "Please make sure you select all required files.";
}
if (fileCollection.Count > 6)
{
lblUpload.Text = "You have selected too many files. Please only add the required files.";
}
}
}
}
protected void fontDbInfo()
{
// define ado.net objects
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("ProductDetails.bnc_Fonts", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
// define sp parameters
cmd.Parameters.Add(new SqlParameter("#Status", SqlDbType.VarChar, 50));
cmd.Parameters["#Status"].Value = "Add";
cmd.Parameters.Add(new SqlParameter("#FontName", SqlDbType.VarChar, 50));
cmd.Parameters["#FontName"].Value = txtFontName.Text;
cmd.Parameters.Add(new SqlParameter("#FontFamily", SqlDbType.VarChar, 50));
cmd.Parameters["#FontFamily"].Value = txtFontFam.Text;
cmd.Parameters.Add(new SqlParameter("#Discontinued", SqlDbType.Bit));
cmd.Parameters["#Discontinued"].Value = 0;
// try to open database, insert font info, catch errors and close the connection
try
{
con.Open();
cmd.ExecuteNonQuery();
DataSet ds = new DataSet();
adapter.Fill(ds, "Fonts");
}
catch (Exception err)
{
lblFontGrd.Text = "Error: " + err.Message;
}
finally
{
con.Close();
}
}}
my stored procedure:
CREATE PROCEDURE [ProductDetails].[bnc_Fonts]
-- Add the parameters for the stored procedure here
#Status varchar(50) = '',
#FontId tinyint = '',
#FontName varchar(50) = '',
#FontFamily varchar(50) = '',
#Discontinued bit = ''
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if (#Status = 'Display')
begin
select FontId, FontName, FontFamily, Discontinued
from ProductDetails.Fonts
where Discontinued = 0
order by FontName asc
end
if (#Status = 'FontFam')
begin
select FontFamily from ProductDetails.Fonts
where FontId = #FontId
end
if (#Status = 'Add')
begin
insert into ProductDetails.Fonts (FontName, FontFamily, Discontinued)
values (#FontName, #FontFamily, #Discontinued)
end
if (#Status = 'Delete')
begin
UPDATE ProductDetails.Fonts
SET Discontinued = #Discontinued
where FontId = #FontId
end
END
I think the way you are attempting to loop through the HttpPostedFile collection is causing you problems. Try checking file validity in a separate method. I'd also suggest you break this problem down into pieces you can test. For example, try a simple Test page with code something like this. Hope this helps.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Web.Configuration;
using System.IO;
using System.Data;
public partial class Test : System.Web.UI.Page
{
private string fontUploadDirectory;
protected void Page_Load(object sender, EventArgs e)
{
// ensure files are uploaded to the right folder
fontUploadDirectory = Server.MapPath(#"~\fonts\");
}
protected void btnUploadFont_Click(object sender, EventArgs e)
{
string[] validFileTypes = { ".eot", ".ttf", ".svg", ".woff", ".woff2", ".css" };
// check files are being submitted
if (flupFonts.HasFiles == false)
{
lblUpload.Text = "No files have been selected.";
}
else
{
HttpFileCollection fileCollection = Request.Files;
foreach (HttpPostedFile uploadedFont in flupFonts.PostedFiles)
{
string ext = System.IO.Path.GetExtension(uploadedFont.FileName);
if (isValid(uploadedFont, validFileTypes, ext))
{
uploadedFont.SaveAs(fontUploadDirectory + "\\" + System.IO.Path.GetFileName(uploadedFont.FileName));
}
}
}
}
private bool isValid(HttpPostedFile file, string[] extAry, string ext)
{
bool isValid = false;
for (int i = 0; i < extAry.Length; i++)
{
if (ext.ToLowerInvariant().IndexOf(extAry[i]) > -1)
isValid = true;
}
return isValid;
}
}
Replace this loop:
foreach (HttpPostedFile uploadedFont in flupFonts.PostedFiles)
{
...
}
With this:
foreach(string key in flupFonts.Keys)
{
HttpPostedFile uploadedFont = flupFonts[key];
...
}