基于Lumisoft.NET组件开发碰到乱码等一些问题的解决
在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:52GMT
Mime-Version: 1.0From:"wuhuacong2013@163.com" <wuhuacong2013@163.com>To:"wuhuacong@96900.com.cn" <wuhuacong@96900.com.cn>
有些邮件日期格式是2013-05-06 19:01:44,则Lumisoft组件无法解析,需要跟踪到他的邮件日期处理的代码,然后进行修改才可以实现正常的邮件日期解析了。
官方的代码如下所示。
publicDateTime Date
{get{if(this.IsDisposed){throw new ObjectDisposedException(this.GetType().Name);
}
MIME_h h= this.Header.GetFirst("Date");if(h != null){try{returnMIME_Utils.ParseRfc2822DateTime(((MIME_h_Unstructured)h).Value);
}catch{throw new ParseException("Header field 'Date' parsing failed.");
}
}else{returnDateTime.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)));
}
}
}
}
需要增加对普通日期格式的修改,修改后的代码如下所示
publicDateTime Date
{get{if(this.IsDisposed){throw new ObjectDisposedException(this.GetType().Name);
}
MIME_h h= this.Header.GetFirst("Date");if(h != null){try{returnMIME_Utils.ParseRfc2822DateTime(((MIME_h_Unstructured)h).Value);
}catch{//尝试转换正常的日期 DateTime dt;string dateString =((MIME_h_Unstructured)h).Value;bool success = DateTime.TryParse(dateString, outdt);if(success)
{returndt;
}else{throw new ParseException("Header field 'Date' parsing failed.");
}
}
}else{returnDateTime.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(stringinput)
{string regex = @"=\?(?<encode>.*?)\?B\?(?<body>.*?)\?=";
Regex re= new Regex(regex, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace |RegexOptions.Multiline);
MatchCollection mcs=re.Matches(input);foreach (Match mc inmcs)
{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);
}
}returninput;
}
如可以通过代码吧标题进行转码解析
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);
这样获取到的标题,以及邮件头部等信息,都是正常的了。