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

使用Azure.Storage.Blobs上传邮件PDF至Blob后无法读取求助

问题:上传至Azure Blob的PDF附件损坏无法打开

上传后用Acrobat Reader打开PDF时出现报错:

Adobe Acrobat Reader could not open 'file.pdf' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded).

已设置容器公共访问策略为PublicAccessType.Blob,也尝试指定ContentType为application/pdf,但问题依旧。当前代码如下:

BlobServiceClient blobServiceClient = new BlobServiceClient(connString);
Attachment attachment = GetEmailPDF(emails);
try
{
    BlobContainerClient blobContainer = blobServiceClient.GetBlobContainerClient(blobDirectoryName);
    if (blobContainer.Exists())
    {
        blobContainer.SetAccessPolicyAsync(PublicAccessType.Blob).Wait();
        string prefix_path = <my custom prefix path setup>;
        var blobClient = blobContainer.GetBlobClient(prefix_path);
        //Upload PDF file
        BlobHttpHeaders blobHttpHeaders = new BlobHttpHeaders();
        blobHttpHeaders.ContentType = attachment.ContentType.ToString();
        blobClient.UploadAsync(attachment.ContentStream, blobHttpHeaders).Wait();
    }
}
catch (Exception e)
{
    throw new Exception("Something happened to UploadPDFFile: ", e);
}

解决办法

1. 重置MemoryStream的位置

邮件附件的ContentStream可能已经被读取过(比如解析邮件时),此时Stream的Position不在起始位置,上传时会从当前位置开始写入,导致文件内容缺失损坏。上传前必须重置位置:

attachment.ContentStream.Position = 0;

2. 直接指定正确的ContentType

不要依赖attachment.ContentType.ToString(),邮件中的ContentType可能包含额外参数(比如application/pdf; name="file.pdf"),直接硬设为标准值更可靠:

blobHttpHeaders.ContentType = "application/pdf";

3. 改用async/await替代.Wait()

同步阻塞异步方法(.Wait())可能引发死锁或异常处理问题,建议重构为异步代码:

BlobServiceClient blobServiceClient = new BlobServiceClient(connString);
Attachment attachment = GetEmailPDF(emails);
try
{
    BlobContainerClient blobContainer = blobServiceClient.GetBlobContainerClient(blobDirectoryName);
    if (await blobContainer.ExistsAsync())
    {
        await blobContainer.SetAccessPolicyAsync(PublicAccessType.Blob);
        string prefix_path = <my custom prefix path setup>;
        var blobClient = blobContainer.GetBlobClient(prefix_path);
        
        // 重置流位置
        attachment.ContentStream.Position = 0;
        
        BlobHttpHeaders blobHttpHeaders = new BlobHttpHeaders();
        blobHttpHeaders.ContentType = "application/pdf";
        
        await blobClient.UploadAsync(attachment.ContentStream, blobHttpHeaders);
    }
}
catch (Exception e)
{
    throw new Exception("Something happened to UploadPDFFile: ", e);
}

额外检查点

  • 确认GetEmailPDF方法返回的Attachment.ContentStream是完整的PDF内容,可以先将Stream保存到本地文件验证是否能正常打开,排除邮件解析阶段的问题。
  • 上传后在Azure Portal中下载Blob,检查文件大小是否和本地附件一致,若大小为0或远小于原文件,说明流位置问题未解决。

内容的提问来源于stack exchange,提问作者Việt Tùng Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:12:39