Avatar of rckrch
rckrchFlag for United States of America asked on

Showing image in image control using vb.net and asp.net

I am having a lot of difficulty trying to get the image that is stored in a database to show up in the image control on my web page.  I have successfully loaded the image into the database with the below code, and retrieving it is not a problem either - except that I cannot get the image into the image control.  I have tried mutiple different codes to get the image to load into the image control, but nothing has worked.

Can anyone help?  Below is the code snipett.

Any help would be greatly appreciated.

Thanks

asp code for the image control
             <asp:Image ID="ProfileImg" runat="server"
                            BorderStyle="None" BorderColor="Transparent"
                            ImageUrl="" Width="30%"
                            Height="50%" />

This part of the code to load the image data into database works fine:

*******************************************
Protected Sub UploadWhiteImg_Click() Handles UploadWhiteImg.Click
        If (WhiteUpload.HasFile) Then
            Dim savePath As String = "C:\My Documents\"
            Dim fileName As String = WhiteUpload.FileName
            Dim pathToCheck As String = savePath + fileName          
            Dim tempfileName As String = "White" & DieNoDrpDnLst.SelectedValue  
            fileName = tempfileName            

            WhiteUpload.SaveAs(pathToCheck)
        Else
           MessageBox("You did not specify a file to upload.")
        End If
        Dim FileText As String = WhiteUpload.PostedFile.FileName.ToString
        Dim dbcon2 As New SqlConnection("Data Source=...")
        Dim dbcmd2 As New SqlCommand("INSERT INTO PROFILEIMAGES (ProfileImage, DieNumber) VALUES (@ProfileImage, @DieNumber)")
        dbcon2.Open()
        dbcmd2.Connection = dbcon2
        Using ProfileImage As System.Drawing.Image = System.Drawing.Image.FromFile(WhiteUpload.PostedFile.FileName)
