File download from database not working - c#

I've inherited this site and having issues with file downloads. Files such as .pdf, .doxs, .txt are saved in Sql as image. A datalist controls is used with a a href controls to view it/downloaded it but it's not working. And I realize that a href control is not a proper control to use but not sure what control to use.
Here is the aspx markup:
<asp:DataList ID="DataList2" runat="server" DataSourceID="SqlDataSource2" DataKeyField="fileId">
<ItemTemplate>
<a href='<%# "~/UserControls/FileFetch.ashx?fileId=" + Convert.ToString(Eval("fileId")) %>' target="_blank">
<%# Convert.ToString(Eval("fileName"))%></a>
</ItemTemplate>
</asp:DataList>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:ClubSiteDB %>"
SelectCommand="SELECT [fileId], [fileName], [postedBy] FROM [FilesLibrary]">
</asp:SqlDataSource>
A helper file called FileFetch.ashx is used to get the file:
<%# WebHandler Language="C#" Class="FileFetch" %>
using System;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using System.IO;
public class FileFetch : IHttpHandler
{
const int BUFFERSIZE = 1024;
public bool IsReusable
{
get
{
return true;
}
}
public void ProcessRequest(HttpContext context)
{
HttpResponse response = context.Response;
HttpRequest request = context.Request;
response.ContentType = "response.ContentType";
response.Cache.SetCacheability(HttpCacheability.Public);
response.BufferOutput = false;
writeSingleImage(Convert.ToInt32(request.QueryString["fileId"]), response.OutputStream);
response.End();
}
public void writeSingleImage(int fileId, Stream output)
{
string cxnstr = System.Configuration.ConfigurationManager.ConnectionStrings["ClubSiteDB"].ConnectionString;
SqlConnection connection = new SqlConnection(cxnstr);
string query;
query = "SELECT fileData FROM dbo.FilesLibrary where fileId=#fileId";
SqlCommand command = new SqlCommand(query, connection);
SqlParameter param0 = new SqlParameter("#fileId", SqlDbType.Int);
param0.Value = fileId;
command.Parameters.Add(param0);
connection.Open();
byte[] d = ((byte[])(command.ExecuteScalar()));
output.Write(d, 0, d.Length);
connection.Close();
}
}

I'm going to take a stab at this and say you need to change your Anchor tag to be the following:
<a href='<%# Page.ResolveUrl("~/UserControls/FileFetch.ashx?fileId=" + Convert.ToString(Eval("fileId"))) %>' target="_blank">
The MSDN link to the Page.ResolveUrl method is here. Page inherits from Control, hence why the link refers to Control.ResolveUrl.
I've just seen that another alternative is to add runat="server" to the Anchor tag to turn it into a server control.

Related

FileUpload1 does not exist in current context

I'm trying to create a site that allows the user to upload a song and download any song that was uploaded. I'm using MySQL to store any uploaded song. I think I have the HTML and C# code right but it keeps throwing me an error saying FileUpload1 does not exist in the current context, you can use a navigation bar to switch context. My C# code is as follows.
using System;
using System.Collections.Generic;
using System.Web;
using System.Xml.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using MySql;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.IO;
using System.Text;
using System.Web.UI.WebControls.WebParts;
using System.Configuration;
public partial class Default3 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnUpload_Click(object sender, EventArgs e)
{
using (BinaryReader br = new BinaryReader(FileUpload1.PostedFile.InputStream))
{
byte[] bytes = br.ReadBytes((int)FileUpload1.PostedFile.InputStream.Length);
string strConnString = "server=localhost;user id=root;database=music;persistsecurityinfo=True";
using (MySqlConnection con = new MySqlConnection(strConnString))
{
using (MySqlCommand command = new MySqlCommand())
{
con.Open();
string SQL = "insert into tblFiles(Name, ContentType, Data) values (#Name, #ContentType, #Data)";
command.CommandText = SQL;
command.Parameters.AddWithValue("#Name", Path.GetFileName(FileUpload1.PostedFile.FileName));
command.Parameters.AddWithValue("#ContentType", "audio/mpeg3");
command.Parameters.AddWithValue("#Data", bytes);
command.Connection = con;
command.ExecuteNonQuery();
con.Close();
}
}
}
Response.Redirect(Request.Url.AbsoluteUri);
}
}
Here is my HTML for the site:
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Music.aspx.cs" Inherits="Default3" %>
<asp:Content ID="music" runat="server" ContentPlaceHolderID ="ContentPlaceHolder1">
<asp:FileUpload ID="FileUpload1" runat="server"/>
<asp:Button ID="btnUpload" runat="server" Text="Upload"
    onclick="btnUpload_Click"/>
