C# .NET 6.0发送邮件时JPEG附件无法添加的问题求助
1. 二进制文件读取错误(核心原因)
你用StreamReader搭配UTF-8编码读取JPEG文件,这是错误的做法。StreamReader是专门用于读取文本文件的工具,用它读取二进制文件(如JPEG、DOCX等)时,UTF-8编码会破坏原始二进制数据,导致生成的Base64字符串无效。虽然部分格式(如DOCX)可能侥幸没触发明显错误,但JPEG对数据完整性要求更高,直接导致附件无法正常解析。
修复代码:
替换原文件读取逻辑,直接用File.ReadAllBytes读取二进制文件,简洁且避免编码破坏数据:
string base64DNI = String.Empty; if (newEsp.rutadni != null && newEsp.rutadni != old.rutadni) { Lst += $"<p style='font-size: 14px;font-weight: bold; font-family: \"Montserrat\",\"Arial\",sans-serif; color: #6668ae;'>Se ha subido un nuevo documento de DNI.</p>"; byte[] docBytes = File.ReadAllBytes(newEsp.rutadni); base64DNI = Convert.ToBase64String(docBytes); }
如果需要手动管理流,也可以用正确的流处理方式(using块会自动释放资源,无需手动调用Close()):
using (var fs = new FileStream(newEsp.rutadni, FileMode.Open, FileAccess.Read)) using (var r = new BinaryReader(fs)) { docBytes = r.ReadBytes((int)fs.Length); base64DNI = Convert.ToBase64String(docBytes); }
2. 检查扩展名识别逻辑
你的代码依赖GetFileExtension(base64DNI)获取文件扩展名,如果这个方法是通过解析Base64内容猜测扩展名,可能无法正确识别JPEG(比如混淆JPG/JPEG后缀,或文件头判断逻辑有问题)。
优化建议:
直接从原文件路径获取扩展名,更可靠:
// 从文件路径提取扩展名,去除开头的点并统一小写 string ext = Path.GetExtension(newEsp.rutadni).TrimStart('.').ToLowerInvariant(); // 统一JPG/JPEG后缀 if (ext == "jpg") ext = "jpeg";
然后将该扩展名直接传递到邮件发送逻辑,避免依赖GetFileExtension的不确定行为。
3. URL-Safe Base64的兼容性检查
你对Base64字符串做了Replace('+', '-').Replace('/', '_')的URL安全转换,但需要确认MailSenderService是否会将这些字符还原回标准Base64的+和/。如果服务端没有做反向还原,JPEG的Base64数据会无效,导致附件无法解析。
处理方式:
- 如果服务端不支持URL-Safe Base64,直接去掉该替换逻辑;
- 如果必须保留,确保服务端执行对应的还原:
// 服务端需执行的还原操作 string standardBase64 = base64DNI.Replace('-', '+').Replace('_', '/');
4. 异步方法调用问题
你的EmailEditUser方法标记为async Task,但内部调用的ExecuteUsingMSS是同步方法且未使用await,这会导致异步逻辑不完整,可能隐藏错误。如果ExecuteUsingMSS有异步版本,建议改为:
await ExecuteUsingMSSAsync(mailSenderConfiguration.MSS_endpoint, reqForMail);
如果没有异步版本,需确保方法内的异常能被正确捕获和日志记录。
内容的提问来源于stack exchange,提问作者Oris Sin

