最近在使用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();//手動高亮 }