MimeKit转换MailMessage时为何修改HeadersEncoding?如何规避?
问题
我有一个MailMessage实例,将其HeadersEncoding设置为windows-1251。但用MimeMessage.CreateFromMailMessage(message)生成MimeMessage后,发现标头编码变成了UTF-8。请问MimeKit为什么会修改编码,怎么避免这个问题?
我的代码如下:
var message = new System.Net.Mail.MailMessage(); message.To.Add("somebody@example.com"); message.From = new MailAddress("someother@example.com", "display name"); message.Body = "<some message body>"; message.BodyEncoding = Encoding.GetEncoding("windows-1251"); message.SubjectEncoding = Encoding.GetEncoding("windows-1251"); message.HeadersEncoding = Encoding.GetEncoding("windows-1251");
用默认SMTP客户端发送时:
var client = new System.Net.Mail.SmtpClient(emailHost, settings.ServerPort); client.Send(message);
得到的From标头是=?windows-1251?q?...,符合预期。
但用MailKit的SMTP客户端发送时:
var client = new MailKit.Net.Smtp.SmtpClient(); var mimeMessage = MimeMessage.CreateFromMailMessage(message); client.Send(mimeMessage);
得到的From标头变成了=?utf-8?b?...。
原因分析
MimeKit的CreateFromMailMessage转换方法默认会把所有标头编码统一转为UTF-8。这是因为MimeKit遵循现代邮件规范,UTF-8的通用性更强,能更好地适配多语言场景,但这个逻辑会直接忽略原MailMessage中设置的HeadersEncoding。
解决办法
要保留windows-1251编码,有两种可行方式:
方式一:转换后手动修正编码
生成MimeMessage后,直接修改全局标头编码,同时重新编码带显示名称的地址(比如From、To等):
var mimeMessage = MimeMessage.CreateFromMailMessage(message); var win1251 = Encoding.GetEncoding("windows-1251"); // 设置全局标头编码为windows-1251 mimeMessage.HeaderEncoding = win1251; // 重新编码From地址的显示名称 var fromAddr = mimeMessage.From.FirstOrDefault() as MailboxAddress; if (fromAddr != null) { mimeMessage.From.Clear(); mimeMessage.From.Add(new MailboxAddress(win1251, fromAddr.Name, fromAddr.Address)); } // 若To/Cc等地址有显示名称,同理重新编码 var toAddr = mimeMessage.To.FirstOrDefault() as MailboxAddress; if (toAddr != null) { mimeMessage.To.Clear(); mimeMessage.To.Add(new MailboxAddress(win1251, toAddr.Name, toAddr.Address)); } // 重新指定主题编码 mimeMessage.SubjectEncoding = win1251;
方式二:手动构建MimeMessage(替代转换方法)
如果需要更精细的控制,可以直接手动创建MimeMessage,全程指定编码:
var mimeMessage = new MimeMessage(); var win1251 = Encoding.GetEncoding("windows-1251"); // 设置收件人、发件人,指定编码 mimeMessage.To.Add(new MailboxAddress(win1251, "", "somebody@example.com")); mimeMessage.From.Add(new MailboxAddress(win1251, "display name", "someother@example.com")); // 设置主题及编码 mimeMessage.Subject = message.Subject; mimeMessage.SubjectEncoding = win1251; // 构建正文并指定编码 var bodyBuilder = new BodyBuilder(); bodyBuilder.HtmlBody = message.Body; mimeMessage.Body = bodyBuilder.ToMessageBody(); foreach (var textPart in mimeMessage.BodyParts.OfType<TextPart>()) { textPart.ContentType.Charset = win1251.WebName; } // 设置全局标头编码 mimeMessage.HeaderEncoding = win1251;
内容的提问来源于stack exchange,提问作者Анастасия Качаева
相关产品推荐
相关产品推荐

