[RESOLVED] dynamically dispalying multiple images from database onto website.
HeLLo everyone:
I have a problem and hope you can help me. I'm attempting to dispaly MULTIPLE images from a SQL database onto a website and I'm using a combination of ASP.net and VB.net. Right now, it's just displaying one image. The website lets the user choose from a series of Articles, each article having Attachments (attachments being images). So, for example, if a user wants to know how to change his/her password, they select the article (article #907) and that particular article has four attachents (four images, stored in a different table), each image will basically walk the user through the process of changing the password. So, the number of images can dynamically change depending upon which article they choose.
I really hope I didn't lose anyone there. Anyway, I have two different files. One is documenthandler.ashx (which is basically the getimage.asp), and then the main .asp website, which displays the image. Currently, the website is just displaying the first attachment. Here's the code:
Documenthandler.ashx
<%@ WebHandler Language="VB" Class="FileHandler" %>
Imports System
Imports System.Web
Imports System.Data
Imports System.Data.SqlClient
Public Class FileHandler
Implements IHttpHandler
Const conString As String = "server/db"
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim con As SqlConnection = New SqlConnection(conString)
Dim cmd As SqlCommand = New SqlCommand("SELECT FileImage, FileType, filename FROM Attachments WHERE ArticleId=@ArticleId", con)
cmd.Parameters.AddWithValue("@ArticleId", context.Request("ArticleId"))
Using con
con.Open()
Dim myReader As SqlDataReader = cmd.ExecuteReader
If myReader.Read() Then
context.Response.Clear()
context.Response.ClearContent()
context.Response.ClearHeaders()
Dim file() As Byte = CType(myReader("FileImage"), Byte())
context.Response.ContentType = "application/octet-stream"
context.Response.AddHeader("content-disposition", "attachment;filename=" + myReader("filename"))
context.Response.BinaryWrite(file)
End If
End Using
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
And then I have the image source tag on the main page:
<asp:Image ID="image1" runat="server" ImageUrl='<%#Eval("Articleid", "~/Handlers/documenthandler-test.ashx?Articleid={0}")%>'/>
And then, I attempt to retreive the SECOND image by replacing the 0 with a 1:
<asp:Image ID="image1" runat="server" ImageUrl='<%#Eval("Articleid", "~/Handlers/documenthandler-test.ashx?Articleid={1}")%>'/>
And I get this error message:
Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
If I can get the first image to show up, then I should be able to get the rest of them to show up. I've already tried to put in a loop and an array in the documenthandler.ashx page, and it still didn't work.
Someone please help! Thanks!
Re: dynamically dispalying multiple images from database onto website.
You've got the 'concept' right but your overall logic is wrong.
You are using DocumentHandler.aspx once per image. Which is right.
But, you are passing in an index as though you can get the second image, but your SQL statement is such that it gets all 4 images, but your code after that only streams the first image.
So, the first point is, you need to add a parameter:
~/Handlers/documenthandler-test.ashx?Articleid={0}&ImageIndex=0
~/Handlers/documenthandler-test.ashx?Articleid={0}&ImageIndex=1
Then, in DocumentHandler.aspx, load your data into a dataset. Not a datareader. A dataset. Then go to the ImageIndexth row of the dataset's table. In other words, ImageIndex=1 means go to the second row of your dataset's datatable. Get the image from there. Stream it.
I've refrained from giving you code because I feel you should learn this yourself.
Re: dynamically dispalying multiple images from database onto website.
Thanks for the reply, mendhak. So let me get this straight: I load the data into a dataset (meaning, I load whatever the SQL Select statement returns into a dataset, as opposed to a datagrid), then I find someway to stream the data back to the main asp page? So that would mean I need to research Datasets and streams.
Should I use any arrays or loops at any point?
Re: dynamically dispalying multiple images from database onto website.
It's easier than you think.
You're already doing the streaming. You only need to research datasets. They're quite simple really. They're already collections so you don't have to MoveNext() on them, just specify the row number that you want.
(Example:
ds.Tables(0).Rows(5).Item("FileImage")
)
It's the source of your stream that needs to change.
These are the lines of code that will be replaced:
Code:
Dim myReader As SqlDataReader = cmd.ExecuteReader
If myReader.Read() Then
Dim file() As Byte = CType(myReader("FileImage"), Byte())
Re: dynamically dispalying multiple images from database onto website.
After doing some research, this is the code I ended up with (and still doesn't work, but I think I'm getting there):
The Parts I changed/added are bolded:
Public Class FileHandler
Implements IHttpHandler
Const conString As String = "server/db"
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim con As SqlConnection = New SqlConnection(conString)
Dim cmd As SqlCommand = New SqlCommand("SELECT FileImage, FileType, filename FROM Attachments WHERE ArticleId=@ArticleId", con)
cmd.Parameters.AddWithValue("@ArticleId", context.Request("ArticleId"))
Using con
con.Open()
Dim ds As New DataSet
Dim da As New SqlDataAdapter(cmd, con)
Dim arrContent As Byte()
Dim dr As DataRow
da.Fill(ds)
dr = ds.Tables(0).Rows(4).Item("FileImage")
arrContent = CType(dr.Item("FileImage"), Byte())
Dim conType As String = dr.Item("FileType").ToString()
Response.ContentType = conType
Response.OutputStream.Write(arrContent, 0, dr.Item("filename"))
Response.End()
con.Close()
End Using
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
Because it's not working, something tells me I'm still doing something wrong. The page is still just showing the first image, and that's it. Putting "ImageIndex=1" or "ImageIndex=2" isn't doing anything. Any ideas?
Re: dynamically dispalying multiple images from database onto website.
Sorry, putting "ImageIndex=1" or "ImageIndex=2" IS doing something, it's displaying the very first image, over and over again.
Re: dynamically dispalying multiple images from database onto website.
dr = ds.Tables(0).Rows(Convert.ToInt32(Request.QueryString("ImageIndex"))).Item("FileImage")
Why did you hardcode 4 in there?
Re: dynamically dispalying multiple images from database onto website.
Quote:
Originally Posted by mendhak
Why did you hardcode 4 in there?
Probably because I have never used VB.net in this capacity before (dynamically bringing back data). I'm basically a novice at VB.net; I've used it to insert data from a webforum into a SQL database before, which is very easy when using a stored procedure.
Anyway, I added that ImageIndex code, and its still not working. I'll keep on playing with it and see what happens. I'll let you know when, or if, I get it.
Thanks for your help, mendhak.
Re: dynamically dispalying multiple images from database onto website.
vb Code:
Dim ds As New DataSet
Dim da As New SqlDataAdapter(cmd, con)
Dim arrContent As Byte()
Dim dr As DataRow
Dim intImageIndex as Integer = Convert.ToInt32(Request.QueryString("ImageIndex"))
da.Fill(ds)
dr = ds.Tables(0).Rows(intImageIndex)
arrContent = CType(dr.Item("FileImage"), Byte())
Dim conType As String = dr.Item("FileType").ToString()
Response.ContentType = conType
Response.OutputStream.Write(arrContent, 0, dr.Item("filename"))
Response.End()
Try that?
If it's not working, post the code you have now again and tell us of any error messags.
Re: dynamically dispalying multiple images from database onto website.
Ok, I added those lines of code in the documenthandler.ashx page, and its still not working (broken images are showing up in the web browser now). Now, I believe it has something to do with my main aspx page. So I'm going to post that particular code and see if anyone can help with it.
I really think I need to put in a dataset somewhere in here. Any help would be appreciated.
Code:
<%@ Page Language="VB" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SQLClient" %>
<%@ import Namespace="System.IO" %>
<%@ import Namespace="System.Web.UI.WebControls" %>
<%@ import Namespace="System.Web.UI.HtmlControls" %>
<%@ import Namespace="System.Web.Mail" %>
<script language=vbscript runat="server">
Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
If Not Page.IsPostBack Then
Dim connStr As String = "server/db"
Dim DBReader As SqlDataReader
Dim Article As String = Request.QueryString("ArticleID")
Dim DBConnection As SqlConnection = New SqlConnection(connStr)
Dim MySQL As String = "Select * from Vw_Article Where ArticleID = " & Article
Dim DBCommand As New SqlCommand(MySQL, DBConnection)
DBConnection.Open()
DBReader = DBCommand.ExecuteReader()
DetailList.DataSource = DBReader
DetailList.DataBind()
DBReader.Close()
DBConnection.Close()
End If
End Sub
</script>
<!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>SOS KnowledgeBase</title>
</head>
<body>
<form id="form1" runat="server">
<div align="right">
<table cellspacing="0" cellpadding="2" >
<tr><td align="left" style="width: 92px"><asp:Image ID="Image1" ImageUrl="~/Images/KBlogo-black.jpg" runat="server" ImageAlign="Middle" Height="89px" Width="106px" />
</td>
<td width="710px"></td>
<td><asp:Image ID="Image2" ImageUrl="~/Images/mde_logo2.jpg" Height="86px" Width="135px" runat="server" ImageAlign="Middle" />
</td>
</tr>
</table>
</div>
<table>
<tbody>
<tr><td width="50px"></td>
<td style="width: 589px">
<asp:DataList id="DetailList" runat="server" Width="588px">
<ItemTemplate>
<table width="100%">
<tbody>
<tr>
<td class="box_title" > Article ID: </td><td><span class="subchannelname"></span><%#DataBinder.Eval(Container.DataItem, "ArticleID")%></td>
<td class="box_title" >
Title: </td><td><%#Container.DataItem("Title")%></td>
</tr>
</tbody>
</table>
<table width="100%">
<tbody>
<tr>
<td class="box_title" > Description: </td></tr>
<tr><td><%#DataBinder.Eval(Container.DataItem, "description")%></td>
</tr>
</tbody>
</table>
</table>
<table width="100%">
<tbody>
<tr>
<td class="box_title" > Walk Through: </td></tr>
<tr><td><%#DataBinder.Eval(Container.DataItem, "walkthrough")%></td>
</tr>
</tbody>
</table>
<table width="100%">
<tbody>
<tr>
<td class="box_title" > Solution: </td></tr>
<tr>
<td>
<asp:Image ID="test" runat="server" ImageUrl='<%#Eval("Articleid", "~/Handlers/documenthandler-test.ashx?Articleid={0}&ImageIndex=0")%>'/>
<asp:Image ID="test1" runat="server" ImageUrl='<%#Eval("Articleid", "~/Handlers/documenthandler-test.ashx?Articleid={0}&ImageIndex=1")%>'/>
<asp:Image ID="test2" runat="server" ImageUrl='<%#Eval("Articleid", "~/Handlers/documenthandler-test.ashx?Articleid={0}&ImageIndex=2")%>'/>
<asp:Image ID="test3" runat="server" ImageUrl='<%#Eval("Articleid", "~/Handlers/documenthandler-test.ashx?Articleid={0}&ImageIndex=3")%>'/>
</td>
</tr>
</tbody>
</table>
<table width="100%">
<tbody>
<tr>
<td class="box_title" > Comments: </td></tr>
<tr><td><%#DataBinder.Eval(Container.DataItem, "comments")%></td>
</tr>
</tbody>
</table>
</ItemTemplate>
</asp:DataList>
</td>
</tr>
</tbody>
</table>
<asp:DataList ID="DetailList1" datasourceid="attachmentqry" runat="server">
<ItemTemplate> <table>
<tbody>
<tr><td>
<asp:HyperLink
id="lnkFile"
Text='<%#Eval("FileName")%>'
NavigateUrl='<%#Eval("AttachmentId", "~/Handlers/AttachmentHandler.ashx?Attachmentid={0}ImageIndex=1")%>'
Runat="server" /></td> </tr></tbody></table></ItemTemplate> </asp:DataList>
<asp:SqlDataSource ID="attachmentqry" runat="server" ConnectionString="<%$ ConnectionStrings:SOSKB %>"
SelectCommand="SELECT AttachmentID, ArticleID, FileName, FileType, FileImage FROM Attachments WHERE (ArticleID = @ArticleID) AND (NOT (FileType = 'jpg'))">
<SelectParameters>
<asp:QueryStringParameter Name="ArticleID" Type="String" QueryStringField="ArticleID"/>
</SelectParameters>
</asp:SqlDataSource>
</form>
</body>
</html>
I really think I need to put in a dataset into here
Re: dynamically dispalying multiple images from database onto website.
You've got to step through your code. Place a breakpoint at the relevant points, you obviously know which ones, to see if the values are actually being passed as such.
Re: dynamically dispalying multiple images from database onto website.
I really don't know how to pass in the dataset into the main .aspx page. I've already tried putting in a dataset, datarow, and datagrid into the main page, but it never works.
Can anyone tell me what I'm doing wrong?
Re: dynamically dispalying multiple images from database onto website.
mendhak,
Could you please review your 4th response to this thread, and tell me what "ImageIndex" is? In your code, you put:
Code:
Dim intImageIndex as Integer = Convert.ToInt32(Request.QueryString("ImageIndex"))
Well, there's no ImageIndex column anywhere in my table so I have no idea where that is coming from. I apologize for the delayed response (it's been atleast a week but I need this for work).
Thanks alot,
-Wes
Re: dynamically dispalying multiple images from database onto website.
I got it. I basically declared and populated string arrays with image tags using VB.net.
Thanks anyway for the help.
Re: [RESOLVED] dynamically dispalying multiple images from database onto website.
Request.QueryString("ImageIndex")
It's a querystring parameter. It's this part of the URL
Documenthandler.aspx?ArticleId=197711&ImageIndex=2
Which means, the 2nd image belonging to Article # 197711