<hr/>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" RowStyle-BackColor="#A1DCF2" Font-Names = "Arial" Font-Size = "10pt"
HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White">
    <Columns>
        <asp:BoundField DataField="Name" HeaderText="FileName"/>
        <asp:TemplateField>
            <ItemTemplate>
                <object type="application/x-shockwave-flash" data='dewplayer-vol.swf?mp3=File.ashx?Id=<%# Eval("Id") %>'
                    width="240" height="20" id="dewplayer">
                    <param name="wmode" value="transparent"/>
                    <param name="movie" value='dewplayer-vol.swf?mp3=File.ashx?Id=<%# Eval("Id") %>'/>
                </object>
            </ItemTemplate>
       </asp:TemplateField>
        <asp:HyperLinkField DataNavigateUrlFields="Id" Text = "Download" DataNavigateUrlFormatString = "~/File.ashx?Id={0}" HeaderText="Download"/>
   </Columns>
</asp:GridView>
</asp:Content>
Your code behind defines a partial class "Default3". I assume your aspx page is named "Default3", and visual studio has generated the code to instantiate the elements in that aspx page. That generated code is also a partial class "Default3", but you will notice in that generated code, that the partial class is defined under a namespace. Your code behind does not define the rest of that class under any namespace, so it does not have access to the same objects. Looks like at some point you deleted the namespace specification out of your code behind.

Ajax AutoCompleteExtender not hitting code behind in userControl C#

I'm trying to use the Ajax autoCompleteExtender to auto complete my textboxes using a sql query in my code behind. The problem I'm having is that my code behind isn't being hit at all.
What happens instead is my autocomplete options display as the code from my masterpage.
I've done some research and the problem might be that my textboxes are in an ascx file called from my aspx file but I can't figure out a way around it. I've even tried pointing the ServicePath to a webService and it still doesn't hit.
Any input would help, thank you!
Here's my relevant code:
Aspx File:
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage/Admin.Master" AutoEventWireup="true" EnableEventValidation="false" %>
<%# Register TagPrefix="AdminSearch" TagName="AdminSearch" Src="AdminSearch.ascx" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<AdminSearch:AdminSearch runat="server" ID="AdminSearch" />
</asp:Content>
Ascx File:
<%# Control Language="C#" ClassName="WebUserControl" AutoEventWireup="true" EnableViewState="true" Inherits="AdminSearch" CodeBehind="AdminSearch.ascx.cs" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<link href="../Style/Search/AdminSearch.css" rel="stylesheet" />
<script src="../Scripts/js/Search/AdminSearch.js"></script>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods = "true">
</asp:ScriptManager>
<td class="g3">
<br />
<asp:TextBox ID="TextBoxTierProfile" CssClass="g3" runat="server"></asp:TextBox><br />
<cc1:AutoCompleteExtender ServiceMethod="SearchProfiles" ServicePath="~/AutoComplete.asmx"
MinimumPrefixLength="2"
CompletionInterval="1" EnableCaching="true" CompletionSetCount="10"
TargetControlID="TextBoxTierProfile"
ID="AutoCompleteExtender2" runat="server" FirstRowSelected="false">
</cc1:AutoCompleteExtender>
</td>
Asmx File:
using System.Collections.Generic;
using System.Web.Services;
using System.Configuration;
using System.Data.SqlClient;
using System.Web;
namespace InternalTools.Admin.Search
{
/// <summary>
/// Summary description for AutoComplete
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class AutoComplete : System.Web.Services.WebService
{
static string sConnection;
public AutoComplete()
{
if (HttpContext.Current.Request.ServerVariables["LOCAL_ADDR"].ToString().Contains("127.0.0.1"))
{
sConnection = ConfigurationManager.ConnectionStrings["Reporting"].ToString();
}
else
{
sConnection = ConfigurationManager.ConnectionStrings["live"].ToString();
}
}
[System.Web.Script.Services.ScriptMethod]
[WebMethod]
public static string[] SearchProfiles(string prefixText, int count)
{
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = sConnection;
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = (I've cut out the query for security reasons)
cmd.Parameters.AddWithValue("#SearchText", prefixText);
cmd.Connection = conn;
conn.Open();
List<string> profiles = new List<string>();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
profiles.Add(sdr["PROFILENAME"].ToString());
}
}
conn.Close();
return profiles.ToArray();
}
}
}
}
}

