由Adobe Reader丢失的Response.Stream输出(PDF)

dno*_*ord 0 c# outputstream response itextsharp

在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();
Run Code Online (Sandbox Code Playgroud)

因此,基本上,PdfReader获取文件,PdfStamper将PdfReader作为参数,并将其完成的PDF推送到Response.OutputStream.

问题是,使用IE和Adobe Reader,如果从文件对话框中选择"打开",Adobe Reader会抛出错误提示"无法找到文件".用户可以"保存"文件,甚至可以再次开始下载(在被问到时再次单击"打开")似乎可以正常工作.但是在一台永远不会下载文件的新机器上,Adobe Reader似乎错误地将文件放在临时文件或IE之间.

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

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

Cᴏʀ*_*ᴏʀʏ 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()
Run Code Online (Sandbox Code Playgroud)

这似乎很好地防止了所有"找不到文件"的垃圾.

编辑:对于那些对这些标题实际意味着什么感兴趣的人:

  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. 其余部分只是描述您希望用户接收的内容.指定"附件"会告诉浏览器将文件作为下载提供,而不是内联显示.