在ASP.NET应用程序中,我使用iTextSharp(主要是PdfStamper)来填充PDF上的一些内容并将其发送给用户 . 以下代码位于OnClick事件中:
PdfReader r = new PdfReader(
new RandomAccessFileOrArray(Request.MapPath(compatiblePdf)), null
);
ps = new PdfStamper(r, Response.OutputStream);
AcroFields af = ps.AcroFields;
af.SetField("ContactInfo[0]", o.mallName);
af.SetField("ClientName", string.Format("{0} {1}", c.firstName, c.lastName));
af.SetField("ClientEmail", c.emailAddress);
ps.FormFlattening = true;
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=Form.pdf");
ps.Close();
Response.End();
因此,基本上,PdfReader获取文件,PdfStamper将PdfReader作为参数,并将其完成的PDF推送到Response.OutputStream .
问题是,使用IE和Adobe Reader,如果从文件对话框中选择“打开”,Adobe Reader会抛出错误提示“无法找到文件” . 用户可以“保存”文件,甚至可以再次开始下载(在被问到时再次单击“打开”)似乎可以正常工作 . 但是在一台永远不会下载文件的新机器上,Adobe Reader似乎错误地将文件放在临时文件或IE之间 .
我现在只能想象一件事: Response.End()
,或许应该是 Response.Close()
,或者也许整个事情应该在它之前有 Response.Flush()
. 但我不会让问题变得更糟,而且我已经下载了一次文件,错误不再被抛出了 .
可能解决问题吗?我在 Headers 中有什么问题吗?或者我还应该对Response / PdfStamper对象做些什么呢?
1 回答
每当我强迫用户使用内容时,我都会按照以下步骤进行响应:
这似乎很好地防止了所有“找不到文件”的垃圾 .
EDIT: 对于那些对这些 Headers 实际意味着什么感兴趣的人:
Pragma: public
有助于控制缓存以实现与HTTP / 1.0请求的向后兼容性 . 即使已经有缓存的响应,它也可以确保您的请求进入服务器 .Expires: 0
是响应到期后的间隔(秒) . 设置为0会立即使响应失效,从而有助于避免过时的缓存 .Cache-control: must-revalidate
告诉缓存它必须服从你的每个命令(即当你要求它时它必须给你一个新的响应) .Cache-control: post-check=0, pre-check=0
:这是一个以秒为单位的间隔,必须在(分别)提供内容之后/之前检查响应的新鲜度 . 设置为0会强制立即检查响应的新鲜度 . (More at MSDN . )其余部分只是描述您希望用户接收的内容 . 指定"attachment"告诉浏览器将文件作为下载提供,并且不以内联方式显示它 .