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虚拟路径的方式避免冲突:
- 给Blob添加路径前缀,比如用估值ID作为虚拟文件夹:
string blobPath = $"{valuation.Id}/{blob.FileName}"; BlobClient client = container.GetBlobClient(blobPath);
不同估值下的同名文件会被放在不同的虚拟路径下,不会产生冲突。
- 同时在
Document实体和Blob元数据中记录原文件名与关联的估值信息,确保用户查看时能对应到正确的估值记录。
这种方式的好处是Blob名称完全保留原始文件名,但需要注意后续的路径管理,比如删除估值时可批量清理对应路径下的Blob文件。
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

