One of our applications has a page for our users to report bugs. We wanted to allow them to “attach” one or more files to the bug record. The files could be screen shots, spreadsheets, etc. So the bug entry page would have the normal data entry part and have the following box at the bottom of the page:
If you click the FileName it will download the file if IIS is setup to send that extention. All this should be made into a user control or a server control, but for now I have the code in the page. Here are the key parts:
// the page has a property that returns the bug's record id.
private int id
{ get { return Convert.ToInt32(Request.QueryString["id"]); } }
private string uploadDir
{ get { return System.AppDomain.CurrentDomain.BaseDirectory+ "\\Uploads\\"; } }
protected void btnUpload_Click(object sender, EventArgs e)
{
if (this.FileUpload1.HasFile)
{ //we rename the file to start with the id and an underscore.
string fileName = uploadDir + id.ToString() + "_" + FileUpload1.FileName;
FileUpload1.SaveAs(fileName);
bindFiles();
} else { setErrorMessage("You have not specified a file."); }
}
protected void bindFiles()
{
// make a table to hold the file's information.
DataTable dt = new DataTable();
dt.Columns.Add("FileName", typeof(String));
dt.Columns.Add("Created", typeof(DateTime));
dt.Columns.Add("Size", typeof(Int32));
dt.Columns.Add("id", typeof(Int32));
// get a list of files that start with our id.
string[] files = Directory.GetFiles(uploadDir,id.ToString()+"_*.*");
//populate the table.
foreach (string fileName in files)
{
DataRow dr = dt.NewRow();
FileInfo fi = new FileInfo(fileName);
// at this point we need to strip off the id.
dr["FileName"] = fileName.Substring(fileName.LastIndexOf("\\") + 2 + id.ToString().Length);
dr["Created"] = fi.CreationTime;
dr["Size"] = fi.Length;
dr["id"] = this.id;
dt.Rows.Add(dr);
}
// now bind the table to our gridview
this.gvFiles.DataSource = dt;
this.gvFiles.DataBind();
}
protected void lbDelete_Click(object sender, EventArgs e)
{
//Don't like how fragile this is, but good enough for now.
string fileName = uploadDir + id.ToString() + "_" + ((HyperLink)((GridViewRow)((LinkButton)sender).Parent.Parent).Cells[1].Controls[0]).Text;
File.Delete(fileName);
bindFiles();
}
Here is the related mark-up from the aspx page:
<div id="divFiles" style="border: solid 1px black">
<span id="Span1" style="font-size:X-Large;font-weight:bold;">FILES</span>
<br />
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="btnUpload_Click" /><br />
<br />
<asp:GridView ID="gvFiles" runat="server" AutoGenerateColumns="False" Caption="<strong>FILES</strong>"
CaptionAlign="Top" CellPadding="4" ForeColor="#333333" GridLines="None">
<RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
<Columns>
<asp:TemplateField InsertVisible="False" ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="lbDelete" runat="server" CausesValidation="False" CommandName="Delete"
Text="Delete" OnClientClick="confirm('Are you sure you want to delete this file?');" OnClick="lbDelete_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:HyperLinkField DataTextField="FileName" SortExpression="FileName" Text="FileName"
HeaderText="FileName" DataNavigateUrlFormatString="~/Uploads/{0}_{1}"
DataNavigateUrlFields="id,FileName" >
<ItemStyle HorizontalAlign="Left" />
</asp:HyperLinkField>
<asp:BoundField DataField="Created" DataFormatString="{0:M/d/yy H:mm}" HeaderText="Created"
SortExpression="Created" />
<asp:BoundField DataField="Size" HeaderText="Size" SortExpression="Size" DataFormatString="{0:#,###,###}" >
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
</Columns>
<PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
</div>
<br />