| 
 在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);  
  
这样获取到的标题,以及邮件头部等信息,都是正常的了。  |