Upload Image in ASP.NET VB - asp.net

Is there any way an image can be uploaded with ASP.NET with VB?
I need an "upload" button on the ASP.NET side.
I already have an image field in the table in SQL server 2008.
Is there any way I can do this?

Add a fileupload control with:
<asp:FileUpload runat="server" id="FileUpload1" />
Add an upload button, and place this in the button click event handler:
Protected Sub btnUpload_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim bldgIDNum As Int32 = FormView_Building.SelectedValue
If FileUpload1.PostedFile IsNot Nothing AndAlso FileUpload1.PostedFile.FileName <> "" Then
Dim imageSize As Byte() = New Byte(FileUpload1.PostedFile.ContentLength - 1) {}
Dim uploadedImage__1 As HttpPostedFile = FileUpload1.PostedFile
uploadedImage__1.InputStream.Read(imageSize, 0, CInt(FileUpload1.PostedFile.ContentLength))
' Create SQL Connection
Dim con As New SqlConnection()
con.ConnectionString = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
' Create SQL Command
Dim cmd As New SqlCommand()
cmd.CommandText = "INSERT INTO Table (PrimaryKey,ImageData) VALUES (#PrimaryKey,#ImageData)"
cmd.CommandType = CommandType.Text
cmd.Connection = con
Dim PrimaryKey As New SqlParameter("#PrimaryKey", SqlDbType.Int, 32)
PrimaryKey.Value = (however you want to get it)
Dim UploadedImage__2 As New SqlParameter("#ImageData", SqlDbType.Image, imageSize.Length)
UploadedImage__2.Value = imageSize
cmd.Parameters.Add(UploadedImage__2)
con.Open()
Dim result As Integer = cmd.ExecuteNonQuery()
con.Close()
If result > 0 Then
lblMessage.Text = "File Uploaded"
End If
End If
ListView_BldgImages.DataBind()
End Sub
The database column ImageData should be varbinary(max)
Create a handler called Handler_Image.ashx with the following content:
Imports System
Imports System.Web
Imports System.Configuration
Imports System.Data.SqlClient
Public Class Handler_Image : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim con As New SqlConnection()
con.ConnectionString = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
' Create SQL Command
Dim cmd As New SqlCommand()
cmd.CommandText = "Select ImageData from Table where PrimaryKey =#PrimaryKey"
cmd.CommandType = System.Data.CommandType.Text
cmd.Connection = con
Dim ID As New SqlParameter("#PrimaryKey", System.Data.SqlDbType.Int)
ID.Value = context.Request.QueryString("PrimaryKey")
cmd.Parameters.Add(ID)
con.Open()
Dim dReader As SqlDataReader = cmd.ExecuteReader()
dReader.Read()
context.Response.BinaryWrite(DirectCast(dReader("ImageData"), Byte()))
dReader.Close()
con.Close()
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
Display the image with an image control with the following property:
ImageUrl='<%# "Handler_Image.ashx?PrimaryKey=" & Eval("PrimaryKey")%>'
Replace the connectionstring, the table name, and the primary key to suit your application

Related

ADO.net ASP.net How to Fill datatable?

I am new to this....How do I correctly fill this datatable ? The editor does not like this code, it gives me squiggles beneath the last occurrence of conn and Fill
Imports System.Data.OleDb
Imports System.Data.SqlClient
Public Class WebForm4
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connstring As String
connstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Z:\CompanyData.mdb"
Dim conn As OleDbConnection
conn = New OleDbConnection(connstring)
conn.Open()
Dim strSql As String
strSql = "select * from Company"
Dim cmd As SqlCommand
cmd = New SqlCommand(strSql, conn)
Dim da As SqlDataAdapter
da = New SqlDataAdapter
da.SelectCommand = cmd
Dim dt As DataTable
dt = New DataTable
da.Fill(dt, "Company")
End Sub
You are using an OleDb to use an MS-Access database. You should use OleDb classes for everything. You create an SqlCommand and a SqlDataAdapter, these classes work for Sql Server but not with OleDb.
Dim connstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Z:\CompanyData.mdb"
Dim strSql = "select * from Company"
Using conn = New OleDbConnection(connstring)
Using cmd = New OleDbCommand(strSql, conn)
conn.Open()
Using da = New OleDbDataAdapter
da.SelectCommand = cmd
Dim dt = New DataTable
da.Fill(dt, "Company")
End Using
End Using
I have changed a bit your code to show how to use the Using Statement. This statement is very important to keep your code clean because it closes and disposes every disposable object declared in the using line.

display table in gridview for website in vb.net

