You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.Net Core 5 Web API使用MimeKit、MailKit发送PDF附件损坏问题求助

问题排查结论

1. 服务端SendEmailAsync方法本身无逻辑错误

你编写的邮件附件添加逻辑符合MimeKit规范,读取IFormFile流转字节数组、指定PDF格式的操作都没有问题,附件损坏的核心原因出在前端生成的Blob文件本身就是无效的。

2. 前端错误点

调用doc.output('datauristring')得到的是带前缀的Data URI字符串,格式为data:application/pdf;base64,xxxxxx,直接把这个字符串塞进Blob,相当于把字符串内容当做PDF二进制数据存储,并非真正的PDF字节流,因此传到服务端的文件本身就是损坏的。


修复方案

前端修改(推荐)

把Data URI转成纯二进制字节流再生成Blob,修改对应逻辑即可:

createPdf(): string {
  var dataURI = doc.output('datauristring');
  return dataURI ? dataURI : "";
}

// 新增DataURI转二进制Blob方法
dataURItoBlob(dataURI: string): Blob {
  const byteString = atob(dataURI.split(',')[1]);
  const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  const ab = new ArrayBuffer(byteString.length);
  const ia = new Uint8Array(ab);
  for (let i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }
  return new Blob([ab], { type: mimeString });
}

createMail(): void {
  // 不要直接传入dataURI生成Blob,先转成二进制格式
  const pdfBlob = this.dataURItoBlob(this.createPdf());
  var fileOfBlob = new File([pdfBlob], this.data.accountName + '_' + this.data.exceptionDate + '_' + 'ExceptionRequest.pdf');
  // 后续FormData逻辑无需修改
  const mail: FormData = new FormData();
  mail.append('ToEmail', this.data.contactEmail);
  mail.append('Subject', 'Test');
  mail.append('Body', 'Test Email');
  mail.append('Attachments', fileOfBlob);

  console.log(fileOfBlob);

  this.mailService.createMail(mail)
    .subscribe(res => {
      console.log(res);
    });
}

服务端兼容优化(前端无法修改时可选)

如果前端暂时无法迭代,也可以在服务端兼容处理,把收到的文件内容先剔除Data URI前缀再转成二进制:

public async Task SendEmailAsync(MailRequest mailRequest)
{
    var email = new MimeMessage();
    email.Sender = MailboxAddress.Parse(_mailSettings.Mail);
    email.To.Add(MailboxAddress.Parse(mailRequest.ToEmail));
    email.Subject = mailRequest.Subject;

    var builder = new BodyBuilder();
    byte[] fileBytes;
    if (mailRequest.Attachments != null)
    {
        var file = mailRequest.Attachments;
        if (file.Length > 0)
        {
            using (var ms = new MemoryStream())
            {
                file.CopyTo(ms);
                var fileContent = System.Text.Encoding.UTF8.GetString(ms.ToArray());
                // 校验是否为Data URI格式,是则截取base64部分转字节
                if (fileContent.StartsWith("data:application/pdf;base64,"))
                {
                    var base64Part = fileContent.Split(',')[1];
                    fileBytes = Convert.FromBase64String(base64Part);
                }
                else
                {
                    fileBytes = ms.ToArray();
                }
            }
            builder.Attachments.Add(file.FileName, fileBytes, MimeKit.ContentType.Parse(MediaTypeNames.Application.Pdf));
        }
    }
    builder.HtmlBody = mailRequest.Body;
    email.Body = builder.ToMessageBody();
    using var smtp = new SmtpClient();
    smtp.Connect(_mailSettings.Host, _mailSettings.Port, SecureSocketOptions.StartTls);
    smtp.Authenticate(_mailSettings.Mail, _mailSettings.Password);
    await smtp.SendAsync(email);
    smtp.Disconnect(true);
}

内容的提问来源于stack exchange,提问作者fletch413

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:09:02