在Lumisoft.NET组件获取POP3邮件的时候,发现大多数邮件都能正常获取,不过对于一些特殊的邮件,好像总是会出现转换错误,或者出现乱码及部分乱码现象,有些在标题里面或者邮件接收人地址,而有些则在内容里面,为了更好整理相关的问题,写了本文,希望对大家使用该组件有一定的帮助作用。
1、 日期转换出错问题。
错误信息:[2013-05-04 10:49:03] 转换邮件的Date出错:账号wuhuacong@163.com 邮件标题:ICP???????????????????????wuhuacong)
LumiSoft.Net.ParseException: Header field 'Date' parsing failed.
在 LumiSoft.Net.Mail.Mail_Message.get_Date()
在 WHC.PlugInService.Pop3Helper.Receive() 位置 ......\Pop3Helper.cs:行号 160
错误原因:由于邮件格式的日期内容格式不同,导致无法正常解析。如一般的格式为下面
Message-ID: <d74841c5887b4df692ebdb7ec7802054@4782e72954a24cc89535840ea2e5da5b> Date: Fri, 26 Apr 2013 08:56:52 GMT Mime-Version: 1.0 From: "wuhuacong2013@163.com" <wuhuacong2013@163.com> To: "wuhuacong@96900.com.cn" <wuhuacong@96900.com.cn>
有些邮件日期格式是2013-05-06 19:01:44,则Lumisoft组件无法解析,需要跟踪到他的邮件日期处理的代码,然后进行修改才可以实现正常的邮件日期解析了。
官方的代码如下所示。
public DateTime Date { get{ if(this.IsDisposed){ throw new ObjectDisposedException(this.GetType().Name); } MIME_h h = this.Header.GetFirst("Date"); if(h != null){ try{ return MIME_Utils.ParseRfc2822DateTime(((MIME_h_Unstructured)h).Value); } catch{ throw new ParseException("Header field 'Date' parsing failed."); } } else{ return DateTime.MinValue; } } set{ if(this.IsDisposed){ throw new ObjectDisposedException(this.GetType().Name); } if(value == DateTime.MinValue){ this.Header.RemoveAll("Date"); } else{ MIME_h h = this.Header.GetFirst("Date"); if(h == null){ this.Header.Add(new MIME_h_Unstructured("Date",MIME_Utils.DateTimeToRfc2822(value))); } else{ this.Header.ReplaceFirst(new MIME_h_Unstructured("Date",MIME_Utils.DateTimeToRfc2822(value))); } } } }
需要增加对普通日期格式的修改,修改后的代码如下所示
public DateTime Date { get{ if(this.IsDisposed){ throw new ObjectDisposedException(this.GetType().Name); } MIME_h h = this.Header.GetFirst("Date"); if(h != null){ try{ return MIME_Utils.ParseRfc2822DateTime(((MIME_h_Unstructured)h).Value); } catch{ //尝试转换正常的日期 DateTime dt; string dateString = ((MIME_h_Unstructured)h).Value; bool success = DateTime.TryParse(dateString, out dt); if (success) { return dt; } else { throw new ParseException("Header field 'Date' parsing failed."); } } } else{ return DateTime.MinValue; } } set{ if(this.IsDisposed){ throw new ObjectDisposedException(this.GetType().Name); } if(value == DateTime.MinValue){ this.Header.RemoveAll("Date"); } else{ MIME_h h = this.Header.GetFirst("Date"); if(h == null){ this.Header.Add(new MIME_h_Unstructured("Date",MIME_Utils.DateTimeToRfc2822(value))); } else{ this.Header.ReplaceFirst(new MIME_h_Unstructured("Date",MIME_Utils.DateTimeToRfc2822(value))); } } } }
2、由于意外的数据包格式,握手失败
错误信息:[2013-05-04 10:13:54] System.IO.IOException: 由于意外的数据包格式,握手失败。
在 LumiSoft.Net.TCP.TCP_Client.Connect(String host, Int32 port, Boolean ssl)
在 WHC.PlugInService.SmtpHelper.Send() 位置 ........\SmtpHelper.cs:行号 123
在 WHC.PlugInService.SendMailService.DataThreadHandle(MailSendConfigInfo info) 位置 ...............\SendMailService.cs:行号 66
错误原因:由于POP3的配置端口不正确导致,一般的端口必须严格按照正常的来填写。
邮件SMTP和POP3常用配置说明:
邮箱 |
Smtp服务器 |
Smtp端口 |
POP3服务器 |
POP3端口 |
使用SSL |
Gmail.com |
smtp.gmail.com |
465 |
pop.gmail.com |
995 |
true |
QQ.com |
smtp.qq.com |
25 |
pop.qq.com |
110 |
true |
163.com |
smtp.163.com |
25 |
pop.163.com |
110 |
false |
Sina.com |
smtp.sina.com |
25 |
pop.sina.com |
110 |
false |
其他 |
smtp.test.com |
25 |
pop.test.com |
110 |
false |
3、邮件标题乱码问题
错误信息:标题出现类似=?utf-8?B?5rWL6K+V6YKu5Lu2?=
错误原因:这个是因为编码的问题,其中=?utf-8?B是表示该段字符为UTF-8的格式,后面的是base64格式的内容。除了utf-8,还可以出现gb2312或者ibm-euccn等格式。为了转换上面的编码问题,我写了一个转码函数,如下所示。
private string DecodeString(string input) { string regex = @"=\?(?<encode>.*?)\?B\?(?<body>.*?)\?="; Regex re = new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline); MatchCollection mcs = re.Matches(input); foreach (Match mc in mcs) { string encode = mc.Groups["encode"].Value; if (!string.IsNullOrEmpty(encode)) { if (encode.ToLower().Contains("euccn") || encode.ToLower().Contains("euc-cn") || encode.ToLower().Contains("gbk")) { encode = "gb2312"; } else if (encode.ToLower().Contains("utf8")) { encode = "utf-8"; } string body = mc.Groups["body"].Value; byte[] bytes = Convert.FromBase64String(body); string result = Encoding.GetEncoding(encode).GetString(bytes); input = input.Replace(mc.Value, result); } } return input; }
如可以通过代码吧标题进行转码解析
info.Title = DecodeString(mime_header.Subject);
转码后,标题和相关的内容都可以正常显示了。
除了上面的转码操作,还有一种更好的方法,能够使得邮件相关信息正常显示。
因为通过分析了解到,由于Lumisoft的Mail_Message.ParseFromByte函数默认只是以UTF8转换字节,一旦字节为GB2312格式,就会发生转换乱码问题,因此先经过Default编码转换,然后再以UTF8获取字节,即可正常转换邮件头部。
byte[] utf8Bytes = Encoding.UTF8.GetBytes(message.HeaderToString()); Mail_Message mime_header = Mail_Message.ParseFromByte(utf8Bytes);
这样获取到的标题,以及邮件头部等信息,都是正常的了。