0

在 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 和 Adob​​e Reader,如果您从文件对话框中选择“打开”,Adobe Reader 会抛出一个错误,提示“找不到文件”。用户可以很好地“保存”文件,甚至再次开始下载(在询问时再次单击“打开”)似乎也可以。但是在从未下载过文件的新机器上,Adobe Reader 似乎将文件放在了临时文件或任何 IE 之间。

我现在只能想象一件事:Response.End()应该,也许,Response.Close()代替,或者也许整个事情应该Response.Flush()在它之前。但我不确定这不会使问题变得更糟,而且我很难进行测试(因为一旦你下载了一次文件,就不会再次抛出错误)。

这能解决问题吗?我在标题中有什么问题吗?或者我应该对 Response / PdfStamper 对象做些什么?

4

1 回答 1

5

每当我向用户强制内容时,我都会按照以下步骤进行响应:

Response.Clear()
Response.ClearHeaders()
Response.Buffer = True
Response.ContentType = "your mime type"
Response.CacheControl = "public"
Response.AddHeader("Pragma", "public")
Response.AddHeader("Expires", "0")
Response.AddHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0")
Response.AddHeader("Content-Description", "Description of your content")
Response.AddHeader("Content-Disposition", "attachment; filename=""somefile.pdf""")

' Add your content to the buffer here

Response.Flush()
Response.End()

这似乎非常适合防止所有“找不到文件”垃圾。

编辑:对于那些对这些标题的实际含义感兴趣的人:

  1. Pragma: public有助于控制缓存以向后兼容 HTTP/1.0 请求。即使已经有缓存的响应,它也可以确保您的请求发送到服务器。
  2. Expires: 0是响应过期的时间间隔(以秒为单位)。设置为 0 会立即使响应过期,从而有助于避免过时的缓存。
  3. Cache-control: must-revalidate告诉缓存它必须服从你的每一个命令(即当你请求它时它必须给你一个新的响应)。
  4. Cache-control: post-check=0, pre-check=0:这是一个以秒为单位的间隔,必须在(分别)提供内容之后/之前检查响应的新鲜度。设置为 0 会强制立即检查响应的新鲜度。(更多在 MSDN 上。)
  5. 其余的只是描述您希望用户接收的内容。指定“附件”告诉浏览器提供文件作为下载而不是内联显示。
于 2010-02-24T18:08:12.340 回答