我正在使用DataGridView来显示语句列表。其中一列是LinkButton,它允许您以PDF格式下载该特定语句。除了IE7和IE之外,我的代码在所有浏览器中都能完美运行。 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>
Grid的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();
}
}
单击网格上的Linkbutton时,Firebug中会显示以下javascript信息,这可能有助于查找问题:
有趣的是,如果我在context.Response.Flush()之后直接调用了context.Response.End(),我会得到以下异常。现在,文件下载对话框仍然在所有浏览器中显示,无论异常如何,但在IE7和&amp; IE8,仍然没有下载对话框。
context.Response.End(); 'context.Response.End()'引发了'System.Threading.ThreadAbortException'类型的异常 base {System.SystemException}:{无法计算表达式,因为代码已优化或本机框架位于调用堆栈之上。} ExceptionState:无法计算表达式,因为代码已优化或本机框位于调用堆栈之上。
这可能与iFrame有关吗?
PS:保存最后一张图片以查看大图
答案 0 :(得分:2)
你可以尝试一下 -
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 :(得分:1)
答案 2 :(得分:1)
两件事:
1)在处理程序中创建响应之前,清除标题的所有。这解决了由Microsoft安全公告MS11-100引起的问题,其中Cache-Control标头设置为no-cache="Set-Cookie"
(有关详细信息,请参阅this blog post):
// snip...
if (estatement.Document != null)
{
context.Response.ClearHeaders();
context.Response.Clear();
context.Response.ContentType = "Application/pdf";
// snip...
2)我不确定这是否真的导致任何问题,而不是每次用户下载PDF时创建iframe,为什么不设置window.location属性?这样你就不会在文档中添加“扔掉”的iframe,行为应该仍然是相同的:
function EStatementDownload(fileid) {
window.location = "EStatementFile.ashx?fileid=" + fileid;
}