最近在使用MailKit组件发送邮件,看了一些博客其实仍是蛮简单的,可是发送附件的时候却产生了不小的问题,附件的中文名字是乱码的,或者附件的名字过长就会无效,附件的名字在QQ邮箱中会变成相似
tcmime.1046.1479.1696.bin
这样问文件名而在163邮箱中则可能变成相似
ATT00002.docx
的名称。若是你也遇到了这样的问题,那么我想你必定很期待接下来的解决办法。git
缘由是字符编码的问题github
MimePart attachment = null; var fs = new FileStream(path, FileMode.Open); list.Add(fs); attachment = new MimePart(contentType) { Content = new MimeContent(fs), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, }; var charset = "GB18030"; attachment.ContentType.Parameters.Add(charset, "name", fileName); attachment.ContentDisposition.Parameters.Add(charset, "filename", fileName);
解决附件名字中文乱码主要依靠最后三行代码,将name和filename的字符集指定为GB18030便可。ui
为何会不超过41个字符呢?
引用github上MailKit的issue
大意是 你使用的mail client 不支持 rfc2231 编码,最有可能的是,它指望的文件名参数编码使用rfc2047编码(理论上历来没有人使用rfc2047编码参数值...,可是,哎... 有些邮件客户端就是 sucks)编码
而后这个回答者给出了两种解决方案,我使用了第一种以下:code
var attachment = bodyBuilder.Attachments.Add (.....); foreach (var param in attachment.ContentDisposition.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047; foreach (var param in attachment.ContentType.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047;
第二种你能够点issue查看,完整的代码看最后get
By the way , 我还遇到了一个问题就是附件在发送以后附件使用的文件流没有被释放掉,我以为这是个bug应该会在之后更正,不过如今你能够在添加附件是将文件流的引用收集起来,等到邮件发送以后释放掉:博客
List<FileStream> list = new List<FileStream>(attachments.Count()); foreach (var path in attachments) { if (!File.Exists(path)) { throw new FileNotFoundException("文件未找到", path); } var fileName = Path.GetFileName(path); var fileType = MimeTypes.GetMimeType(path); var contentTypeArr = fileType.Split('/'); var contentType = new ContentType(contentTypeArr[0], contentTypeArr[1]); MimePart attachment = null; var fs = new FileStream(path, FileMode.Open); list.Add(fs); attachment = new MimePart(contentType) { Content = new MimeContent(fs), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, }; var charset = "GB18030"; attachment.ContentType.Parameters.Add(charset, "name", fileName); attachment.ContentDisposition.Parameters.Add(charset, "filename", fileName); foreach (var param in attachment.ContentDisposition.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047; foreach (var param in attachment.ContentType.Parameters) param.EncodingMethod = ParameterEncodingMethod.Rfc2047; collection.Add(attachment); } await SendEmail(body, subject, isHtml, to, cc, collection); foreach (var fs in list) { fs.Dispose();//手动高亮 }