Here is my problem. I have a user control that will download a binary file (image, pdf etc.) using a link button in gridview.
<asp:GridView Visible="true" ID="GridView1" runat="server" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White"
RowStyle-BackColor="#A1DCF2" AlternatingRowStyle-BackColor="White" AlternatingRowStyle-ForeColor="#000"
AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID"/>
<asp:BoundField DataField="FileName" HeaderText="File Name"/>
<asp:TemplateField HeaderText="Action" ItemStyle-HorizontalAlign = "Center">
<ItemTemplate>
<asp:LinkButton ID="lnkDownload" runat="server" Text="Download" OnClick="DownloadFile" CommandArgument='<%# Eval("Id") %>'></asp:LinkButton>
<asp:LinkButton ID="lnkDelete" runat="server" Text="Delete" OnClick="DeleteFile" CommandArgument='<%# Eval("Id") %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind:
Protected Sub DownloadFile(sender As Object, e As EventArgs)
Dim id As Integer = Integer.Parse(TryCast(sender, LinkButton).CommandArgument)
Dim bytes As Byte()
Dim fileName As String, contentType As String
Using con As New SqlConnection(DataSource.ConnectionString)
Using cmd As New SqlCommand()
cmd.CommandText = "select FileName, PatImage, FileType from DB where Id=#Id"
cmd.Parameters.AddWithValue("#Id", id)
cmd.Connection = con
con.Open()
Using sdr As SqlDataReader = cmd.ExecuteReader()
sdr.Read()
bytes = DirectCast(sdr("PatImage"), Byte())
contentType = sdr("FileType").ToString()
fileName = sdr("FileName").ToString()
End Using
con.Close()
End Using
End Using
Response.Clear()
Response.Buffer = True
Response.Charset = ""
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = contentType
Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName)
Response.BinaryWrite(bytes)
Response.Flush()
Response.End()
End Sub
But this is not working if I have an UpdatePanel in my parent aspx page. So i googled and I found an answer; that is to place a code in RowDataBound:
Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
Dim lb As LinkButton = TryCast(e.Row.FindControl("lnkDownload"), LinkButton )
ScriptManager.GetCurrent(Me.Page).RegisterAsyncPostBackControl(lb)
End Sub
And a new error occurred. That is I can't find my linkButton inside my GridView using my code in my RowDataBound.
So i googled again, and i found out that i should add a property to my aspx page ClientIDMode="AutoID". But this is only working on framework 4.x. And I couldn't do that 'cause im currently using 3.5. Are there any remedies in my current situation?
A already found an answer, I just changed my RowDataBound content, refer to the code:
Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim LButton = CType(e.Row.FindControl("lnkDownload"), System.Web.UI.WebControls.LinkButton)
Dim scriptManager__1 = ToolkitScriptManager.GetCurrent(Me.Page)
If scriptManager__1 IsNot Nothing Then
scriptManager__1.RegisterPostBackControl(LButton)
End If
End If
End Sub
Related
I have an ASP.NET Core web site running under IIS on a server. I created a folder and want to display any pdf file in that folder in the browser using the url for the site.
https://example.com/pdf/myfile.pdf
folder structure:
c:\inetpub\wwwroot\mysite\pdf\myfile.pdf - contains pdf files
I enabled Directory Browsing for the site in IIS Manager, but I get a 404 error.
I'm on Window Server 2019 IIS version 10.
I would dispense with folder/directory browsing. You can't control the user experince and UI.
And it just we few lines of code to display the files in a web page, and then have a button to display the pdf in the browser.
So our markup is like this:
<h2>Select a PDF file to view</h2>
<br />
<div style="width:45%">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" CssClass="table table-hover">
<Columns>
<asp:BoundField DataField="Date" HeaderText="Date" ItemStyle-Width="100px" />
<asp:BoundField DataField="File Name" HeaderText="ID" />
<asp:BoundField DataField="File Size" HeaderText="Size" ItemStyle-Width="100px" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="cmdDownLoad" runat="server" Text="View"
OnClick="cmdDownLoad_Click"
Row = '<%# Container.DataItemIndex %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
And our code to pull files from a folder and shove into the above gridview looks like this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack = False Then
ShowFiles()
End If
End Sub
Sub ShowFiles()
Dim MyTable As New DataTable
MyTable.Columns.Add("Date", GetType(String))
MyTable.Columns.Add("File Size", GetType(String))
MyTable.Columns.Add("File Name", GetType(String))
MyTable.Columns.Add("FullFile", GetType(String))
'Dim strFolder = Server.MapPath("/app_data")
Dim strFolder = "c:\Test4"
Dim MyDir As New DirectoryInfo(strFolder)
Dim MyFiles() As FileInfo = MyDir.GetFiles("*.pdf")
For Each MyFile As FileInfo In MyFiles
Dim oneRow As DataRow = MyTable.Rows.Add
oneRow("Date") = MyFile.LastAccessTime.ToShortDateString
oneRow("File Size") = Int(MyFile.Length / 1024) & " KB"
oneRow("File Name") = MyFile.Name
oneRow("FullFile") = MyFile.FullName
Next
ViewState("MyTable") = MyTable
GridView1.DataSource = MyTable
GridView1.DataBind()
End Sub
The result is thus this:
So, now all we need is the button code to display the pdf in the browser.
This will work:
Protected Sub cmdDownLoad_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim RowID = btn.Attributes.Item("Row")
Dim MyTable As DataTable = ViewState("MyTable")
With MyTable.Rows(RowID)
ShowPdf(.Item("File Name"), .Item("FullFile"))
End With
End Sub
Sub ShowPdf(strFileOnlyName As String, strFile As String)
Dim pDFData As Byte()
pDFData = File.ReadAllBytes(strFile)
Response.Buffer = False ' //transmitfile self buffers
Response.Clear()
Response.ClearContent()
Response.ClearHeaders()
Response.AddHeader("Accept-Header", pDFData.Length.ToString())
Response.AddHeader("Content-Length", pDFData.Length.ToString())
Response.AddHeader("Content-Disposition", "inline; filename=" & strFileOnlyName)
Response.AddHeader("Expires", "0")
Response.AddHeader("Cache-Control", "private")
Response.ContentType = "application/pdf"
Response.AddHeader("Accept-Ranges", "bytes")
Response.BinaryWrite(pDFData)
Response.Flush()
Response.End()
End Sub
So you can click on the button - it will display the PDF in the browser. If you hit back, then you back to the grid, and you can then view another file.
I am trying to copy a row from a gridview to be displayed on a new page through a button in one of the columns in the gridview. I have my gridview populated from an Access database that is linked to my project. I have tried several different things, but nothing will display the row information when the project is ran. The current code I am trying from the actual dataview is:
Example 1a
<asp:GridView ID="Grid1" runat="server" Width ="90%" AutoGenerateColumns="false" OnRowDeleting="Grid1_RowDeleting" DataKeyNames="Title">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Console" HeaderText="Console" />
<asp:BoundField DataField="Year_Released" HeaderText="Year Released" />
<asp:BoundField DataField="ESRB" HeaderText="ESRB Rating" />
<asp:BoundField DataField="Score" HeaderText="Personal Score" />
<asp:BoundField DataField="Publisher" HeaderText="Publisher" />
<asp:BoundField DataField="Developer" HeaderText="Developer" />
<asp:BoundField DataField="Genre" HeaderText="Genre" />
<asp:BoundField DataField="Purchase" HeaderText="Purchase Date" />
<asp:TemplateField ItemStyle-Width="7%" ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="lnkDetails" runat="server" Text="View" PostBackUrl='<%# "~/ViewDetails.aspx?RowIndex=" & Container.DataItemIndex %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the codebehind code on the page where I am trying to have the code be displayed is:
Example 1b
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Me.Page.PreviousPage IsNot Nothing Then
Dim rowIndex As Integer = Integer.Parse(Request.QueryString("RowIndex"))
Dim GridView1 As GridView = DirectCast(Me.Page.PreviousPage.FindControl("Grid1"), GridView)
Dim row As GridViewRow = GridView1.Rows(rowIndex)
lblTitle.Text = row.Cells(0).Text
lblConsole.Text = row.Cells(1).Text
lblYear.Text = row.Cells(2).Text
lblESRB.Text = row.Cells(3).Text
lblScore.Text = row.Cells(4).Text
lblPublisher.Text = row.Cells(5).Text
lblDeveloper.Text = row.Cells(6).Text
lblGenre.Text = row.Cells(7).Text
lblPurchase.Text = row.Cells(8).Text
End If
End Sub
I have also tried another set of code where the button on the gridview was:
Example 2a
<asp:Button ID="btnLink" runat="server" Text="View Details" PostBackUrl='<%# Eval("Title", "~/ViewDetails.aspx?Id={0}") %>'/>
Where the codebehind code is:
Example 2b
Protected Sub Page_Load(sender As Object, e As EventArgs)
If Not IsPostBack Then
Dim GameTitle As String = Request.QueryString("Id")
Dim connString As String = "PROVIDER=Microsoft.ACE.OLEDB.12.0;" + "DATA SOURCE=" + Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "App_Data" + "db1.accdb")
Using connection As New OleDbConnection(connString)
connection.Open()
Dim reader As OleDbDataReader = Nothing
Dim command As New OleDbCommand((Convert.ToString("SELECT * from [Video_Games] WHERE Title='") & GameTitle) + "'", connection)
reader = command.ExecuteReader()
While reader.Read()
lblTitle.Text = reader(0).ToString()
lblConsole.Text = reader(1).ToString()
lblYear.Text = reader(2).ToString()
lblESRB.Text = reader(3).ToString()
lblScore.Text = reader(4).ToString()
lblPublisher.Text = reader(5).ToString()
lblDeveloper.Text = reader(6).ToString()
lblGenre.Text = reader(7).ToString()
lblPurchase.Text = Convert.ToDateTime(reader(8).ToString()).ToShortDateString()
End While
End Using
End If
End Sub
End Class
I have tried making variations of both, mainly the second, but whatever I try the labels are not populated with the row information. Any assistance would be appreciated, and I can post any other code needed, like how I populated the gridview. Thank you.
It was as simple as changing the AutoEventWireup to "true" in my .aspx file.
MY search button is linked to a GridvieW, which has an edit button on every row. When I press search button, data changes and a databind() occurs.
After that, If I try to use the edit button it displays another row to edit, not the selected one(biggest problem).Both buttons work well when tested separately, but not one after another. I solved that removing GridView1.DataBind() from edit button event, but then It will require 2 clicks to display the edit template(another problem).
EDIT: I guess teh problem is in the search button. Can you give a good search code that doesn't depend of sqldatasource?
'Where data is loaded into GV
Dim SqlDataSource1 As New SqlDataSource
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
SqlDataSource1.SelectCommand = "SELECT * FROM [TABLE]"
SqlDataSource1.ConnectionString = "Conn String"
If Not IsPostBack Then
Dim conn As New SqlConnection
conn.ConnectionString = con.GetConnectionString
Dim cmd As New SqlCommand()
cmd.CommandText = "SELECT [AREA], [LEADER_USER] FROM [AREA]"
cmd.CommandType = CommandType.Text
cmd.Connection = conn
conn.Open()
Dim adpt As New SqlDataAdapter(cmd)
Dim ds As New DataSet()
adpt.Fill(ds)
GridView1.DataSource = ds
GridView1.DataBind()
conn.Close()
End If
End Sub
'Search button
Protected Sub btnSearch_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSearch.Click
Try
SqlDataSource1.SelectCommand = "SELECT * FROM TABLE WHERE id LIKE #id"
SqlDataSource1.SelectParameters.Clear()
SqlDataSource1.SelectParameters.Add(New Parameter("id", DbType.String, "%" + txtSearch.Text + "%"))
GridView1.DataSource = SqlDataSource1
GridView1.DataBind()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
'Edit button
Protected Sub EditRow(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
GridView1.EditIndex = e.NewEditIndex
GridView1.DataSource = SqlDataSource1
GridView1.DataBind()
End Sub
Markup:
<asp:TextBox ID="TextBox1" runat="server" BackColor="#D9ECFF"
style="height: 20px; width: 186px" AutoPostBack="True"></asp:TextBox>
<asp:Button ID="btnSearch" runat="server" BackColor="#0066cc"
BorderColor="#0066cc" BorderStyle="Outset" Font-Bold="True" ForeColor="White"
style=" height: 26px; width: 56px" Text="Search" />
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" CellPadding="4" OnRowEditing="EditRow"
OnRowCancelingEdit="CancelEditRow" DataKeyNames="AREA" DataMember="DefaultView">
<Columns>
<asp:BoundField DataField="AREA" HeaderText="AREA" ReadOnly="True"
SortExpression="AREA" />
<asp:TemplateField HeaderText="LEADER_USER" SortExpression="LEADER_USER">
<ItemTemplate><%#Eval("leader_user")%></ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtleaderuser" runat="server" Text='<%#Eval("leader_user")%>'/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="editButton" runat="server" CommandName="Edit"
ImageUrl="images/pencil1.png" Text="Edit" ToolTip="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:Button ID="BtnUpdate" runat="server" CommandName="Update"
Text="Update" />
<asp:Button ID="BtnCancel" runat="server" CommandName="Cancel"
Text="Cancel" />
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Please help me. How are these 2 gridview functionalities supposed to be coded to work together? This is the only way I know how to do this, but any idea is ok for me if it works. If you are a C# guy, you ca use a C#-to VB converter:
http://www.developerfusion.com/tools/convert/csharp-to-vb/
Try this :
fill_grid()
{
// populate your grid
SqlCommand cmd = new SqlCommand();
cmd.CommandText = " your select statement ";
cmd.CommandType = CommandType.Text;
cmd.Connection = this.sqlConnection1;
this.yourConnection .Open();
SqlDataAdapter adpt = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adpt.Fill(ds);
yourGrid.DataSource = ds;
yourGrid.DataBind();
this.sqlConnection1.Close();
}
Then hook to the button click event of your search button like this :
yourButton_Click ((object sender, EventArgs e)
{
GridViewRow clickedRow = ((Button)sender).NamingContainer as GridViewRow;
//Then find your parameter from your textbox in the clicked row
TextBox yourbox = (TextBox)clickedRow.FindControl("your_box");
//Here is where you would all your search logic whatever that is
}
Then you could still use your row_updating event independently of the search button click event.
you can add Where statement in page_load by if command and delete where in btnSearch_Click function. like this
if (txtSearch.Text.length()>0)
SqlDataSource1.SelectCommand += "WHERE id LIKE #id"
then it works properly
i have this button which i add in row of data however, i only add two row of the date, when click this button it give me 4 data, each date is being inserted twice meaning date A den date B den date A and den date B, what the problem
Protected Sub Button2_Click(sender As Object, e As System.EventArgs) Handles Button2.Click
Dim rowIndex As Integer = 0
Dim sc As New StringCollection()
Dim sc1 As New Date
If ViewState("CurrentTable") IsNot Nothing Then
Dim dtCurrentTable As DataTable = DirectCast(ViewState("CurrentTable"), DataTable)
Dim drCurrentRow As DataRow = Nothing
If dtCurrentTable.Rows.Count < 10 Then
For i As Integer = 1 To dtCurrentTable.Rows.Count
'extract the TextBox values
Dim box5 As TextBox = DirectCast(Gridview3.Rows(rowIndex).Cells(1).FindControl("TextBox5"), TextBox)
Dim box7 As Date = Convert.ToDateTime(box5.Text)
Dim myConn As New SqlConnection
Dim myCmd As New SqlCommand
myConn.ConnectionString = ConfigurationManager.ConnectionStrings("mydatabase").ConnectionString
Dim cmd As String
cmd = "Insert into Date values (#date) "
myCmd.CommandText = cmd
myCmd.CommandType = CommandType.Text
myCmd.Parameters.Add(New SqlParameter("#date", box7))
myCmd.Connection = myConn
myConn.Open()
myCmd.ExecuteNonQuery()
myCmd.Dispose()
myConn.Dispose()
rowIndex += 1
Next
End If
Else
' lblMessage.Text = "Cannot save as there no information recorded"
MsgBox("failed")
End If
End Sub
<asp:GridView ID="Gridview3" runat="server" AutoGenerateColumns="False"
Height="89px" ShowFooter="True" Width="303px">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="No of Available:" />
<asp:TemplateField HeaderText="New Date Available :">
<ItemTemplate>
<asp:TextBox ID="TextBox5" runat="server" />
<AjaxToolkit:CalendarExtender ID="calExtender6" runat="server"
Format="dd/MM/yyyy" OnClientDateSelectionChanged="CheckDateEalier"
TargetControlID="TextBox5" />
</ItemTemplate>
<FooterStyle Height="22px" HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" onclick="ButtonAdd_Click"
Text="Add New Row" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Protected Sub ButtonAdd_Click(sender As Object, e As System.EventArgs)
AddNewRowToGrid()
End Sub
You called the function twice, once when you declare "Handles Button2.Click" and second when you set the onclick="ButtonAdd_Click".
You need to choose one of the options.
Hope that's help
Please check in the view page. I have experienced a similar issue like this in my struts,spring,hibernate application. My action method was called twice. This is because i have give the tag for the button as submit. something like <button:submit... . Just ensure that your method is called once or twice.
I had a similar problem, I created another button and copied all codes of the first button and inserted behind the new button, now the problem has solved.
it worked for me.
I am trying to an ImageUrl to an image in a Template Field in GridView but keep getting the error:
Object reference not set to an instance of an object. on this line:
Dim imagePath As String = rowView("image_path")
I've never done this before on a GridView but had it working on a ListView.
Thanks for any help heres my code:
.APSX
<asp:GridView ID="gvImages" DataKeyNames="id" runat="server" AutoGenerateColumns="False" BorderWidth="0px" GridLines="None">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="imageId" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Image ID="imageFile" runat="server"></asp:Image>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="id" />
</Columns>
</asp:GridView>
CODE BEHIND
Protected Sub gvImages_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvImages.RowDataBound
Dim rowView As DataRowView = CType(e.Row.DataItem, DataRowView)
Dim imagePath As String = rowView("image_path")
Dim strImageUrl As String = "~/admin/images/cases/" & Request.QueryString("uid") & "/" & imagePath
Dim imageFile As System.Web.UI.WebControls.Image = CType(e.Row.FindControl("imageFile"), System.Web.UI.WebControls.Image)
imageFile.ImageUrl = strImageUrl
End Sub
I think you need to check that its a data row and not the header row
Try this
Protected Sub gvImages_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvImages.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim rowView As DataRowView = CType(e.Row.DataItem, DataRowView)
Dim imagePath As String = rowView("image_path")
Dim strImageUrl As String = "~/admin/images/cases/" & Request.QueryString("uid") & "/" & imagePath
Dim imageFile As System.Web.UI.WebControls.Image = CType(e.Row.FindControl("imageFile"), System.Web.UI.WebControls.Image)
imageFile.ImageUrl = strImageUrl
End If
End Sub
try
Dim imagePath As String = e.rowView("image_path").ToString()
If the table binded with the grid has column "image_path", then instead use an easier way....
<asp:Image id="img1" runat="server" imageUrl = '<%#Eval("image_path")%>' />
If you want to build some custome string
imageurl = '<%# String.Format("{0} - {1} - {2} - {3}", Eval("Name1"), Eval("Name2"), Session["abc"],Request["abc"]) %>'