IE7 / 8: файл PDF не будет загружаться с HTTP GET - PullRequest
0 голосов
/ 08 февраля 2012

Я использую DataGridView для отображения списка операторов. Одним из столбцов является LinkButton, который позволяет вам загружать это конкретное утверждение в формате PDF. Мой код прекрасно работает во всех браузерах, кроме IE7 и IE8. Я понятия не имею, почему это так.

       <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>

Событие RowDataBound для сетки делает следующее:

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 для вызова страницы, которая создает PDF:

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

Наконец, код для 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();
        }
    }

Когда нажимается кнопка Link на сетке, в Firebug отображается следующая информация javascript, которая может быть полезна при поиске проблемы: Firebug Output

Что-то интересное, чтобы заметить, если я вызываю context.Response.End () непосредственно после context.Response.Flush (), я получаю следующее исключение. Теперь диалог загрузки файла по-прежнему отображается во всех браузерах, независимо от исключения, но в IE7 и IE8 по-прежнему отсутствует диалог загрузки.

context.Response.End (); 'context.Response.End ()' сгенерировал исключение типа 'System.Threading.ThreadAbortException' base {System.SystemException}: {Невозможно оценить выражение, потому что код оптимизирован или собственный фрейм находится над стеком вызовов.} ExceptionState: невозможно оценить выражение, поскольку код оптимизирован или собственный фрейм находится над стеком вызовов.

Может, это как-то связано с iFrame?

enter image description here

PS: сохранить последнее изображение, чтобы увидеть большое изображение

Ответы [ 3 ]

2 голосов
/ 08 февраля 2012

Можете ли вы попробовать это-

    Response.Buffer = true;
            Response.Clear();
            Response.ClearContent();
            Response.ClearHeaders();
            Response.ContentType = "application/pdf";
            Response.AddHeader(
              "Content-Disposition",
              string.Format("attachment; filename={0}",filename)
            );
            // stream pdf bytes to the browser
            Response.OutputStream.Write(estatement.Document, 0, estatement.Document.Length);
            Response.End();
1 голос
/ 08 февраля 2012

Две вещи:

1) Очистите все ваших заголовков перед созданием ответа в обработчике. Это решило проблему для меня из-за бюллетеня по безопасности Microsoft MS11-100, где заголовок Cache-Control был установлен на no-cache="Set-Cookie" (см. в этом блоге для получения дополнительной информации):

// snip...

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

2) Я не уверен, вызывает ли это какие-либо проблемы, а не создает iframe каждый раз, когда пользователь загружает PDF, почему бы просто не установить свойство window.location? Таким образом, вы не добавляете в документ «одноразовые» фреймы, и их поведение должно быть таким же:

function EStatementDownload(fileid) {
    window.location = "EStatementFile.ashx?fileid=" + fileid;
}
1 голос
/ 08 февраля 2012

Вот сообщение о стека, которое у меня было, которое звучит как та же проблема.

IE8 и ниже не могут обработать заголовок Cache-control и приводят к тому, что статическое содержимое, такое как PDF, не загружается.

Ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...