Retrieving an Image from SQL using C# to an asp:Image

I am trying to retrieve an image from SQL Server 2008 Express and insert it into an <ASP:Image>. I have tried using a MemoryStream but I just can't seem to get it right.
My C# code at the minute looks like:
try
{
con.Open();
SqlCommand sqlGetStep1 = new SqlCommand("staff_getStep1", con);
{
sqlGetStep1.CommandType = CommandType.StoredProcedure;
sqlGetStep1.Parameters.Add(new SqlParameter("#taskID", Convert.ToInt16(taskID)));
SqlDataReader step1 = sqlGetStep1.ExecuteReader();
//Check if username exists
if (step1.Read())
{
step1Text = (string)step1["step1Text"];
step1Image = (byte)step1["step1Image"];
}//if
else
{
step1Text = "null";
step1Image = 0;
}//else
}//sqlDeleteNotification
}//try
catch (SqlException sqlEx)
{
lblSQLError.Visible = true;
lblSQLError.Text = sqlEx.Message.ToString();
}//catach sql
catch (Exception ex)
{
lblError.Visible = true;
lblError.Text = ex.ToString();
}//Catch exception
finally
{
con.Close();
}//Finally
My aspx code where I would like to display the image looks like:
<asp:Panel runat="server" ID="pnlStep1" Visible="false" CssClass="NormalText">
<asp:Label runat="server" ID="lblStep1Text" Text="Step 1 Instruction: "></asp:Label>
<asp:TextBox runat="server" ID="txtStep1Text" Text="" ReadOnly="true"></asp:TextBox>
<asp:Label runat="server" ID="lblStep1Image" Text="Step 1 Image: "></asp:Label>
<asp:Image runat="server" ID="imgStep1" ImageUrl="" Height="100px" Width="100px"/>
</asp:Panel>
Any help would be greatly appreciated :)
You need to have a separate url that takes the id of the image to be delivered (in this case the step id) and delivers the contents as the results with the correct MIME type. Use the url to this method as the url for the asp:Image. Normally, you'd implement this (in WebForms) as a HttpHandler. See How to return an image as the response in ASP.NET

ASP.NET SlideShowExtender retrieving images from web service, but doing nothing when executed

So on my ASP.NET solution's default page, I have a SlideShowExtender object, linked to a WebMethod which retrieves slides from an MSSQL database. Through debugging I can confirm that Slide objects are successfully created from said database, but once the page has loaded the SlideShow element does nothing.
Below is my code; I appreciate in advance any responses received. Thank you.
Edit: I forgot to mention that I've have verified the integrity of the Image URLs; they're correct.
Default.aspx (Default.aspx.cs is just a standard code-behind with an empty Page_Load method):
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="Dissertation._Default" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ToolkitScriptManager ID="scrptman" runat="server"></asp:ToolkitScriptManager>
<asp:Image ID="imgBanner" Width="800" Height="300" runat="server"/>
<br />
<asp:Label ID="lblDesc" runat="server"></asp:Label>
<asp:SlideShowExtender ID="sldShow" runat="server"
TargetControlID="imgBanner"
SlideShowServicePath="~/BannerImages.asmx"
SlideShowServiceMethod="GetPhotos"
AutoPlay="true"
ImageDescriptionLabelID="lblDesc"
Loop="true" />
</asp:Content>
BannerImages.asmx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data.SqlClient;
using System.Configuration;
using AjaxControlToolkit;
namespace Dissertation
{
/// <summary>
/// Summary description for BannerImages
/// </summary>
///
[System.Web.Script.Services.ScriptService]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class BannerImages : System.Web.Services.WebService
{
[WebMethod]
[System.Web.Script.Services.ScriptMethod]
public Slide[] GetPhotos()
{
List<Slide> images = new List<Slide>();
ConnectionStringSettings settings = System.Configuration.ConfigurationManager.ConnectionStrings["Database"];
SqlConnection conn = new SqlConnection(settings.ConnectionString);
SqlCommand cmd = new SqlCommand("Select * from sol_bannerData", conn);
SqlDataReader read = null;
try
{
conn.Open();
read = cmd.ExecuteReader();
while(read.Read())
{
images.Add(new Slide(Server.MapPath("~/cms/uploads/banners/" + read["ImageURL"].ToString()), "", read["Description"].ToString()));
}
}
catch(SqlException err)
{
images.Clear();
images.Add(new Slide("", "", "Images could not be loaded: " + err.Message));
return images.ToArray();
}
finally
{
if(read != null) read.Close();
if(conn != null) conn.Close();
}
Slide[] toReturn = images.ToArray();
return toReturn;
}
}
}
Problem solved; I used jquery.cycle.all instead.