(WhiteUpload.PostedFile.FileName.LastIndexOf("\") + 1))
            Using stream As New IO.MemoryStream
                ProfileImage.Save(stream, Imaging.ImageFormat.Jpeg) 'Jpeg
                dbcmd2.Parameters.Add("@ProfileImage", SqlDbType.VarBinary).Value = stream.GetBuffer()
                dbcmd2.Parameters.AddWithValue("@DieNumber", DieNoDrpDnLst.SelectedValue)
            End Using
        End Using
        dbcmd2.ExecuteNonQuery()
        dbcmd2.Dispose()
        dbcon2.Close()
        dbcon2.Dispose()


    End Sub

*************************************
The below code is intended to return the image with a drop down list selectedindexchanged event.  It will return the image, but not in the image control.  It returns the image filling the entire screen.  I am just trying to load the image into the image control.

Protected Sub DieNoDrpDnLst_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles DieNoDrpDnLst.SelectedIndexChanged

Dim dbconimg As New SqlConnection("Data Source=io.....")
        Dim dbcmdimg As New SqlCommand("SELECT ProfileImage FROM PROFILEIMAGES WHERE DieNumber =" & DieNoDrpDnLst.SelectedValue)
        dbconimg.Open()
        dbcmdimg.Connection = dbconimg

Dim imageData As Byte() = DirectCast(dbcmdimg.ExecuteScalar(), Byte())          Context.Response.ContentType = "image/jpeg"
        Context.Response.BinaryWrite(imageData)           'ProfileImg.DataBind()
       

        dbcmdimg.Dispose()
        dbconimg.Close()
        dbconimg.Dispose()

End Sub
Visual Basic.NETASP.NET

Avatar of undefined
Last Comment
Robert Schutt

8/22/2022 - Mon
Robert Schutt

One way to do this is to move your image retrieval code to a separate page and in your main page just have this:
    Protected Sub DieNoDrpDnLst_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles DieNoDrpDnLst.SelectedIndexChanged
        ProfileImg.ImageUrl = "GetImage.aspx?id=" & DieNoDrpDnLst.SelectedValue
    End Sub

Open in new window

The new page (which as you can see above, I have called GetImage.aspx), contains in the code behind:
Imports System.Data.SqlClient

Public Class GetImage
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Try
            Using dbconimg As New SqlConnection("Data Source=....")
                Using dbcmdimg As New SqlCommand("SELECT ProfileImage FROM PROFILEIMAGES WHERE DieNumber = " & Replace(Request.QueryString("id"), "'", "''"))
                    dbconimg.Open()
                    dbcmdimg.Connection = dbconimg

                    Dim imageData As Byte() = DirectCast(dbcmdimg.ExecuteScalar(), Byte())
                    Context.Response.Clear()
                    Context.Response.ContentType = "image/jpeg"
                    Context.Response.BinaryWrite(imageData)
                    Context.Response.End()
                End Using
            End Using
        Catch ex As Exception
            ' show default image or error
        End Try
    End Sub

End Class

Open in new window

By the way; when using this method there is no need to save the uploaded files to disk. So unless you want those files for another reason, just use this code for the upload:
    Protected Sub UploadWhiteImg_Click() Handles UploadWhiteImg.Click
        If (WhiteUpload.HasFile) Then
        Else
            'MessageBox("You did not specify a file to upload.")
            Exit Sub
        End If
        Using dbcon2 As New SqlConnection("Data Source=....")
            Using dbcmd2 As New SqlCommand("INSERT INTO PROFILEIMAGES (ProfileImage, DieNumber) VALUES (@ProfileImage, @DieNumber)")
                dbcon2.Open()
                dbcmd2.Connection = dbcon2
                Using ProfileImage As System.Drawing.Image = System.Drawing.Image.FromStream(WhiteUpload.FileContent)
                    Using stream As New IO.MemoryStream
                        ProfileImage.Save(stream, Imaging.ImageFormat.Jpeg) 'Jpeg
                        dbcmd2.Parameters.Add("@ProfileImage", SqlDbType.VarBinary).Value = stream.GetBuffer()
                        dbcmd2.Parameters.AddWithValue("@DieNumber", DieNoDrpDnLst.SelectedValue)
                    End Using
                End Using
                dbcmd2.ExecuteNonQuery()
            End Using
        End Using
    End Sub

Open in new window

Of course, another method would be to just save the files to disk (instead of or besides saving to db) and set the image url to the location of that file but I guessed that was not the way you wanted to go.

EDIT: added try/catch in retrieval code.
ASKER
rckrch

Thanks very much for the reply robert_schutt, but it still does not work.  I don't get any errors during trouble shooting, but I jsut don't get the image in the image control.

Any other suggestions?

Thanks again.
ASKER
rckrch

You can see below where I put the new page code you wrote.  I just put it above my current page load code behind.  Is this where it should be?

Public Class GetImage
        Inherits System.Web.UI.Page

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Try
                Using dbconimg As New SqlConnection("Data Source=io....ld")
                    Using dbcmdimg As New SqlCommand("SELECT ProfileImage FROM PROFILEIMAGES WHERE DieNumber = " & Replace(Request.QueryString("id"), "'", "''"))
                        dbconimg.Open()
                        dbcmdimg.Connection = dbconimg

                        Dim imageData As Byte() = DirectCast(dbcmdimg.ExecuteScalar(), Byte())
                        Context.Response.Clear()
                        Context.Response.ContentType = "image/jpeg"
                        Context.Response.BinaryWrite(imageData)
                        Context.Response.End()
                    End Using
                End Using
            Catch ex As Exception
                ' show default image or error
            End Try
        End Sub

    End Class
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
       

        Dim CurCustomer As String = OEMDropDownLst.SelectedValue

        Dim CurProgram As String = PRGRAMListDrpDwn.SelectedValue
       
        Dim CurHennPlant As String = HnPltDrpDn.SelectedValue
        Dim CurAssyDesc As String = AssyNoDrpDn.SelectedValue
       
        Dim CurPartDesc As String = PrtDscDrpDn.SelectedValue
        Dim CurLineNo As String = LineNoDrpDn.SelectedValue
       
        ProgramListDataSource.SelectParam........
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Robert Schutt

No, if you already had a page called GetImage then please choose another name. If this is the new page, then don't put other code in it, just the one Page_Load function.
Robert Schutt

Depending on your settings you can debug an individual page by just pressing F5 (or the green 'Play' arrow) when you have the file active. Then I added ?id=4 (non-existent in my data) to see the error message, just for testing.
capture 0capture 1In the "Catch" I added:
Response.Write(String.Format("<pre>{0}</pre>", ex.ToString()))

Open in new window

This is useless in normal use (because the output is only used as an image) but will help in debugging.

If that page is working then you need to look at the assignment to ImageUrl, maybe you need to reference the correct location of the page, if the page you're using it on is not in the same folder.
ASKER
rckrch

I ma sorry I don't understand everything you are trying to tell me.  I am still somewhat new to this and handling images is all new for me.

I don't know what you mean by the below comment:

'No, if you already had a page called GetImage then please choose another name. If this is the new page, then don't put other code in it, just the one Page_Load function. '

I have to have the page load to handle other procedures in my application page.  I don't already have another page called GetImage.  Bottom line - I don't know where to put this code (including the public class) to make it work.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER CERTIFIED SOLUTION
Robert Schutt

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
ASKER
rckrch

Thanks very much for that explanation.  I now understand what I am 'trying' to do from a 10,000 foot level.  Separate page and using the url for that page.

I do have another question now though.  This part of your command that you sent to me:    'Replace(Request.QueryString("id"), "'", "''"))'.  I don't know where this comes from.  Why not just use the parameterized queery with the DieNumber parameter to get to the correct image in the database?  By the way - the DieNumber is not the id (index) in the database.  It is another part identification used for other searches.

Thanks very much for the help!!!!!!!!!!!!!!!
ASKER
rckrch

Thanks robert_schutt.  It works!!!  I have one last question.  How do I get the image to resize?  is there also a way to improve the image resolution?

Thanks very much for all your help!!
ASKER
rckrch

Thanks very much for all the help.  Very informative and effective at resolving the issue I had.
Your help has saved me hundreds of hours of internet surfing.
fblack61
Robert Schutt

Great!

The Replace command means that any single quote characters, that someone might add to the URL to get access to your data (called "SQL injection"), are defused so to speak. I usually add that command to anything that I put in a SQL statement string that could be tampered with. This is only a little base-level protection, much better is to use a parameterized command.

The code you posted earlier contains measurements in the image tag: Width="30%" and Height="50%". These determine the size of the image (relative to the size of the browser window!) and because the browser does the resizing, also partly the quality. If you need a specific size than it might be better to do that in the upload code, where you are already converting to jpeg format. If you want the original size then don't specify width/height in the image tag.
ASKER
rckrch

Thanks again!!
ASKER
rckrch

robert_schutt - I don't know if I reopen this question, but I ran into another problem.  The program below will work for the first entry in the database (top line), but will not pick the next one down.  I added another image for another dienumber and I get an error.  It says:

Conversion failed when converting the nvarchar value '2368.12' to data type int.

This is strange because the current dienumber for which the image is being retrieved is 2352.  It is as if the executescalar is ignoring the where clause in the sqlcommand.  During trouble shooting the QueryString in the routine below does show the correct dienumber (2352).

Can you help?

Thanks

Public Class GetImage
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Try
            Using dbconimg As New SqlConnection("Data Source=io....rd=cld")
                Using dbcmdimg As New SqlCommand("SELECT ProfileImage FROM PROFILEIMAGES WHERE DieNumber = " & Replace(Request.QueryString("id"), "'", "''"))
                    dbconimg.Open()
                    dbcmdimg.Connection = dbconimg

                    Dim imageData As Byte() = DirectCast(dbcmdimg.ExecuteScalar(), Byte())
                    Context.Response.Clear()
                    Context.Response.ContentType = "Image/jpeg"  '"image/jpeg"
                    Context.Response.BinaryWrite(imageData)
                    Context.Response.End()
                    dbcmdimg.Dispose()
                End Using
                dbconimg.Close()
                dbconimg.Dispose()
            End Using


        Catch ex As Exception
            ' show default image or error
        End Try
    End Sub

End Class
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Robert Schutt

Without knowing more about your data it's hard to say what's happening. If you store a number other than integer in a varchar field, you have to start worrying about regional settings (decimal point or comma). Can you post your table create statement and some obfuscated (depersonalised) data?
ASKER
rckrch

SubStatusCode      {"This operation requires IIS integrated pipeline mode."}      System.PlatformNotSupportedException

In the immediate window I got this from the error.  I don't know if this means anything or not relative to the table in the database.

I will give you the information from the table.
ASKER
rckrch

Here is the table design window.  There realy isn't much information in the table except to lines with the columns you see here.  One with one DieNumber and one with a different one.
Imgtabledesign.png
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
ASKER
rckrch

Changing the data type in the table to 'float' fixed the problem.  Thanks for putting the thought in my head.
Robert Schutt

ok, great! I was out for a bit and returned to find you solved it ;-)