I am new to vb.net and I want to display an Access table in gridview using vb.net in an ASP.NET secnario.
Public Class Form1
Public Sub New()
InitializeComponent()
BindGrid()
End Sub
Private Sub BindGrid()
Dim constring As String = "Data Source=.\SQL2005;Initial Catalog=Northwind;User id = sa;password=pass#123"
Using con As New SqlConnection(constring)
Using cmd As New SqlCommand("SELECT * FROM Customers", con)
cmd.CommandType = CommandType.Text
Using sda As New SqlDataAdapter(cmd)
Using dt As New DataTable()
sda.Fill(dt)
GridView1.DataSource = dt
End Using
End Using
End Using
End Using
End Sub
End Class
Can someone please help me?
To use a ACCESS database you must change your connection string.
Dim constring As String = "Data Source=.\SQL2005;Initial Catalog=Northwind;User id = sa;password=pass#123"
To
http://www.connectionstrings.com/access/
Also
Using ds As New DataSet()
sda.Fill(ds)
GridView1.DataSource = ds.Table(0)
GridView1.DataBind()
End Using

Adding new object into ArrayList, currently it rewrites the last object

I am adding products to an ArrayList to display with a repeater
Protected Sub Add_Click(sender As Object, e As EventArgs) Handles Add.Click
Dim ProductID As Integer = ddProduct.SelectedValue
Dim Qty As Integer = QtyBox.Text
Dim TempProduct As OrderEntry = fillProduct(ProductID, Qty)
OrderList.Add(TempProduct)
Orders.DataSource = OrderList
Orders.DataBind()
End Sub
However, when I add a new object, it replaces the old one with a new, and I assume its because it references the old object, instead of creating a new one. Where do I create a new one?
Imports System.Data
Imports System.Data.SqlClient
Partial Class placeOrder
Inherits System.Web.UI.Page
Dim OrderList As New ArrayList
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack() Then
dataFill()
End If
End Sub
Private Sub dataFill()
fillProduct()
End Sub
Private Sub fillProduct()
Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("class_readonly").ConnectionString)
'Here bad connection string is a problem
conn.Open()
'Dim cmd As SqlCommand = conn.CreateCommand()
Dim sqlCmd As New SqlCommand()
With sqlCmd
.Connection = conn
.CommandText = "SELECT distinct ProductID, Name FROM dbo.Product;"
End With
Dim objDataAdapter As New SqlDataAdapter()
Dim objDataSet As New DataSet()
objDataAdapter.SelectCommand = sqlCmd
objDataAdapter.Fill(objDataSet)
ddProduct.DataSource = objDataSet.Tables(0)
ddProduct.DataBind()
End Sub
Protected Sub Add_Click(sender As Object, e As EventArgs) Handles Add.Click
Dim ProductID As Integer = ddProduct.SelectedValue
Dim Qty As Integer = QtyBox.Text
Dim TempProduct As OrderEntry = fillProduct(ProductID, Qty)
OrderList.Add(TempProduct)
Orders.DataSource = OrderList
Orders.DataBind()
dataFill()
End Sub
Private Function fillProduct(ByVal ProductID As Integer, ByVal Qty As Integer) As OrderEntry
Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("class_readonly").ConnectionString)
'Here bad connection string is a problem
conn.Open()
'Dim cmd As SqlCommand = conn.CreateCommand()
Dim sqlCmd As New SqlCommand()
With sqlCmd
.Connection = conn
.CommandText = "SELECT * FROM dbo.Product WHERE ProductID=#ProductID ;"
.Parameters.Add(New SqlParameter("#ProductID", SqlDbType.Int, 4)).Value = ProductID
End With
Dim objDataAdapter As New SqlDataAdapter()
Dim objDataSet As New DataSet()
objDataAdapter.SelectCommand = sqlCmd
objDataAdapter.Fill(objDataSet)
Dim dtRow As DataRow = objDataSet.Tables(0).Rows(0)
Dim Total_Cost As Decimal = Decimal.Multiply(Qty, dtRow("Wholesale_Price"))
Dim Total_Price As Decimal = Decimal.Multiply(Qty, dtRow("Retail_Price"))
Dim Profit As Decimal = Total_Price - Total_Cost
Dim productInfo As New OrderEntry(dtRow("ProductID"), Qty, Total_Cost, Total_Price, Profit, dtRow("Name"))
sqlCmd.Dispose()
conn.Dispose()
Return productInfo
End Function
End Class
As #OneFineDay points out, if each element of your array is going to be of the same type then use an object of type "List Of" instead of "ArrayList".
This is how your class should look. You are saving your list to a session variable in Add_Click. In Page_Load, you are retrieving this session variable, casting it to a List(Of OrderEntry) and assigning it back to your page level list variable. Also I have removed the unnecessary dataFill procedure. Make sure that you understand the concepts rather than just copying and pasting.
Imports System.Data
Imports System.Data.SqlClient
Partial Class placeOrder
Inherits System.Web.UI.Page
Private m_myOrderList As List(Of OrderEntry)
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack() Then fillProduct()
m_myOrderList = CType(Session("MyOrderList"), List(Of OrderEntry))
End Sub
Private Sub fillProduct()
Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("class_readonly").ConnectionString)
'Here bad connection string is a problem
conn.Open()
'Dim cmd As SqlCommand = conn.CreateCommand()
Dim sqlCmd As New SqlCommand()
With sqlCmd
.Connection = conn
.CommandText = "SELECT distinct ProductID, Name FROM dbo.Product;"
End With
Dim objDataAdapter As New SqlDataAdapter()
Dim objDataSet As New DataSet()
objDataAdapter.SelectCommand = sqlCmd
objDataAdapter.Fill(objDataSet)
ddProduct.DataSource = objDataSet.Tables(0)
ddProduct.DataBind()
End Sub
Protected Sub Add_Click(sender As Object, e As EventArgs) Handles Add.Click
If IsNothing(m_myOrderList) = True Then m_myOrderList = New List(Of OrderEntry)
Dim ProductID As Integer = ddProduct.SelectedValue
Dim Qty As Integer = QtyBox.Text
Dim TempProduct As OrderEntry = fillProduct(ProductID, Qty)
m_myOrderList.Add(TempProduct)
Session("MyOrderList") = m_myOrderList
Orders.DataSource = m_myOrderList
Orders.DataBind()
End Sub
Private Function fillProduct(ByVal ProductID As Integer, ByVal Qty As Integer) As OrderEntry
Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("class_readonly").ConnectionString)
'Here bad connection string is a problem
conn.Open()
'Dim cmd As SqlCommand = conn.CreateCommand()
Dim sqlCmd As New SqlCommand()
With sqlCmd
.Connection = conn
.CommandText = "SELECT * FROM dbo.Product WHERE ProductID=#ProductID ;"
.Parameters.Add(New SqlParameter("#ProductID", SqlDbType.Int, 4)).Value = ProductID
End With
Dim objDataAdapter As New SqlDataAdapter()
Dim objDataSet As New DataSet()
objDataAdapter.SelectCommand = sqlCmd
objDataAdapter.Fill(objDataSet)
Dim dtRow As DataRow = objDataSet.Tables(0).Rows(0)
Dim Total_Cost As Decimal = Decimal.Multiply(Qty, dtRow("Wholesale_Price"))
Dim Total_Price As Decimal = Decimal.Multiply(Qty, dtRow("Retail_Price"))
Dim Profit As Decimal = Total_Price - Total_Cost
Dim productInfo As New OrderEntry(dtRow("ProductID"), Qty, Total_Cost, Total_Price, Profit, dtRow("Name"))
sqlCmd.Dispose()
conn.Dispose()
Return productInfo
End Function
End Class
OK so it's an ASP.NET webpage. After you click on the button, it's posting the page back to the server. OrderList does not persist between calls and is reinitialised with each click. Try adding OrderList to a session variable as follows in your button click procedure :
OrderList.Add(TempProduct)
Session("OrderList") = OrderList
and in your page load event, insert:
OrderList = Session("OrderList")
Also your dataFill procedure is superfluous. Delete that procedure and replace calls to dataFill with fillProduct. It's not an error but it's untidy.

