【问题标题】:Response.Stream output (a PDF) lost by Adobe ReaderAdobe Reader 丢失了 Response.Stream 输出(PDF)
【发布时间】:2010-02-24 17:57:56
【问题描述】:

在 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 对象做些什么?

【问题讨论】:

    标签: c# itextsharp response outputstream


    【解决方案1】:

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

    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 会强制立即检查响应的新鲜度。 (More at MSDN.)
    5. 其余部分只是描述您希望用户接收的内容。指定“附件”告诉浏览器提供文件作为下载而不是内联显示。

    【讨论】:

    • 为什么必须这样做?它有效,但有什么具体原因吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多