西里尔文文件名上传Azure Blob容器触发System.AggregateException的解决办法
解决Azure Blob上传含西里尔文文件名文件的异常问题
问题原因
经排查,异常由原文件名中的西里尔文存入Blob元数据引发。Azure Blob存储的元数据字段默认要求值为ASCII兼容字符,直接存入非ASCII字符(如西里尔文)会触发编码错误,最终抛出System.AggregateException。
解决方法
1. 对元数据中的非ASCII文件名编码
将原文件名进行URL编码后存入元数据,读取时再解码,确保符合Azure元数据的字符规范。
修改代码中元数据初始化部分:
// 需引用 System.Net 命名空间 var metadata = new Dictionary<string, string> { { "Email", userEmail }, { "UserFileName", System.Net.WebUtility.UrlEncode(file.FileName) } };
后续读取原文件名时解码:
string originalFileName = System.Net.WebUtility.UrlDecode(blobClient.GetProperties().Value.Metadata["UserFileName"]);
2. 捕获内部异常精准定位(调试用)
展开AggregateException的内部异常,能直接获取错误根源:
catch (AggregateException ex) { var innerErrors = ex.Flatten().InnerExceptions.Select(e => e.Message); return StatusCode(500, $"上传错误详情:{string.Join(" | ", innerErrors)}"); }
3. 验证扩展名提取(可选)
若扩展名包含西里尔文(如.документ),可添加日志确认Path.GetExtension是否正确提取:
string extension = Path.GetExtension(file.FileName); Console.WriteLine($"提取的扩展名:{extension}");
完整修改后代码
using Azure.Storage.Blobs; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Azure.Storage.Blobs.Models; using System.IO; using System; using System.Threading.Tasks; using System.Collections.Generic; using System.Net; // 添加命名空间 namespace DocxSender.API.Controllers { [ApiController] [Route("api/upload")] public class UploadController : Controller { private readonly IConfiguration _config; public UploadController(IConfiguration config) { _config = config; } [HttpPost] public async Task<IActionResult> Upload([FromForm] IFormFile file, [FromForm] string userEmail) { string containerConnectionString = _config.GetValue<string>("ConnectionString"); string blobName = _config.GetValue<string>("BlobName"); string fileName = Guid.NewGuid().ToString(); string extension = Path.GetExtension(file.FileName); BlobServiceClient blobServiceClient = new BlobServiceClient(containerConnectionString); BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(blobName); BlobClient blobClient = containerClient.GetBlobClient(fileName + extension); var metadata = new Dictionary<string, string> { { "Email", userEmail }, { "UserFileName", WebUtility.UrlEncode(file.FileName) } // 编码原文件名 }; try { await blobClient.UploadAsync(file.OpenReadStream(), new BlobUploadOptions() { Metadata = metadata }); return Ok(); } catch (AggregateException ex) { var innerErrors = ex.Flatten().InnerExceptions.Select(e => e.Message); return StatusCode(500, $"上传错误:{string.Join(" | ", innerErrors)}"); } catch (Exception ex) { return StatusCode(500, $"上传文件出错:{ex.Message}"); } } } }
内容的提问来源于stack exchange,提问作者swaggoo
相关产品推荐
相关产品推荐