Using Eval function in my code behind?

Here's my code:
Partial Class VideoPlayer
Inherits System.Web.UI.Page
Protected strFileName As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim con As New OleDbConnection
Dim dbProvider As String
Dim dbSource As String
Dim vidID As Integer = Integer.Parse(Request.QueryString("ID"))
dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;"
dbSource = "Data Source = |DataDirectory|/webvideos.mdb"
con.ConnectionString = dbProvider & dbSource
con.Open()
Dim strSQL As String = "SELECT * FROM Videos WHERE ID=" & vidID
strFileName = "videos/TrainingVideos/" & Eval("Filename")
con.Close()
End Sub
End Class
So when I run the code, it tells me it can't run Eval on my string. What am I missing?
Eval will work in your .aspx code with a DataBoundControl.
When in code-behind, you are setting up the connectionstring, sql query and other variables but you are not actually executing the query.
So your code should be something like below:
Dim con As New OleDbConnection
Dim dbProvider As String
Dim dbSource As String
Dim vidID As Integer = Integer.Parse(Request.QueryString("ID"))
dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;"
dbSource = "Data Source = |DataDirectory|/webvideos.mdb"
con.ConnectionString = dbProvider & dbSource
con.Open()
Dim strSQL As String = "SELECT * FROM Videos WHERE ID=" & vidID
//Create an OleDbCommand object.
//Pass in the SQL query and the OleDbConnection object
Dim cmd As OleDbCommand = New OleDbCommand(strSQL, con)
//Execute the command
Dim reader As OleDbDataReader = cmd.ExecuteReader
//Read the first record from the reader
reader.Read()
strFileName = "videos\TrainingVideos\" & reader(1)
con.Close()
First the most important, you are open for sql-injection here:
"SELECT * FROM Videos WHERE ID=" & vidID
Use sql-parameters instead.
You can use Eval only in a databinding context. So you need to call Me.DataBind before.
Me.DataBind()
Dim fileName = Me.Eval("Filename").ToString()
strFileName = System.IO.Path.Combine("videos/TrainingVideos", fileName)
However, i don't know what you're actually trying to achieve here. Why do you need it at all?
Global variable, forgot to add it up there.
Then access it directly.

