【问题标题】:Corrupt PDF Attachment损坏的 PDF 附件
【发布时间】:2011-10-28 11:22:07
【问题描述】:

我正在尝试执行以下操作:

  1. 从网页中检索生成的 pdf
  2. 创建电子邮件
  3. 将 pdf 附加到邮件中
  4. 发送消息

我能够从网页中检索 pdf 并将其作为附件发送消息。但是,当我尝试打开附件时,会收到可怕的“Adobe Reader 无法打开 'filename.pdf',因为它不是受支持的文件类型或文件已损坏”消息。

pdf 由 MVC3 页面生成,使用自定义 ActionResult 返回 pdf。看起来是这样的

public class EnrollmentExpectationsPdfResult : FileResult
{
    IList<AdminRepEnrollmentExpectationViewModel> adminreps;

    public EnrollmentExpectationsPdfResult(IList<AdminRepEnrollmentExpectationViewModel> adminrep)
        : this("application/pdf", adminrep)
    { }

    public EnrollmentExpectationsPdfResult(string contentType, IList<AdminRepEnrollmentExpectationViewModel> adminrep)
        : base(contentType)
    {
        adminreps = adminrep;

    }

    protected override void WriteFile(HttpResponseBase response)
    {
        var cd = new ContentDisposition
        {
            Inline = true,
            FileName = "MyPDF.pdf"
        };
        response.AppendHeader("Content-Disposition", cd.ToString());

        //Skip a bunch of boring font stuff
        ...

        var writer = PdfWriter.GetInstance(doc, response.OutputStream);
        writer.PageEvent = new EnrollmentExpectationPDFPageEvent();            
        doc.Open();

        //Skip the doc writing stuff
        ...

        doc.Close();
    }
}

控制器方法在这里

public ActionResult EnrollmentExpectationsPDF()
{
    //skip a bunch a database stuff
    ...
    return new EnrollmentExpectationsPdfResult(adminList);
}

这是问题核心的代码...

//Get PDF
CredentialCache cc = new CredentialCache();
cc.Add(
       new Uri("http://myserver/mypdfgeneratingpage"),
       "NTLM",
       new NetworkCredential("myusername", "mypassword"));

var webRequestObject = (HttpWebRequest)WebRequest.Create("http://iapps.national.edu/erp/Reports/EnrollmentExpectationsPDF");
webRequestObject.Credentials = cc;
var response = webRequestObject.GetResponse();
var webStream = response.GetResponseStream();

//Create Mail
System.Net.Mail.MailMessage eMail = ...

//Skipping to attachment stuff
ContentType ct = new ContentType()
{
     MediaType = MediaTypeNames.Application.Pdf,
     Name = "EnrollmentExpecations_2.pdf"
};

Attachment a = new Attachment(webStream, ct);
eMail.Attachments.Add(a);

//Send Message
....

作为实验,我尝试将下载的文件写入磁盘

MemoryStream ms = new MemoryStream();
var fileStream = File.Create("C:\\MyPDF.pdf");
webStream.CopyTo(fileStream);

Viola,我可以毫无问题地从磁盘打开文件。

为了使附件可读,我缺少什么?

【问题讨论】:

  • 啊...好吧,我想也许它对于电子邮件来说可能太大了。现在我必须仔细阅读代码哈哈
  • 确保在发送对象后关闭并刷新流
  • @rlb.usa,这行得通......如果你把它作为答案而不是评论,我会“检查”它。谢谢!

标签: .net asp.net-mvc pdf itextsharp system.net.mail


【解决方案1】:

只是为了让用户清楚,感谢@rlb.usa

确保在发送对象后关闭并刷新流

【讨论】:

  • 正如我上面提到的,如果@rlb.usa 将其作为答案,我将很高兴接受。
  • 如果我可能会问,您如何“在发送对象后关闭并刷新您的流”?我们是在谈论 PDF 创建过程还是电子邮件过程?
【解决方案2】:

对我们来说,答案是不同的。

问题是在写入数据库时​​,我们使用的是 GetBuffer() 而不是 ToArray()。因此,如果缓冲区为 256,则剩余数量作为空字符附加到数据库中的文档中。

我在这里找到了答案http://forums.asp.net/t/1083910.aspx

我认为错误不在您下载文档的代码中。我相信由于文档最初存储在数据库中的方式而发生错误。确保在将文件写入数据库时​​没有使用 GetBuffer() 方法。尝试使用 ToArray() 代替,它不会将额外的字符附加到文件流的末尾。这里有一个链接可以为您提供更多详细信息:http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer.aspx

PDF 文档末尾 %%EOF 标记后的多余字符很可能是导致该消息的原因:

【讨论】:

    猜你喜欢
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 2012-03-16
    • 2014-02-11
    相关资源
    最近更新 更多