• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1673
  • Last Modified:

Displaying a PDF File in ASP.Net

I have looked at

http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_22583313.html

and am still having problems. The table containing the links has three fields, ID, Volume, and Link. A Gridview is bound to the table and a hyperlink field has been created with the DataNavigateUrlField set to Link and the DataNavigateUrlFormatString set to {0}. (I think the problem is here, but don't know how to remedy it. The other things I have tried don't work, either.) This results in a 404 error indicating the link was not found, however the path was correct. So, I clearly don't understand how to do this. I have three reference books and none of them show this.
I would like instruction in the following:
1. How should the link field be filled, both for pdf files in wwwroot and files that are in a directory not in wwwroot. The test file is Test.pdf in  ~/Folder/Test.pdf where Folder is the folder containing Default.aspx. I have tried both  Folder/Test.pdf and Test.pdf with the same results.

2. What is the best way to archive .PDF files for anonymous users to be able to view and download, if desired?

3. How should the DataNavigateUrlFormatString be set based on the Link format in 2?

4. What is the best way to simply display a .PDF file using something like a link button? I got that to work once but lost the site and cannot reconstruct it. (I'm an old man just learning this so chalk it up to a senior moment.)

Thanks for your help.
0
rkulp
Asked:
rkulp
  • 12
  • 9
1 Solution
 
Bob LearnedCommented:
1) Hmmm, the "best" way is not always a single way.  It depends on factors like authorization, database types, personal preference, etc.  

2) SQL Server, MySQL, Oracle, etc., are good at storing files, and don't require much code to reconstruct.

3) DataNavigateUrlFormatString should be something like this:

       DataNavigateUrlFormatString="WebPage1.aspx?filename={0}"

4) I'm an old man, too, so I respect senior moments.

Bob
0
 
rkulpAuthor Commented:
Bob,

Thanks for your quick reply. I've been out of pocket for a few days and could not respond.

1 & 2) By this do you mean storing the whole pdf file as a field or simply storing the link to a location with the file? I have stored the link.
3) Well, I haven't been able to figure this one out. What is the proper control to pass the query string to? I have tried a detail view but that did not work. I have tried it without a control but that does not work. I overcame the senior moment and got a hyperlink to load the pdf but have not figured out how to have a hyperlink executed when the page loads. If I were loading a picture file, then I'd put the picture into an image field in a detail view. Not helpful for pdf files. In this case ignorance is not bliss.

Thanks a bunch.
0
 
rkulpAuthor Commented:
Bob,
I have made a very small amount of progress. At least I know how to pass the query string. At this point I have the hyperlink going to the path, but eventually I'll go to the ID and then get the path using another sqlDataSource on the display page. At least that is the plan now.

Here is my code, gleaned from several other sources, primarily a topic on p2p.wrox.com:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim sLink As String = Server.MapPath("~/Newsletters/" & Request.QueryString("Link"))
        Dim fs As New System.IO.FileStream(sLink, IO.FileMode.Open, IO.FileAccess.Read)
        Dim Buffer(fs.Length) As Byte
        fs.Read(Buffer, 0, CInt(fs.Length))
        fs.Close()
        With Response
            .BufferOutput = True
            .ClearContent()
            .ClearHeaders()
            .AddHeader("Content-Length", Buffer.Length.ToString)
            .AddHeader("content-disposition", "inline")
            .ContentType = "application/pdf"
            .BinaryWrite(Buffer)
            .Flush()
            .Close()
        End With
    End Sub

I don't know if that works or not because the file cannot be found.  I have stepped through the subroutine in debug mode and sLink is the correct full path. Clearly, I'm missing something.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Bob LearnedCommented:
If you are having problems finding the file, then I wouldn't know how to help you, other than something like a rights issue.

Bob
0
 
rkulpAuthor Commented:
Bob,

I understand your inability to help on that. What I don't understand is that a straight hyperlink will open the file but the gridview hyperlink will not.  What is the difference between the two? Debug shows exactly the same path for the Response.WriteFile argument as the hyperlink argument. The error shows the complete physical path which is also correct. If it is a permission problem, both should fail.
0
 
Bob LearnedCommented:
Review:

1) Show me how you used the "straight" hyperlink

2) Show me how you tried to use the Gridview with a HyperlinkField

Bob
0
 
rkulpAuthor Commented:
Bob,

Thanks for your extrordinary support. Here is the code. DisplayNewsletter.aspx is linked to a masterpage but the content is empty.

Source for the page with the GridView and the hyperlink.

<%@ Page Language="vb" AutoEventWireup="false" MasterPageFile="~/MD12S.Master" CodeBehind="Default.aspx.vb" Inherits="lions12S._Default1" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <asp:SqlDataSource ID="newslettersDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:lions12SConnectionString %>"
        SelectCommand="SELECT * FROM [vw_aspnet_Newsletters]"></asp:SqlDataSource>
    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"
        AutoGenerateColumns="False" DataKeyNames="NewsletterID" DataSourceID="newsletersDataSource">
        <Columns>
            <asp:HyperLinkField DataNavigateUrlFields="Link" DataNavigateUrlFormatString="DisplayNewsletter.aspx?Link={0}"
                Text="View Newsletter" />
            <asp:BoundField DataField="Volume" HeaderText="Volume" SortExpression="Volume" />
            <asp:BoundField DataField="Link" HeaderText="Link" SortExpression="Link" />
            <asp:BoundField DataField="NewsletterID" HeaderText="NewsletterID" InsertVisible="False"
                ReadOnly="True" SortExpression="NewsletterID" />
        </Columns>
    </asp:GridView>
    <br />
    <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Newsletters/Sept-Oct District Newsletter.pdf">HyperLink</asp:HyperLink>

