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