ASP.NET中如何将Base64字符串解码为各类原文件并保存到文件夹
任意类型Base64文件转存实现方案
你原有代码仅支持图片的核心原因是引入了System.Drawing.Image做图片流解析,还强制将文件存为PNG格式。要支持PDF、JSON、XML等任意类型文件转存,根本不需要针对特定格式做解析——Base64解码得到的字节数组就是原始文件的完整二进制内容,直接写入磁盘即可。
核心实现逻辑
- 入参校验:判断上传的文件内容、文件名、后缀等必填参数是否为空
- 格式兼容:处理前端传入Base64可能携带的Data URI前缀(比如
data:application/pdf;base64,开头的前缀),避免解码失败 - 安全校验:提前指定文件存储根目录,对传入的文件名做路径遍历防护,防止恶意请求将文件写入系统非授权目录
- 直接写盘:将Base64解码得到的字节数组直接写入目标路径,不需要做任何格式转换
完整实现代码
// 存储根路径建议放到配置文件中统一管理,可通过IConfiguration注入读取,这里为演示用固定路径 private readonly string _storageRootPath = Path.Combine(Directory.GetCurrentDirectory(), "UploadedFiles"); [HttpPost("upload-any-file")] public async Task<IActionResult> UploadAnyFile(FileUploadRequest fileRequest) { // 基础入参校验 if (fileRequest == null || string.IsNullOrWhiteSpace(fileRequest.FileContent) || string.IsNullOrWhiteSpace(fileRequest.FileName) || string.IsNullOrWhiteSpace(fileRequest.FileExtension)) { return BadRequest("文件内容、名称、后缀为必填项"); } // 兼容带Data URI前缀的Base64内容 var pureBase64 = fileRequest.FileContent; if (pureBase64.Contains(',')) { pureBase64 = pureBase64.Split(',', 2)[1]; } byte[] fileBytes; try { fileBytes = Convert.FromBase64String(pureBase64); } catch (FormatException) { return BadRequest("Base64内容格式非法,解码失败"); } // 存储目录不存在则自动创建 if (!Directory.Exists(_storageRootPath)) { Directory.CreateDirectory(_storageRootPath); } // 拼接安全文件路径,避免路径遍历攻击 var fileExt = fileRequest.FileExtension.TrimStart('.'); var safeFileName = Path.GetFileName($"{fileRequest.FileName}.{fileExt}"); var fullSavePath = Path.Combine(_storageRootPath, safeFileName); // 二次校验最终存储路径必须在指定根目录下 if (!fullSavePath.StartsWith(_storageRootPath, StringComparison.Ordinal)) { return BadRequest("非法文件路径"); } // 直接写入字节数组,支持任意格式文件,不需要做格式解析 await File.WriteAllBytesAsync(fullSavePath, fileBytes); return Ok(new { FileName = safeFileName, SavePath = fullSavePath, FileSize = fileBytes.Length }); } /// <summary> /// 通用文件上传请求模型 /// </summary> public class FileUploadRequest { /// <summary> /// 文件Base64内容,支持带/不带Data URI前缀 /// </summary> public string FileContent { get; set; } /// <summary> /// 文件名(不含后缀) /// </summary> public string FileName { get; set; } /// <summary> /// 文件后缀,如pdf/json/xml/docx等 /// </summary> public string FileExtension { get; set; } }
注意事项
- 不建议用Base64传输大文件:Base64编码会使文件体积增大约33%,超过100MB的文件建议直接使用
multipart/form-data格式上传,传输和服务端处理性能更好 - 生产环境建议给文件生成不重复的文件名(比如拼接GUID),避免同名文件被覆盖
- 如果需要做文件格式校验,可以在解码后通过文件头魔数判断真实文件类型,不要完全信任传入的后缀参数
内容的提问来源于stack exchange,提问作者RoseG
相关产品推荐
相关产品推荐