Displaying Database Images in Gridview with HttpHandler

I am trying to use an ashx page as a http handler for images stored in an SQL server database. These Images are to be displayed in a gridview on an aspx page.
<%# WebHandler Language="C#" Class="LinqHandler" %>
using System;
using System.Web;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Configuration;
using System.IO;
public class LinqHandler : IHttpHandler {
public void ProcessRequest(HttpContext context)
{
SqlConnection connect = new SqlConnection();
connect.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlCommand command = new SqlCommand();
command.CommandText = "SELECT roomID,roomNumber,roomImage1 FROM Rooms "
+ "WHERE roomID = #roomID";
command.CommandType = System.Data.CommandType.Text;
command.Connection = connect;
SqlParameter RoomID = new SqlParameter("#roomID", System.Data.SqlDbType.Int);
RoomID.Value = context.Request.QueryString["roomID"];
command.Parameters.Add(RoomID);
connect.Open();
SqlDataReader dr = command.ExecuteReader();
dr.Read();
context.Response.BinaryWrite((byte[])dr["roomImage1"]);
context.Response.ContentType = "image/gif";
dr.Close();
connect.Close();
}
public bool IsReusable {
get {
return false;
}
}
}
for some reason, the images don't bind to the asp:Image control on the aspx page. I'm stumped as to why.
Here is the databinding snippet:
<asp:GridView ID="GridView1" runat="server"
CssClass="gridviews" PagerStyle-CssClass="pager"
DataKeyNames="roomID" AlternatingRowStyle-CssClass="alt"
AutoGenerateColumns="False" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="roomID" HeaderText="roomID" />
<asp:BoundField DataField="roomNumber" HeaderText="Room Number" />
<asp:TemplateField HeaderText="Image 1">
<ItemTemplate>
<asp:Image runat="server" ID="pic1"
ImageUrl='<%# "~/LinqHandler.ashx?roomID=" + Eval("roomID") %>'>
</asp:Image>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [roomID], [roomNumber], [roomImage1] FROM [Rooms]">
</asp:SqlDataSource>
you can use Handler.ashx for show image. For example:
<img src="Handler.ashx?roomID=1" />
this way you can show image of the one number room.
If you want to do it another way, you can use base64 in css. You dont need to use handler. For example:
<img runat="server" ID="image"/>
//code behind
var bytes = (byte[])dr["roomImage1"]);
var base64String = System.Convert.ToBase64String(bytes, 0, bytes.Length);
image.src = "data:image/gif;base64,"+ base64String;
EDIT:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var bytes = (byte[])((DataRow)e.Row.DataItem)["roomImage1"];
var base64String = System.Convert.ToBase64String(bytes, 0, bytes.Length);
var image = (Image)e.Row.FindControl("pic1");
image.ImageUrl = "data:image/gif;base64,"+ base64String;
//or
image.ImageUrl = "LinqHandler.ashx?roomID="+((DataRow)e.Row.DataItem)["roomID"];
}
}
Try as below:
<ItemTemplate>
<asp:Image ID="pic1" runat="server"
ImageUrl='<%# Eval("roomID", "LinqHandler.ashx?roomID={0}") %>'
Height="100px" Width="80px" />
</ItemTemplate>
It turns out that my problems stem from inserting garbage into my SQL BLOB fields. There is nothing wrong with the retrieval mechanism posted in my source code. If you are curious to see the insert statements I used, let me know and I will be glad to post them.

Categories

Resources