Using VS2013 (asp.net, VB) and SQL Server 2012.
I have a table in my database that consists of columns ID, Name and ProfilePic. ProfilePic has a type of image.
I want to display a list of ALL of the images in a gridview. Looking at google I can only find examples where someone is selecting an image based on an ID which is not what I want.
Here is my imageHandler.ashx:
<%# WebHandler Language="VB" Class="profilePICHandler" %>
Imports System
Imports System.Web
Imports System.Data.SqlClient
Public Class profilePICHandler : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim con As New SqlConnection()
con.ConnectionString = ConfigurationManager.ConnectionStrings("nefsaConnectionString").ConnectionString
' Create SQL Command
Dim cmd As New SqlCommand()
cmd.CommandText = "select * from ProfilePics"
cmd.CommandType = System.Data.CommandType.Text
cmd.Connection = con
con.Open()
Dim dReader As SqlDataReader = cmd.ExecuteReader()
dReader.Read()
context.Response.BinaryWrite(DirectCast(dReader("profilepic"), 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
On my aspx page I have this
<asp:GridView ID="gridSelectAPic" runat="server"
AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Image">
<ItemTemplate>
<asp:Image runat="server"
ImageUrl='<%# "ProfilePICHandler.ashx"%>'
ID="profilePIC" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And on the code behind I have this
Dim dt As New DataTable
Dim conn As New SqlConnection(ConnectionString)
Using conn
Dim ad As New SqlDataAdapter("Select * from ProfilePics", conn)
ad.Fill(dt)
End Using
gridSelectAPic.DataSource = dt
gridSelectAPic.DataBind()
I am at a bit of a loss how to proceed so any help greatly appreciated
Its because your handler is implemented wrong. You will need a querystring to tell the handler which image you have to retrieve.
You can use asp:ImageField for brevity and readability. Markup
<asp:ImageField HeaderText="Image"
DataImageUrlField="EmployeeID"
DataImageUrlFormatString="ProfilePICHandler.ashx?id={0}" />
<asp:TemplateField HeaderText="Image">
<ItemTemplate>
<asp:Image runat="server"
ImageUrl='<%# Eval("EmployeeID", "ProfilePICHandler.ashx?id={0}")%>'
ID="profilePIC" />
</ItemTemplate>
</asp:TemplateField>
Now fetch from querystring from the generic handler like this
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim con As New SqlConnection()
con.ConnectionString = ConfigurationManager.ConnectionStrings("nefsaConnectionString").ConnectionString
Dim cmd As New SqlCommand()
cmd.CommandText = String.Format("select profilepic from ProfilePics where EmployeeID=", context.Request.QueryString("id"))
cmd.CommandType = System.Data.CommandType.Text
cmd.Connection = con
con.Open()
Dim dReader As SqlDataReader = cmd.ExecuteReader()
dReader.Read()
context.Response.BinaryWrite(DirectCast(dReader("profilepic"), Byte()))
dReader.Close()
con.Close()
End Sub
Please note that
I have given the name EmployeeID for your PK in DB
Your handler name is Pascalcased on Eval and CamelCased at its implementation. Is it a typo?
Haven't parameterized the query for brevity.
Related
i hope you can help with my issue. I'm trying to fill out a form from my database using a datatable. All seems to work fine but i get no data returned. Can anyone explain why? I've looked at the debug and there seems to be no errors and nothing looks like its failed. Here's my code behind (vb.net)
Imports System.Data
Imports System.Data.SqlClient
Imports System.Net.Mail
Partial Class _Default
Inherits System.Web.UI.Page
Private Sub getData(ByVal user As String)
Dim dt As New DataTable()
Dim constr As String = ConfigurationManager.ConnectionStrings("conn").ConnectionString
Dim connection As New SqlConnection(constr)
connection.Open()
Dim sqlCmd As New SqlCommand("SELECT * from tblContent WHERE CID = #ID", connection)
Dim sqlDa As New SqlDataAdapter(sqlCmd)
sqlCmd.Parameters.AddWithValue("#ID", Request.QueryString("ID"))
sqlDa.Fill(dt)
If dt.Rows.Count > 0 Then
ID.Text = dt.Rows(0)("CID").ToString
TextBox2.Text = dt.Rows(0)("Heading").ToString
TextBox1.Text = dt.Rows(0)("ContText").ToString
Label2.Text = dt.Rows(0)("Location").ToString
End If
connection.Close()
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
If Not Page.IsPostBack Then
getData(Me.User.Identity.Name)
End If
End Sub
Presentation layer:
<h2><asp:Label ID="Label2" runat="server" Text=""></asp:Label></h2>
<asp:TextBox ID="ID" runat="server" Visible="false"> </asp:TextBox><br />
<asp:Label ID="Label3" runat="server" Text="Heading" CssClass="label"></asp:Label>
<asp:TextBox ID="TextBox2" TextMode="SingleLine" Text="" runat="server"></asp:TextBox><br />
<asp:Label ID="Label1" runat="server" Text="Content" CssClass="label"></asp:Label><br />
<asp:TextBox ID="TextBox1" TextMode="MultiLine" runat="server"></asp:TextBox>
I'm passing through the ID from another page via the query string (ID=5 as an example). There is data in my database and all labels/textboxes have the right IDs etc. I just can see what's wrong?
Thanks!
You could try to pass the correct type instead of string:
Using sqlDa As New SqlDataAdapter(sqlCmd)
Dim idParam = new SqlParameter("#ID", SqlDbType.Int)
Dim id As Int32
If Not Int32.TryParse(Request.QueryString("ID"), id) Then Throw New Exception("Not a valid ID-parameter!")
idParam.Value = id
sqlDa.SelectCommand.Parameters.Add(idParam)
sqlDa.Fill(dt)
End Using
By the way, also use the Using-statement for the connection. As an aside, you don't need to open/close the connection with SqlDataAdapter.Fill(table) since that is done automatically.
I tried to make a text box which gives suggestions from database columns. However it's showing this error when i run that page .
Error -
Could not load file or assembly 'AjaxControlToolkit' or one of its dependencies. The system cannot find the file specified.
asp code
<asp:ToolkitScriptManager ID="ScriptManager1" runat="server"></asp:ToolkitScriptManager>
<asp:AutoCompleteExtender ID="autoComplete1" runat="server"
EnableCaching="true"
BehaviorID="AutoCompleteEx"
MinimumPrefixLength="2"
TargetControlID="myTextBox"
ServicePath="AutoComplete.asmx"
ServiceMethod="GetCompletionList"
CompletionInterval="1000"
CompletionSetCount="20"
CompletionListCssClass="autocomplete_completionListElement"
CompletionListItemCssClass="autocomplete_listItem"
CompletionListHighlightedItemCssClass="autocomplete_highlightedListItem"
DelimiterCharacters=";, :"
ShowOnlyCurrentWordInCompletionListItem="true"> </asp:AutoCompleteExtender>
<td><asp:TextBox ID="TextBox2" runat="server" CssClass="text_box" autocomplete="off"></asp:TextBox><br /><asp:RequiredFieldValidator
ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBox2" ErrorMessage="Please Enter Client / Company Name" style="color:#f00; font-size:11px"></asp:RequiredFieldValidator></td>
vb code
<System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
Public Class AutoComplete
Inherits System.Web.Services.WebService
Dim cn As New SqlClient.SqlConnection()
Dim ds As New DataSet
Dim dt As New DataTable
<WebMethod()> _
Public Function GetCompletionList(ByVal prefixText As String, _
ByVal count As Integer) As String()
'ADO.Net
Dim strCn As String = _
"Data Source=SONAM-PC\SQLSERVER2008R2;Initial Catalog=Brandstik2; Integrated Security=True"
cn.ConnectionString = strCn
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = cn
cmd.CommandType = CommandType.Text
'Compare String From Textbox(prefixText)
'AND String From Column in DataBase(CompanyName)
'If String from DataBase is equal to String from TextBox(prefixText)
'then add it to return ItemList
'-----I defined a parameter instead of passing value
'directly to prevent SQL injection--------'
cmd.CommandText = "select * from BrandstikTesti Where client_name like #myParameter"
cmd.Parameters.AddWithValue("#myParameter", "%" + prefixText + "%")
Try
cn.Open()
cmd.ExecuteNonQuery()
Dim da As New SqlDataAdapter(cmd)
da.Fill(ds)
Catch ex As Exception
Finally
cn.Close()
End Try
dt = ds.Tables(0)
'Then return List of string(txtItems) as result
Dim txtItems As New List(Of String)
Dim dbValues As String
For Each row As DataRow In dt.Rows
''String From DataBase(dbValues)
dbValues = row("client_name").ToString()
dbValues = dbValues.ToLower()
txtItems.Add(dbValues)
Next
Return txtItems.ToArray()
End Function
End Class
Add Top of your aspx page
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
Or You are missing dll
dropdown in gridview
<asp:TemplateField HeaderText="ProjectModifiedBy" HeaderStyle-BackColor="#C0C0C0" HeaderStyle-BorderColor="Black">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" Width="99%" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
code of web method
<WebMethod()> _
Public Function BindDropDown() As SqlDataReader
Dim strConnString As String = ConfigurationManager.ConnectionStrings("conString").ConnectionString
Dim sqlQuery As String
sqlQuery = "Sp_SelectEmpName"
Dim con As New SqlConnection(strConnString)
Dim cmd As New SqlCommand(sqlQuery, con)
cmd.CommandType = CommandType.StoredProcedure
Dim reader As SqlDataReader
con.Open()
reader = cmd.ExecuteReader()
Return reader
End Function
this is the code behind method which calls webmethod,what should i write here to bind the empname column data with dropdown of gridview
Private Sub BindDataDropDown()
End Sub
I have a comments box which has a template field which looks something like this..
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" DataSourceID="CommentsDataSource" Height="167px" Width="325px">
<Columns>
<asp:TemplateField HeaderText="Comments">
<ItemTemplate>
<div style="background-color:Silver">
<div class="avatar-frame">
<asp:Image ID="ProfilePic" runat="server"/>
</div>
<h1><%# Eval("TagLine")%></h1>
<h2><%# Eval("IfNonMemberUserName")%></h2>
<p><%# Eval("CommentBody")%></p>
</div>
</ItemTemplate>
<AlternatingItemTemplate>
<div style="background-color:White">
<div class="avatar-frame">
</div>
<h1><%# Eval("TagLine")%></h1>
<h2><%# Eval("IfNonMemberUserName")%></h2>
<p><%# Eval("CommentBody")%></p>
</div>
</AlternatingItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="CommentsDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:BookMeetConnString %>" ProviderName="<%$ ConnectionStrings:BookMeetConnString.ProviderName %>" SelectCommand="SELECT [IfNonMemberUserName], [UserAvatar], [TagLine], [CommentBody] FROM [comments] WHERE ([BookID] = ?)">
<SelectParameters>
<asp:QueryStringParameter Name="?" QueryStringField="ID" />
</SelectParameters>
</asp:SqlDataSource>
Some background:
I have an MS Access database with a table called 'userprofiles' which has a field called AvatarURL. Similiarly there is also a table called 'comments' which has lookupfield called 'UserAvatar' inside of it referring to the 'userprofiles' table's 'AvatarURL' field.
I am receiving the "'ProfilePic' is not declared. It may not be accessible due to it's permission level" error in my code behind. Intellisense is telling me that the image that has the ID 'ProfilePic' is not declared (within the DisplayData sub routine.
The problematic bit of code is:
Protected Sub DisplayData()
Dim conn As OleDbConnection = New OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
Dim sql = "SELECT * FROM userprofiles WHERE TravellerName=#f1"
Dim cmd = New OleDbCommand(sql, conn)
cmd.Parameters.AddWithValue("#f1", User.Identity.Name)
conn.Open()
Dim profileDr = cmd.ExecuteReader()
profileDr.Read()
If Not IsDBNull(profileDr("AvatarURL")) Then ProfilePic.ImageUrl = profileDr.Item("AvatarURL")
conn.Close()
End Sub
At runtime, detail.aspx works fine, but the avatars in the comment box don't show up at all. What am I doing wrong?
EDIT:
I have managed to get this far:
Protected Sub GridView2_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Dim conn As OleDbConnection = New OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
Dim sql = "SELECT * FROM userprofiles WHERE TravellerName=#f1"
Dim cmd = New OleDbCommand(sql, conn)
cmd.Parameters.AddWithValue("#f1", User.Identity.Name)
conn.Open()
Dim profileDr = cmd.ExecuteReader()
profileDr.Read()
Dim ProfilePic
If e.Row.RowType = DataControlRowType.DataRow Then
ProfilePic = e.Row.FindControl("ProfilePic")
If Not IsDBNull(profileDr("AvatarURL")) Then ProfilePic.ImageUrl = profileDr.Item("AvatarURL")
End If
conn.Close()
End Sub
However, the images still do not appear at runtime. What is wrong with this? Should I be using the datareader?
The only way to refer to get at ProfilePic is to set it at DataBind time. You'll need to wire up the GridView2_RowDataBound event by adding OnRowDataBound="GridView2_RowDataBound" to your asp:GridView tag.
You'll then get the RowDataBound event for each row (even header and footer rows, so you need to test for what type of row is currently firing the event. You can then use FindControl on the current row item to look for the current row's ProfilePic. You'll have to cast the output of that function into an Image.
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Image ProfilePic = (Image)e.Row.FindControl("ProfilePic");
ProfilePic.ImageUrl = "stuff";
}
}
As a control within a template, you can only access the control when binding, in particular in the OnRowDataBound event handler (for a GridView).
In this event handler you need to call FindControl with the ID of the wanted control and cast it to the right type (only if you need to access specific members of that type).
Try this
public string DisplayData()
Dim conn As OleDbConnection = New OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
Dim sql = "SELECT * FROM userprofiles WHERE TravellerName=#f1"
Dim cmd = New OleDbCommand(sql, conn)
cmd.Parameters.AddWithValue("#f1", User.Identity.Name)
conn.Open()
Dim profileDr = cmd.ExecuteReader()
profileDr.Read()
string imagename= profileDr("AvatarURL")
conn.Close()
return imagename
End Sub
and client side change for
<asp:Image ID="ProfilePic" **ImageUrl='<%# DisplayData()%>'** runat="server" />
This is in vb.net
The photo never show up and I have no error....???
This is how I stock the photo on The SQl DB
Sub StartUpLoad()
Dim imgName As String = FileUpload1.FileName
Dim imgSize As Int32 = FileUpload1.PostedFile.ContentLength
Dim photo As Byte() = New Byte(imgSize) {}
Dim user As String = "kdjhkjgh"
If FileUpload1.PostedFile IsNot Nothing AndAlso FileUpload1.PostedFile.FileName IsNot "" Then
If (FileUpload1.PostedFile.ContentLength > 100240) Then
Page.ClientScript.RegisterClientScriptBlock(GetType(Page), "alert depuis le codehind", String.Format("alert('{0}')", "Fichier trop gros"), True)
Else
Dim connectionString As String = WebConfigurationManager.ConnectionStrings("BecsEtMuseauxSQL").ConnectionString
Dim con As SqlConnection = New SqlConnection(connectionString)
con.Open()
Dim cmd As New SqlCommand("dbo.addPost", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("#UserName", SqlDbType.VarChar).Value = user
cmd.Parameters.Add("#titre", SqlDbType.NVarChar).Value = TextBoxTitre.Text
cmd.Parameters.Add("#description", SqlDbType.VarChar).Value = TextBoxDescrip.Text
cmd.Parameters.Add("#image", SqlDbType.Image).Value = photo
cmd.ExecuteNonQuery()
con.Close()
Page.ClientScript.RegisterClientScriptBlock(GetType(Page), "alert depuis le codehind", String.Format("alert('{0}')", "Post sauvegardé"), True)
End If
End If
End Sub
This my handler
Public Class Handler : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim connectionString As String = WebConfigurationManager.ConnectionStrings("BecsEtMuseauxSQL").ConnectionString
Dim con As SqlConnection = New SqlConnection(connectionString)
' Create SQL Command
Dim cmd As New SqlCommand()
cmd.CommandText = "Select Titre,Image from Post where ID =#IID"
cmd.CommandType = System.Data.CommandType.Text
cmd.Connection = con
Dim ImageID As New SqlParameter("#IID", Data.SqlDbType.Int)
ImageID.Value = Convert.ToInt32(context.Request.QueryString("ID"))
cmd.Parameters.Add(ImageID)
con.Open()
Dim dReader As SqlDataReader = cmd.ExecuteReader()
dReader.Read()
context.Response.BinaryWrite(DirectCast(dReader("Image"), 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
This is my asp data grid
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False"
ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="Titre" HeaderText="Titre" SortExpression="Titre" />
<asp:TemplateField HeaderText="Image">
<ItemTemplate>
<asp:Image ID="Image1" runat="server"
ImageUrl='<%# Eval("ID", "Handler.ashx?ID={0}")%>'/>
</ItemTemplate>
<ControlStyle Height="200px" />
</asp:TemplateField>
<asp:ImageField DataImageUrlField="Image">
</asp:ImageField>
</Columns>
</asp:GridView>
<br />
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:BecsEtMuseauxSQL %>"
ProviderName="<%$ ConnectionStrings:BecsEtMuseauxSQL.ProviderName %>" SelectCommand="SELECT [ID], [Titre], [Image] FROM [Post]"></asp:SqlDataSource>
Do you have any idea why my photo never show up???
Thanks for helping me!!!
I think, you response doesn't know what type of binary data you are sending (by default it is text/html). Try to set ContentType to "image/jpeg" (exactly, there must be your image file MIME).
If you download different image types it is better to store into table Post its MIME in your addPost procedure (you may use FileUpload1.PostedFile.ContentType property for this purpose) and use it in handler.
you can use context.Response.ContentType property to mention file details, so that browser can serve basic needs to rendering.
context.Response.ContentType=ImageFormat.Jpeg;