Downloading a file from SQL Server - ArgumentOutOfRangeException

I'm trying to download files from an SQL Server 2012 database using GridView. I am getting an ArgumentOutOfRangeException giving me this error:
Index was out of range. Must be non-negative and less than the size of the collection.
on:
Dim fileid As Integer = Convert.ToInt32(GridView1.DataKeys(gvrow.RowIndex).Value.ToString())
Code concerned:
Protected Sub lnkDownload_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim lnkbtn As LinkButton = TryCast(sender, LinkButton)
Dim gvrow As GridViewRow = TryCast(lnkbtn.NamingContainer, GridViewRow)
Dim fileid As Integer = Convert.ToInt32(GridView1.DataKeys(gvrow.RowIndex).Value.ToString())
Dim name As String, type As String
Dim con As New SqlConnection("Data Source=BRIAN-PC\SQLEXPRESS;Initial Catalog=master_db;Integrated Security=True;")
con.Open()
Using cmd As New SqlCommand()
cmd.CommandText = "Select content_name, content_type, content_file from content where content_id=#Id"
cmd.Parameters.AddWithValue("#Id", fileid)
cmd.Connection = con
con.Open()
Dim dt As DataTable = GetData(cmd)
If dt IsNot Nothing Then
download(dt)
End If
End Using
End Sub
Public Function GetData(ByVal cmd As SqlCommand) As DataTable
Dim dt As New DataTable
Dim strConnString As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnStringDb1").ConnectionString()
Dim con As New SqlConnection(strConnString)
Dim sda As New SqlDataAdapter
cmd.CommandType = CommandType.Text
cmd.Connection = con
Try
con.Open()
sda.SelectCommand = cmd
sda.Fill(dt)
Return dt
Catch ex As Exception
Response.Write(ex.Message)
Return Nothing
Finally
con.Close()
sda.Dispose()
con.Dispose()
End Try
End Function
Protected Sub download(ByVal dt As DataTable)
Dim bytes() As Byte = CType(dt.Rows(0)("Data"), Byte())
Response.Buffer = True
Response.Charset = ""
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = dt.Rows(0)("ContentType").ToString()
Response.AddHeader("content-disposition", "attachment;filename=" & dt.Rows(0)("Name").ToString())
Response.BinaryWrite(bytes)
Response.Flush()
Response.End()
End Sub
gvrow.RowIndex at time of debugging is 0.
Full Code:
Imports System.Data.SqlClient
Imports System.Data
Imports System.IO
Partial Class Documents
Inherits System.Web.UI.Page
Protected Sub btnUploadContent_Click(sender As Object, e As EventArgs) Handles btnUploadContent.Click
Dim filePath As String = FileUpload.PostedFile.FileName
Dim filename As String = Path.GetFileName(filePath)
Dim ext As String = Path.GetExtension(filename)
Dim contenttype As String = String.Empty
Select Case ext
Case ".doc"
contenttype = "application/vnd.ms-word"
Exit Select
Case ".docx"
contenttype = "application/vnd.ms-word"
Exit Select
Case ".xls"
contenttype = "application/vnd.ms-excel"
Exit Select
Case ".xlsx"
contenttype = "application/vnd.ms-excel"
Exit Select
Case ".jpg"
contenttype = "image/jpg"
Exit Select
Case ".png"
contenttype = "image/png"
Exit Select
Case ".gif"
contenttype = "image/gif"
Exit Select
Case ".pdf"
contenttype = "application/pdf"
Exit Select
End Select
If contenttype <> String.Empty Then
Dim fs As Stream = FileUpload.PostedFile.InputStream
Dim br As New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(fs.Length)
'insert the file into database
Dim strQuery As String = "INSERT INTO [master_db].[dbo].[content] ([content_name],[content_type],[content_file]) VALUES (#Name, #ContentType, #Data)"
Dim cmd As New SqlCommand(strQuery)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = filename
cmd.Parameters.Add("#ContentType", SqlDbType.VarChar).Value() = contenttype
cmd.Parameters.Add("#Data", SqlDbType.Binary).Value = bytes
InsertUpdateData(cmd)
lblMessage.ForeColor = System.Drawing.Color.Green
lblMessage.Text = "File Uploaded Successfully"
Else
lblMessage.ForeColor = System.Drawing.Color.Red
lblMessage.Text = "File format not recognised." + " Upload Image/Word/PDF/Excel formats"
End If
End Sub
Protected Sub lnkDownload_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim lnkbtn As LinkButton = TryCast(sender, LinkButton)
Dim gvrow As GridViewRow = TryCast(lnkbtn.NamingContainer, GridViewRow)
Dim fileid As Integer = Convert.ToInt32(GridView1.DataKeys(gvrow.RowIndex).Value.ToString())
Dim name As String, type As String
Dim con As New SqlConnection("Data Source=BRIAN-PC\SQLEXPRESS;Initial Catalog=master_db;Integrated Security=True;")
con.Open()
Using cmd As New SqlCommand()
cmd.CommandText = "Select content_name, content_type, content_file from content where content_id=#Id"
cmd.Parameters.AddWithValue("#Id", fileid)
cmd.Connection = con
con.Open()
Dim dt As DataTable = GetData(cmd)
If dt IsNot Nothing Then
download(dt)
End If
End Using
End Sub
Public Function GetData(ByVal cmd As SqlCommand) As DataTable
Dim dt As New DataTable
Dim strConnString As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnStringDb1").ConnectionString()
Dim con As New SqlConnection(strConnString)
Dim sda As New SqlDataAdapter
cmd.CommandType = CommandType.Text
cmd.Connection = con
Try
con.Open()
sda.SelectCommand = cmd
sda.Fill(dt)
Return dt
Catch ex As Exception
Response.Write(ex.Message)
Return Nothing
Finally
con.Close()
sda.Dispose()
con.Dispose()
End Try
End Function
Protected Sub download(ByVal dt As DataTable)
Dim bytes() As Byte = CType(dt.Rows(0)("Data"), Byte())
Response.Buffer = True
Response.Charset = ""
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = dt.Rows(0)("ContentType").ToString()
Response.AddHeader("content-disposition", "attachment;filename=" & dt.Rows(0)("Name").ToString())
Response.BinaryWrite(bytes)
Response.Flush()
Response.End()
End Sub
Public Function InsertUpdateData(ByVal cmd As SqlCommand) As Boolean
Dim strConnString As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnStringDb1").ConnectionString()
Dim conn As New SqlConnection("Data Source=BRIAN-PC\SQLEXPRESS;Initial Catalog=master_db;Integrated Security=True;")
cmd.CommandType = CommandType.Text
cmd.Connection = conn
Try
conn.Open()
cmd.ExecuteNonQuery()
Return True
Catch ex As Exception
Response.Write(ex.Message)
Return False
Finally
conn.Close()
conn.Dispose()
End Try
End Function
End Class
What is happening and why?
replace the error line with this:
Dim selectedRow As Integer = Me.GridView1.CurrentRow.Index
Dim fileid As Integer = Convert.ToInt32(Me.GridView1.Item(1,gvrow.RowIndex).Value.ToString())
Replace the number 1 with the index of the cell that contains the fileid (ie if its the 0 for the first cell, 1 for the second and so on)
Let me know if this works. Am a C# developer so conversions may differ.
pass the RowIndex via CommandArgument and use it to retrieve the DataKey value
add the below line on Button
CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>'
and add the below line on Server Event
Dim Index As Integer = Integer.Parse(e.CommandArgument.ToString())
Dim val As String = DirectCast(Me.grid.DataKeys(Index)("YourDataKeyName"), String)
Update:
See this samples :
sample1
sample 2
I ran into this a while ago myself replacing a predecessors data adapter's with data readers for obvious reasons.
My fix was simple:
if (dt.Rows.Count == 0)
//do stuff
else
//do nothing
GV.DataSource = new DataTable();
you're also loading with a datatable, so that should make deploying it easier.
The reason in your specific case is the exception is thrown when no data is passed to the GV.

Resources