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

Azure Blob Storage SDK for .NET中BlobClient.UploadAsync始终抛出异常但文件上传成功的问题求助

排查Azure Blob Storage SDK UploadAsync抛出409但文件上传成功的问题

我来帮你捋捋这个诡异的问题!明明用GUID保证Blob名称唯一,提前确认Blob不存在,结果每次上传都抛409 The specified blob already exists,但文件又能成功上传,这确实让人摸不着头脑。结合你提供的代码和场景,我整理了几个可能的原因和对应的解决方案:

一、先排查调用代码的潜在问题

你在SaveFile方法里调用StoreAttachmentAsync时没有加await:

// 原代码:没有await,可能导致异步方法被重复执行或状态异常
StoreAttachmentAsync(Guid.NewGuid(),fileData);

这种写法会让StoreAttachmentAsync在后台无等待执行,极端情况下可能因为请求重复提交、线程调度问题导致同一Blob(虽然是GUID,但如果代码逻辑有重复触发的情况)被多次上传尝试,进而引发409。先把调用改成带await的正确异步写法:

public async Task<ActionResult> SaveFile(IEnumerable<HttpPostedFileBase> files) {
    var file = files.First();
    byte[] fileData;
    using (var ms = new MemoryStream()) {
        file.InputStream.CopyTo(ms);
        fileData = ms.ToArray();
    }
    // 加上await,确保异步方法执行完成
    await StoreAttachmentAsync(Guid.NewGuid().ToString(), fileData);
    return Ok();
}

二、显式设置上传条件,避免SDK默认逻辑冲突

新的Azure Blob SDK的UploadAsync方法,底层可能会有分块上传、预检查等隐含逻辑,即使Blob不存在,也可能因为临时操作触发409。你可以显式指定仅当Blob不存在时才上传的条件,同时捕获异常并查看详细请求ID,方便后续排查:

public async Task StoreAsync(string container, string blob, byte[] givenBytes, CancellationToken cancellationToken = default) {
    BlobContainerClient containerReference = this.client.GetBlobContainerClient(container);
    await containerReference.CreateIfNotExistsAsync(cancellationToken: cancellationToken);
    BlobClient blobReference = containerReference.GetBlobClient(blob);
    
    var uploadOptions = new BlobUploadOptions
    {
        Conditions = new BlobRequestConditions
        {
            // 仅当目标Blob不存在时执行上传(匹配任何已存在的ETag则拒绝)
            IfNoneMatch = ETag.All
        }
    };
    
    try
    {
        await blobReference.UploadAsync(new BinaryData(givenBytes), uploadOptions, cancellationToken);
    }
    catch (RequestFailedException ex)
    {
        // 打印错误详情,包括Azure返回的Request ID,方便去Portal查日志
        Console.WriteLine($"上传异常:{ex.Message},Request ID:{ex.RequestId}");
        // 根据业务需求决定是否重新抛出异常
        throw;
    }
}

三、检查Azure存储账户的配置

有时候存储账户的特殊配置会导致这种异常:

  • Blob版本控制:如果你的容器开启了Blob版本控制,即使当前版本的Blob已被删除,旧版本的存在可能会干扰SDK的检查逻辑。可以去Azure Portal的容器设置里关闭版本控制试试(如果业务允许的话)。
  • 软删除:同理,软删除开启后,已删除的Blob会在保留期内存在,虽然你访问URL返回不存在,但SDK的内部检查可能会检测到残留的软删除Blob。

四、查看Azure存储日志定位根因

如果以上方法都没解决,建议去Azure Portal开启存储账户的日志记录,然后根据异常里的Request ID去查询对应的请求详情。日志会显示该409请求的完整上下文,比如是哪个操作触发的、具体的请求参数是什么,能帮你精准定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 10:39:07