Issue with downloading PDF file using HTTP GET on IE7/8

Using a DataGridView to display a list of statements, with one column as a LinkButton for downloading in PDF format. Works perfectly in most browsers except IE7 & IE8 - not sure why.

<asp:GridView ID="dgvEStatements" runat="server" EnableSortingAndPagingCallbacks="False"
    EnableViewState="true" GridLines="Vertical" Width="100%" AutoGenerateColumns="False" CssClass="gridheader"
    EmptyDataText="<%$ Resources:IBEStatements, dgvEStatements_NoRows %>" OnPageIndexChanging="dgvEStatements_PageIndexChanging"
    OnRowCommand="dgvEStatements_RowCommand" OnRowDataBound="dgvEStatements_RowDataBound">
    <Columns>
        <asp:BoundField DataField="Date" HeaderText="<%$ Resources:IBEStatements, dgvEStatements_DateHeader %>"
            HeaderStyle-CssClass="lhs">
            <ItemStyle CssClass="lhs" />
        </asp:BoundField>
        <asp:BoundField DataField="Description" HeaderText="<%$ Resources:IBEStatements, dgvEStatements_DescriptionHeader %>"
            HeaderStyle-CssClass="lhs" />
        <asp:BoundField DataField="DocumentType" Visible="false" HeaderText="<%$ Resources:IBEStatements, dgvEStatements_DocumentTypeHeader %>"
            HeaderStyle-CssClass="lhs">
            <ItemStyle CssClass="lhs" />
        </asp:BoundField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:LinkButton ID="lnkDownloadEStatement" runat="server" Text="<%$ Resources:IBEStatements, lnkDownloadEStatement %>" />
            </ItemTemplate>
            <ItemStyle CssClass="rhs" />
        </asp:TemplateField>
    </Columns>

</asp:GridView>

The RowDataBound event for the Grid:

protected void dgvEStatements_RowDataBound(object sender, GridViewRowEventArgs e)
{

if (e.Row.RowType == DataControlRowType.DataRow)
{
    LinkButton lnkEStatement = (LinkButton)e.Row.FindControl("lnkDownloadEStatement");

    string fileId = DataBinder.Eval(e.Row.DataItem, "StatementID").ToString();
    lnkEStatement.Attributes.Add("onclick", "javascript:EStatementDownload('" + fileId + "'); return false;");
}        
}

Javascript function for calling the page that generates the PDF:

function EStatementDownload(fileid) {
var iframe = document.createElement("iframe");
iframe.src = "EStatementFile.ashx?fileid=" + fileid;
iframe.style.display = "none";
document.body.appendChild(iframe);
}

Code behind for EStatementFile.ashx:

public void ProcessRequest(HttpContext context)
{
try
{
string args = context.Request.QueryString["fileid"].ToString();

int statementID = 0;
int.TryParse(args, out statementID);

string documentID = String.Empty;
string accountnumber = String.Empty;
DateTime fileDate = DateTime.MinValue;

foreach (EStatement item in EStatementListing.EStatements)
{
if (statementID == item.StatementID)
{
    documentID = item.DocumentID;
    accountnumber = item.AccountNumber;
    fileDate = item.DocumentDate;
    break;
}
}

EStatementFacade estatementFacade = new EStatementFacade();
EStatement estatement = estatementFacade.GetEStatement(documentID, accountnumber, fileDate);
if (estatement.Document != null)
{
    context.Response.Clear();
    context.Response.ContentType = "Application/pdf";
    context.Response.Cache.SetCacheability(HttpCacheability.Private);
    context.Response.AppendHeader("Cache-Control", "private; must-revalidate");
    context.Response.AppendHeader("Pragma", "private");
    context.Response.AddHeader("content-disposition", "attachment; filename=" + fileDate.ToString("ddMMyyyy") + ".pdf");
    context.Response.BinaryWrite(estatement.Document);
    context.Response.Flush();                                      
}
}
catch (Exception ex)
{
}
finally
{
context.ApplicationInstance.CompleteRequest();
}
}

When Linkbutton is clicked, Firebug shows relevant javascript info:

Note: If I call context.Response.End() after Flush(), exception occurs but download dialog still displays in all browsers except IE7 & IE8.

context.Response.End(); 'context.Response.End()' threw 'System.Threading.ThreadAbortException' base {System.SystemException}: {...}

Possible issue with iFrame?

PS: Save image at the end for full view

Answer №1

Could you give this a try?

    Response.Buffer = true;
            Response.Clear();
            Response.ClearContent();
            Response.ClearHeaders();
            Response.ContentType = "application/pdf";
            Response.AddHeader(
              "Content-Disposition",
              string.Format("attachment; filename={0}",filename)
            );
            // send pdf bytes to the browser
            Response.OutputStream.Write(estatement.Document, 0, estatement.Document.Length);
            Response.End();

Answer №2

Check out this post on stackoverflow where I shared a similar issue.

It seems that IE8 and below struggle with the Cache-control header, leading to problems downloading static content like PDFs.

Source

Answer №3

Here are a couple of key points to consider:

1) It is vital to clear all headers before crafting your response in the handler. This issue was resolved by Microsoft Security Bulletin MS11-100, where the Cache-Control header was mistakenly set to no-cache="Set-Cookie". Refer to this blog post for more details:

// snip...

if (estatement.Document != null)
{
    context.Response.ClearHeaders();
    context.Response.Clear();
    context.Response.ContentType = "Application/pdf";
    // snip...

2) Instead of generating an iframe each time a user downloads a PDF, consider setting the window.location property. This approach avoids adding unnecessary iframes to the document and should maintain the same functionality:

function EStatementDownload(fileid) {
    window.location = "EStatementFile.ashx?fileid=" + fileid;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Updating the content with HTML and JavaScript

Hello everyone, I am currently working on a project to change the content of a div using JavaScript for educational purposes. Here is what I have done so far - <div id="navbar"> ... <ul> <li> <text onclick="getWordProcessing() ...

White border appears when hovering over MUI TextField

I've been troubleshooting this issue for what seems like an eternity. I've combed through Chrome's inspect tool, searching for any hover styles on the fieldset element, but to no avail. Here's my dilemma... I simply want a basic outline ...

"Customizing the gaps between cluster bars on AmCharts JS for a clean and professional

Previously, I utilized the AmCharts flash version where creating clustered column/bar charts like the image below was a breeze. In that setup, the clustered bars were tightly packed with no spacing in between. However, transitioning to the JS version of Am ...

Executing ws.send from the controller in a Node.js environment

In my project, I am looking to send a websocket using express-ws from a different controller rather than through a route. In my server.js file, I have the following code: var SocketController = require('./routes/ws.routes'); var app = express(); ...

Tips for integrating JSON data into an accordion component in a React.js application

{ "message": "", "data": [{ "root": "Expenditure", "root_seq": 4, "group_id": 4000, "subgroup_seq": 18, "group_seq": 5, "rootgroup_id": 4, "subgroup": "Workshop Expenses", ...

Obtain the content from a dynamically generated dropdown menu and incorporate it into a separate file

My website features two dropdown menus - one for selecting countries and another for cities. The country menu is populated with data from a database, and once a country is selected, the city dropdown is dynamically filled with corresponding cities using a ...

Issue with Magento site: Clicking on thumbnail photo does not update the large photo on mobile devices

As I navigate through a Magento site, I encounter a problem with the thumbnail images not reloading the larger image when clicked. Instead, the browser jumps to the top of the page and a hash symbol gets added to the URL. Based on this behavior, I suspect ...

JavaScript: Finding the full Base-URL - A Step-by-Step Guide

Is there a way to incorporate JavaScript into external files without relying on the use of base/root URLs in HTML/PHP templates? Everything is functioning properly except for the need to determine the base/root URL in an included JS file. Dilemma: I am se ...

How can Vue.js implement a satisfactory method for synchronizing computed values with asynchronous data?

Imagine retrieving a list of products from the state manager in your Vue.js component, where a computed property is then used to process this list for display on the DOM. <template> <span>{{ computedProducts }}</span> </template> ...

Having trouble running npm start with Express generator

After installing Express Generator according to the instructions on the website, I encountered an issue when trying to run npm start. My Windows system has npm 6.4.1 and node v10.15.3 installed. > [email protected] start C:\Users\ONLINEW ...

Why is the renderer using viewport and scissor in Three.js resulting in a fully black canvas?

My user interface setup consists of two vertical windows - the left for the canvas and renderer, and the right for the UI components. Within this UI layout, I plan to include special viewers like a top view window. I have implemented the viewports and sc ...

Utilizing jQuery to apply a class to a targeted element when clicked

I'm currently working on animating a menu item where it expands to the left when hovered over, and contracts back when the mouse moves out. This part is functioning as expected. Additionally, I am trying to apply a specific color to the button by add ...

Is there a way to send an array of objects as parameters in JavaScript?

I have an array of objects with the same key name. My goal is to pass each address key inside those objects as a parameter to my API. How can I achieve this? The response I receive looks something like this: { '0': { address: 'abcd' }, ...

"Implementing SpellChecking Functionality Within the Code-Behind

Is there a way to verify spelling programmatically? I have only found methods for using it with UI controls. <TextBox SpellCheck.IsEnabled="True" Height="20" Width="100"/> What I need is a function like boolean CheckSpell(string word) I do not re ...

What is the process of importing a JSON data file and utilizing it within a React component?

As a beginner in React, I am struggling with the concepts of importing, exporting, and rendering components. I have a fakeData.json file within the same src/components folder as the component I want to render. Let's take a look at the structure: < ...

Exploring Django's AJAX filter capabilities for streamlined list filtering

I've been trying to create a filter that can sort through a list when a certain option value is clicked. I know there are similar questions out there, but for some reason, I just can't seem to grasp it. views.py def gps_list(request): selec ...

Getting the version from package.json in Next.js can be easily achieved by accessing the `version

In my quest to retrieve the "version" from the package.json in a Next.js application, I encountered a roadblock. I attempted using process.env.npm_package_version, similar to how it is done in a Node application, but unfortunately, it returned undefined. ...

When using a jsonp ajax call, the response is successfully returned as json in Firebug, but unfortunately it

After encountering a jsonp cross domain ajax query, I am facing an issue where the jQuery ajax function's error part is triggered despite receiving a status of 200 OK and a status text of success. Even though I can monitor the response in Firebug and ...

Troubleshooting an Issue with MediaStreamRecorder in TypeScript: Dealing with

I've been working on an audio recorder that utilizes the user's PC microphone, and everything seems to be functioning correctly. However, I've encountered an error when attempting to record the audio: audioHandler.ts:45 Uncaught TypeError ...

The API is now configured to provide a single result rather than returning multiple results in response to an 11ty/elevent

In my 11ty project (static site generator), I am fetching property data and then using it in a Promise.all call to: fetch all property images fetch tenancy application URLs After that, I combine these into one array named allData for my pages. The image ...