</asp:Content>
*****************************************
Link field content:

Sept-Oct District Newsletter.pdf

**************************************************

CodeBehind for DisplayNewsletter.aspx:

Public Partial Class DisplayNewsletter
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim NewsletterPath As String = "~/Newsletters/" & Request.QueryString("Link")
        With Response
            .ClearContent()
            .ClearHeaders()
            .ContentType = "application/pdf"
            .WriteFile(NewsletterPath)
            .Flush()
            .Close()
        End With
    End Sub

End Class

****************************************

Source for DisplayNewsletter.aspx:

<%@ Page Language="vb" AutoEventWireup="false" MasterPageFile="~/MD12S.Master" CodeBehind="DisplayNewsletter.aspx.vb" Inherits="lions12S.DisplayNewsletter" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    &nbsp;

</asp:Content>
0
 
Bob LearnedCommented:
Ok, so your HyperLink had this as part of the URL:

Sept-Oct District Newsletter.pdf

Does the 'Link' field in the data source have the same value?  Are any of the values blank or invalid?

Bob

0
 
rkulpAuthor Commented:
As shown in the link field content above, they are exactly the same. There is only one record in the table for testing. There are no blank or invalid values.
0
 
Bob LearnedCommented:
If you put a breakpoint on this line, can you verify what you are getting for 'NewsletterPath'?

Dim NewsletterPath As String = "~/Newsletters/" & Request.QueryString("Link")

Bob
0
 
rkulpAuthor Commented:
I have done that. It is exactly the same as the hyperlink:

~/Newsletters/Sep-Oct District Newsletter.pdf

Frustrating, or what?
0
 
Bob LearnedCommented:
Yes, it sounds as frustrating as some my problems that I have to solve.

Does this work?

<asp:HyperLinkField DataNavigateUrlFields="Link" DataNavigateUrlFormatString="~/Newsletters/{0}" Text="View Newsletter" />

Bob
0
 
rkulpAuthor Commented:
Bob,

With "~/Newsletters/{0}" one gets illegal characters in path error. Without the double quotes it cannot find the resource /Newsletters/Sep-Oct District Newsletter.pdf or it is not available.

My next try is to put the file outside the site and set the path directly to it in the hyperlink. If that works fine, then I'll change the path in the db and make the DataNavigateUrlFormatString={0}.
I'll let you know what happens.

Thanks.

Dick
0
 
Bob LearnedCommented:
What would happen if you encode the path?

Sep-Oct%20District%20Newsletter.pdf

Bob
0
 
rkulpAuthor Commented:
Bob,

It is the same as not encoding. Also, putting in the full path and using {0} makes it not be a hyperlink.
What about making it a template field and adding a hyperlink to that? Then the user would actually click a hyperlink. I have to work out the path part. That is the next thing I'll try.

Dick
0
 
rkulpAuthor Commented:
Bob,

Using the following "hard-wired" template field worked:

           <asp:TemplateField>
                <ItemTemplate><asp:HyperLink ID="hlLink" runat="server" NavigateUrl="~/Newsletters/Sept-Oct District Newsletter.pdf" Text = "View" />
                </ItemTemplate>
            </asp:TemplateField>

Replacing
NavigateUrl="~/Newsletters/Sep-Oct District Newsletter.pdf"
with
NavigateUrl="<%# Eval("Link")  %>"
where the path in Link is now the complete relative path as in the hard-wired version yields a correct path (i.e., it evaluates properly) but the resource is still not found or is temporily unavailable.
I got this idea from http://codeproject.wordpress.com/2007/10/13/83/ but trying it with the FormatUrl command Rana has in it yielded no response at all.

Dick
0
 
Bob LearnedCommented:
Eval("Link") is missing the ~/Newsletters part.

Try this:
   NavigateUrl="<%# '~/Newsletters' & Eval('Link')  %>"

Bob

0
 
rkulpAuthor Commented:
The link had ~/Newsletters/Sep-Oct District Newsletter.pdf in it. It yielded the Error 404 and showed the path as  /Newsletters/Sep-Oct District Newsletter.pdf. I created a Newsletters directory in C:\ and copied the pdf file there. That way the link worked from the GridView. That says the "~" has no effect on the path sent. My next try is to return the data to the original value (file name only) and then use your suggestion for the NavigateUrl.
All this is on a development computer. I don't know what will happen when it is moved to a host with the data tables on a SQLServer computer and the site on another one.

Dick
0
 
Bob LearnedCommented:
Does that mean that this might work?

<asp:HyperLinkField DataNavigateUrlFields="Link" DataNavigateUrlFormatString="{0}" Text="View Newsletter" />

Bob
0
 
rkulpAuthor Commented:
I stand corrected. The setup that worked actually had the link hard-coded. The "{0}" approach leads to an error that the path has illegal characters in it. I'll keep trying.

Dick
0
 
rkulpAuthor Commented:
Bob,

I want to thank you for your patience. It is finally working on another page but I don't know exactly why. In my searching I found a neat control for embedding a PDF in a web page at

http://www.codeproject.com/aspnet/EmbedPDFinWebpages.asp.

I'm going to close this and award the points.

Dick
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 12
  • 9
Tackle projects and never again get stuck behind a technical roadblock.
Join Now