SmtpClient发送邮件:An invalid character was found in the mail header

by kevin 8. 十月 2015 14:19 >

.net 4.0的环境下使用SmtpClient发送邮件,带有附件。碰到这个恶心的Exception

System.FormatException: An invalid character was found in the mail header:

查了两天,终于解决了,是.Net自身的bug,据说后续版本是有解决的(估计.net 4.5以后)。

这里贴出解决方案:

        public static Attachment CreateAttachment(Stream attachmentFile, string displayName, string contentType, string attachmentFilePath)
        {
            var currentCulture = Thread.CurrentThread.CurrentCulture;//.net4.0 bug,
            var attachment = new Attachment(attachmentFile, displayName);
            try
            {
                Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
                attachment.ContentType = new ContentType(contentType);
                attachment.ContentDisposition.CreationDate = File.GetCreationTime(attachmentFilePath);
                attachment.ContentDisposition.ModificationDate = File.GetLastWriteTime(attachmentFilePath);
                attachment.ContentDisposition.ReadDate = File.GetLastAccessTime(attachmentFilePath);
                attachment.TransferEncoding = TransferEncoding.Base64;
                attachment.NameEncoding = Encoding.UTF8;
                string encodedAttachmentName = Convert.ToBase64String(Encoding.UTF8.GetBytes(displayName));
                encodedAttachmentName = SplitEncodedAttachmentName(encodedAttachmentName);
                attachment.Name = encodedAttachmentName;
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = currentCulture;
            }
            return attachment;
        }

        private static string SplitEncodedAttachmentName(string encoded)
        {
            const string encodingtoken = "=?UTF-8?B?";
            const string softbreak = "?=";
            const int maxChunkLength = 30;
            int splitLength = maxChunkLength - encodingtoken.Length - (softbreak.Length * 2);
            IEnumerable<string> parts = SplitByLength(encoded, splitLength);
            string encodedAttachmentName = encodingtoken;
            foreach (var part in parts)
            {
                encodedAttachmentName += part + softbreak + encodingtoken;
            }
            encodedAttachmentName = encodedAttachmentName.Remove(encodedAttachmentName.Length - encodingtoken.Length, encodingtoken.Length);
            return encodedAttachmentName;
        }

        private static IEnumerable<string> SplitByLength(string stringToSplit, int length)
        {
            while (stringToSplit.Length > length)
            {
                yield return stringToSplit.Substring(0, length);
                stringToSplit = stringToSplit.Substring(length);
            }
            if (stringToSplit.Length > 0)
            {
                yield return stringToSplit;
            }
        }

参考:https://support.microsoft.com/zh-cn/kb/2402064

分享到: 更多