最近将从.net3.5升级到.net4.0邮件发送出现了一系列问题,问题如下。
问题:
1,邮件发送系统,吧.net从3.5升到4.0后,带附件邮件发送失败。
2,解决第一个问题后,附件的名字过长时,邮件接收方无法解析邮件名称。
原因:
1, ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(str);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(str);
disposition.ReadDate = System.IO.File.GetLastAccessTime(str);
是由以上一段代码引发了邮件对象发生异常。
2,Base64编码一行不能超过30个字节,每行都要有换行符“=?UTF-8?B?”
所以如果邮件名字过长后如果不对编码后的字符进行换行的话,在接收方会无法解析邮件名称。
编码规则可 参考http://hi.baidu.com/sbdwcdc/blog/item/68dd8e4a6c76742908f7efb8.html
解决方案:
1,去掉原因中的那段代码。
2,对编码后的邮件名称进行字符换行。
以下是一个将附件名称处理的一个附件操作类:
public class AttachmentHelper
{
public static Attachment CreateAttachment(string attachmentFile, string displayName, TransferEncoding transferEncoding)
{
Attachment attachment = new Attachment(attachmentFile);
attachment.TransferEncoding = transferEncoding;
string tranferEncodingMarker = String.Empty;
string encodingMarker = String.Empty;
int maxChunkLength = 0;
switch (transferEncoding)
{
case TransferEncoding.Base64:
tranferEncodingMarker = "B";
encodingMarker = "UTF-8";
maxChunkLength = 30;
break;
case TransferEncoding.QuotedPrintable:
tranferEncodingMarker = "Q";
encodingMarker = "ISO-8859-1";
maxChunkLength = 76;
break;
default:
throw (new ArgumentException(String.Format("The specified TransferEncoding is not supported: {0}", transferEncoding, "transferEncoding")));
}
attachment.NameEncoding = Encoding.GetEncoding(encodingMarker);
string encodingtoken = String.Format("=?{0}?{1}?", encodingMarker, tranferEncodingMarker);
string softbreak = "?=";
string encodedAttachmentName = encodingtoken;
if (attachment.TransferEncoding == TransferEncoding.QuotedPrintable)
encodedAttachmentName = HttpUtility.UrlEncode(displayName, Encoding.Default).Replace("+", " ").Replace("%", "=");
else
encodedAttachmentName = Convert.ToBase64String(Encoding.UTF8.GetBytes(displayName));
encodedAttachmentName = SplitEncodedAttachmentName(encodingtoken, softbreak, maxChunkLength, encodedAttachmentName);
attachment.Name = encodedAttachmentName;
return attachment;
}
private static string SplitEncodedAttachmentName(string encodingtoken, string softbreak, int maxChunkLength, string encoded)
{
int splitLength = maxChunkLength - encodingtoken.Length - (softbreak.Length * 2);
var 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;
}