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

Azure Blob容器同名Blob上传处理方案咨询

解决方案

一、可以修改Blob存储的文件名(推荐方案)

完全可以修改存储到Blob的文件名,既解决重复冲突,又能保留原文件名供用户查看。核心思路是给原文件名加上唯一标识前缀,确保Blob名称全局唯一,同时在数据库Document实体中保留原始文件名。

修改代码如下:

foreach (var blob in blobs.Files)
{
    try
    {
        // 生成唯一的Blob文件名:Guid前缀+原文件名
        string uniqueBlobName = $"{Guid.NewGuid()}_{blob.FileName}";
        BlobClient client = container.GetBlobClient(uniqueBlobName);

        await using (Stream? data = blob.OpenReadStream())
        {
            await client.UploadAsync(data);
        }

        Guid documentGuid = Guid.NewGuid();
        var metadata = new Dictionary<string, string>
        {
            {"Guid", documentGuid.ToString()},
            {"UserId", valuation.UserId.ToString()},
            {"TenantId", valuation.TenantId.ToString()},
            {"ValuationId", valuation.Id.ToString()},
            {"OriginalFileName", blob.FileName} // 元数据也保留原文件名
        };

        await client.SetMetadataAsync(metadata);

        Document document = new Document()
        {
            Guid = documentGuid.ToString(),
            FileName = blob.FileName, // 数据库存原文件名,用户查看时显示这个
            FileType = blob.ContentType,
            FileUrl = client.Uri.AbsoluteUri,
            ValuationId = valuation.Id,
            UserId = valuation.UserId,
            TenantId = valuation.TenantId
        };

        await _ctx.Document.AddAsync(document);
        await _ctx.SaveChangesAsync();

        blobResponse.Status = $"File {blob.FileName} Uploaded Successfully";
        blobResponse.Error = false;
        blobResponse.Blobs.Add(new BlobDTO
        {
            Name = blob.FileName, // 返回给前端原文件名
            Uri = client.Uri.AbsoluteUri
        });
    }
    // 捕获异常逻辑可保留,加Guid前缀后几乎不会触发BlobAlreadyExists
    catch (RequestFailedException ex) when (ex.ErrorCode == BlobErrorCode.BlobAlreadyExists)
    {
        blobResponse.Status = $"File with name {blob.FileName} already exists. Please use another name to store your file.";
        blobResponse.Error = true;
        serviceResponse.Success = false;
        serviceResponse.Message = "Filename already exists";
        serviceResponse.Data = blobResponse;
        return serviceResponse;
    }
    catch (Exception ex)
    {
        blobResponse.Status = $"Unexpected error: {ex.StackTrace}. Check log with StackTrace ID.";
        blobResponse.Error = true;
        serviceResponse.Success = false;
        serviceResponse.Message = "Unexpected error";
        serviceResponse.Data = blobResponse;
    }
}

处理后效果:

  • Blob存储的文件名全局唯一,不会出现重复冲突
  • 用户在前端查看、下载时看到的始终是原始文件名
  • 数据库和Blob元数据都保留了原文件名,方便后续追溯管理

二、不修改Blob文件名的处理方案

如果必须保留原始文件名作为Blob名称,可以通过按估值/租户划分Blob虚拟路径的方式避免冲突:

  1. 给Blob添加路径前缀,比如用估值ID作为虚拟文件夹:
string blobPath = $"{valuation.Id}/{blob.FileName}";
BlobClient client = container.GetBlobClient(blobPath);

不同估值下的同名文件会被放在不同的虚拟路径下,不会产生冲突。

  1. 同时在Document实体和Blob元数据中记录原文件名与关联的估值信息,确保用户查看时能对应到正确的估值记录。

这种方式的好处是Blob名称完全保留原始文件名,但需要注意后续的路径管理,比如删除估值时可批量清理对应路径下的Blob文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:23:08