我知道这个问题已被多次询问过,我已经仔细研究了这些答案,以找到解决我的代码所发生情况的潜在解决方案无济于事。所以这里。
我有一个包含更新面板的页面。在此更新面板上,我有一个生成Telerik pdf报告并下载它的按钮。但是,单击按钮时出现臭名昭着的错误:服务器无法在发送HTTP标头后设置内容类型。
这是我的代码(为简便发布此问题而简化:
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.GetCurrent(this).RegisterPostBackControl(btnPayrollDetails);
}
protected void btnPayrollDetails_Click(object sender, EventArgs e)
{
PayPeriod pay = GetPeriod();
if (pay == null || (pay.Expenses.Count == 0 && pay.Invoices.Count == 0))
{
return;
}
var file = "test";
var report = new Core.Reports.PayrollDetails(Global.Account.Member.ID, pay, mypMonth.SelectedDate.Value);
Telerik.Reporting.Processing.RenderingResult result = new Telerik.Reporting.Processing.ReportProcessor().RenderReport("PDF", report, null);
this.Response.DownloadFile(result.DocumentBytes, file + ".pdf");
}
对this.Response.DownloadFile的调用在此处调用扩展方法:
public static void DownloadFile(this HttpResponse Response, byte[] fileBytes, string fileName, string mime = "application/pdf")
{
Response.Clear();
Response.BufferOutput = true;
Response.ContentType = mime;
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + "\"");
using (MemoryStream ms = new MemoryStream(fileBytes)) { ms.WriteTo(Response.OutputStream); }
HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
HttpContext.Current.Response.SuppressContent = true; // Gets or sets a value indicating whether to send HTTP content to the client.
HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
}
令人困惑的部分是我在其他项目中运行完全相同的代码,它绝对没有任何问题。所以,如果有人能指出我做错了什么,我会非常感激。
答案 0 :(得分:1)
好的,这个问题让我感到很长时间,直到我偶然发现了一个解决方案。
对于任何遇到类似问题的人来说,最终对我有用。
我从Page_Load()事件中删除了ScriptManager.GetCurrent(this).RegisterPostBackControl(btnPayrollDetails);
并将其添加到button_Init事件中:
<asp:Button ID="btnPayrollDetails" runat="server" Text="Payroll Details" OnClick="btnPayrollDetails_Click" OnInit="btnPayrollDetails_Init" />
protected void btnPayrollDetails_Init(object sender, EventArgs e)
{
ScriptManager.GetCurrent(this).RegisterPostBackControl(btnPayrollDetails);
}
由于某种原因,按钮未被注册到脚本管理器并将其从PageLoad()移动到按钮Init()方法修复了此问题。