使用MimeKit的MimeMessage.Load()解析邮件实体标头失败
解决MimeKit解析邮件流失败的问题
问题背景
从数据库提取邮件字符串转换为内存流后,调用MimeMessage.Load()解析邮件标头失败,Aspose可正常解析但无法使用,此前使用过MimeKit创建邮件,需解决解析问题。
现有错误代码
调用逻辑
MemoryStream ms = SerializeToStream(emailString); ms.Position = 0; MimeMessage mimeMessage = MimeMessage.Load(ms);
字符串转流方法
private MemoryStream SerializeToStream( object obj ) { MemoryStream stream = new MemoryStream(); using (var writer = new BinaryWriter(stream, Encoding.UTF8, true)) { writer.Write(obj.ToString()); } return stream; }
待解析邮件内容
MIME-Version: 1.0 From: "John Doe" <John.Doe@anycompany.co.uk> To: "John Doe" <John.Doe@anycompany.co.uk> Date: 04 May 2023 09:48:01 +0000 Subject: Simple no-frills email Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: quoted-printable <html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:sc= hemas-microsoft-com:office:office" xmlns:w=3D"urn:schemas-microso= ft-com:office:word" xmlns:m=3D"http://schemas.microsoft.com/offic= e/2004/12/omml" xmlns=3D"http://www.w3.org/TR/REC-html40"><head><= meta name=3DGenerator content=3D"Microsoft Word 15 (filtered medi= um)"><style><!--/* Font Definitions */@font-face {font-family:"Ca= mbria Math"; panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face {font-famil= y:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4;}/* Style Definitions */= p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0cm; font-size:1= 1.0pt; font-family:"Calibri",sans-serif; mso-ligatures:standardco= ntextual; mso-fareast-language:EN-US;}span.EmailStyle17 {mso-styl= e-type:personal-compose; font-family:"Calibri",sans-serif; color:= windowtext;}.MsoChpDefault {mso-style-type:export-only; font-fami= ly:"Calibri",sans-serif; mso-ligatures:standardcontextual; mso-fa= reast-language:EN-US;}@page WordSection1 {size:612.0pt 792.0pt; m= argin:72.0pt 72.0pt 72.0pt 72.0pt;}div.WordSection1 {page:WordSec= tion1;}--></style><!--[if gte mso 9]><xml><o:shapedefaults v:ext=3D= "edit" spidmax=3D"1026" /></xml><![endif]--><!--[if gte mso 9]><x= ml><o:shapelayout v:ext=3D"edit"><o:idmap v:ext=3D"edit" data=3D"= 1" /></o:shapelayout></xml><![endif]--></head><body lang=3DEN-GB = link=3D"#0563C1" vlink=3D"#954F72" style=3D'word-wrap:break-word'= ><div class=3DWordSection1><p class=3DMsoNormal>Hello<o:p></o:p><= /p><p class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal= ><span style=3D'font-size:10.0pt;color:black;mso-ligatures:none;m= so-fareast-language:EN-GB'>John Doe | Technical Consultant</span= ><span style=3D'mso-ligatures:none;mso-fareast-language:EN-GB'> <= br></span><span style=3D'font-size:10.0pt;color:black;mso-ligatur= es:none;mso-fareast-language:EN-GB'>T: +44 (0)1959 560410</span><= span style=3D'mso-ligatures:none;mso-fareast-language:EN-GB'> <br= ></span><span style=3D'font-size:10.0pt;color:black;mso-ligatures= :none;mso-fareast-language:EN-GB'>Any Company | the CRM exper= ts</span><span style=3D'mso-ligatures:none;mso-fareast-language:E= N-GB'> <br>&nbsp; </span><o:p></o:p></p></div></body></html>
问题根源
BinaryWriter.Write(string)方法会在写入字符串内容前,先写入一个7位编码的整数前缀表示字符串长度,这会在邮件流的开头添加额外字节,破坏了邮件原始的纯文本格式,导致MimeKit解析标头时出错。
修复方案
替换SerializeToStream方法,直接将邮件字符串转换为UTF-8字节数组写入内存流,避免添加额外前缀:
方法一:直接转换字节数组
private MemoryStream SerializeToStream(string emailString) { byte[] emailBytes = Encoding.UTF8.GetBytes(emailString); return new MemoryStream(emailBytes); }
方法二:使用StreamWriter写入
private MemoryStream SerializeToStream(string emailString) { MemoryStream stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true)) { writer.Write(emailString); } stream.Position = 0; return stream; }
验证
修改后调用MimeMessage.Load(ms)即可正常解析邮件内容,无需调整ParserOptions参数。
内容的提问来源于stack exchange,提问作者Kyle Wood
相关产品推荐
相关产品推荐

