.NET Core中如何根据ContentType为文件名添加对应扩展名
如何根据ContentType正确生成对应文件扩展名?
原代码仅处理了xlsx一种特殊类型,且未考虑带参数的ContentType(如text/html;charset=utf-8),也未覆盖大部分常见文件类型的映射。要处理所有ContentType,可通过预定义类型映射表+ContentType清理逻辑来实现:
第一步:定义ContentType到扩展名的映射表
先建立一个覆盖常见文件类型的静态字典,优先使用业界标准的扩展名,避免直接用ContentType的冗长后缀:
// 预定义ContentType与标准扩展名的映射,兼容大小写 private static readonly Dictionary<string, string> ContentTypeToExtensionMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { // 文本类 { "text/plain", ".txt" }, { "text/html", ".html" }, { "text/css", ".css" }, { "text/javascript", ".js" }, { "text/csv", ".csv" }, // 图片类 { "image/jpeg", ".jpg" }, { "image/png", ".png" }, { "image/gif", ".gif" }, { "image/bmp", ".bmp" }, { "image/webp", ".webp" }, { "image/svg+xml", ".svg" }, // 办公文档类 { "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx" }, { "application/vnd.ms-excel", ".xls" }, { "application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".docx" }, { "application/msword", ".doc" }, { "application/vnd.openxmlformats-officedocument.presentationml.presentation", ".pptx" }, { "application/vnd.ms-powerpoint", ".ppt" }, { "application/pdf", ".pdf" }, // 压缩包类 { "application/zip", ".zip" }, { "application/rar", ".rar" }, { "application/x-7z-compressed", ".7z" }, // 音视频类 { "audio/mpeg", ".mp3" }, { "audio/wav", ".wav" }, { "video/mp4", ".mp4" }, { "video/mpeg", ".mpeg" }, { "video/avi", ".avi" } };
第二步:优化扩展名生成逻辑
先清理ContentType中的参数部分,再优先从映射表查找,找不到时做容错处理:
if (suggestedFileName != null && !System.IO.Path.HasExtension(suggestedFileName)) { string contentType = HttpContext.Request.ContentType; // 无ContentType时默认用.txt if (string.IsNullOrEmpty(contentType)) { suggestedFileName = $"{suggestedFileName}.txt"; return; } // 移除ContentType中的参数(如;charset=utf-8),只保留纯类型部分 string cleanedContentType = contentType.Split(';')[0].Trim(); // 优先从映射表获取标准扩展名 if (ContentTypeToExtensionMap.TryGetValue(cleanedContentType, out string extension)) { suggestedFileName = $"{suggestedFileName}{extension}"; } else { // 映射表无匹配时,尝试从ContentType第二部分提取,同时过滤非法字符 string[] contentTypeParts = cleanedContentType.Split('/'); if (contentTypeParts.Length == 2) { string safeExtensionPart = System.Text.RegularExpressions.Regex.Replace(contentTypeParts[1], @"[^a-zA-Z0-9.]", ""); suggestedFileName = $"{suggestedFileName}.{safeExtensionPart}"; } else { // 格式异常时默认用.txt suggestedFileName = $"{suggestedFileName}.txt"; } } }
核心优化点说明
- 清理ContentType:处理带参数的类型(如
text/plain;charset=utf-8),确保只基于纯类型查找映射。 - 标准映射表:避免直接使用ContentType的冗长后缀(比如把
vnd.openxmlformats-officedocument.spreadsheetml.sheet直接映射为.xlsx),符合用户预期。 - 大小写兼容:字典使用
StringComparer.OrdinalIgnoreCase,兼容Image/Jpeg、image/jpeg等不同大小写的ContentType。 - 容错处理:无ContentType、格式异常时默认用
.txt;提取扩展名时过滤特殊字符,避免生成非法文件名。 - 扩展性强:如果业务需要新增特殊ContentType,直接在映射表中添加对应条目即可。
内容的提问来源于stack exchange,提问作者Manoj Prasanna
相关产品推荐
相关产品推荐

