mailkit----163邮箱登录拉取邮件的坑
在使用mailkit的ImapClient拉取邮件的时候,如果我们使用的是网易的邮箱(如:163、126等),如果你没有按照网易的设置去打开IMAP协议,那么将无法登录邮箱,并且发送一封使用不安全的客户端登录邮箱的邮件到你的邮箱,但是使用网易自己的邮箱大师的话,可以轻易的登录,并不会提示。
这其实是网易故意设置的障碍,其实是网易需要我们表明我们登录的客户端身份,具体的原理和命令参照我上一篇文章查看IMAP ID COMMAND命令,下面只具体说说mailkit如何使用到这条命令,其实mailkit是提供这个命令的,足见mailkit的强大。
1 ImapClient client = new ImapClient(); 2 3 string account = "xxxxxx@163.com"; 4 string passWord = "xxxxxx"; 5 6 7 try 8 { 9 client.Connect("imap.163.com", 993, true); 10 } 11 catch (ImapCommandException ex) 12 { 13 Console.WriteLine($"---------尝试连接时出错:{0}------------" + ex.Message); 14 } 15 catch (ImapProtocolException ex) 16 { 17 Console.WriteLine($"---------尝试连接时的协议错误:{0}------------" + ex.Message); 18 } 19 catch (Exception ex) 20 { 21 Console.WriteLine($"---------服务器连接错误:{0}------------" + ex.Message); 22 } 23 24 25 try 26 { 27 client.Authenticate(account, passWord); 28 } 29 catch (AuthenticationException ex) 30 { 31 Console.WriteLine($"---------无效的用户名或密码:{0}------------" + ex.Message); 32 } 33 catch (ImapCommandException ex) 34 { 35 Console.WriteLine($"---------尝试验证错误:{0}------------" + ex.Message); 36 } 37 catch (ImapProtocolException ex) 38 { 39 Console.WriteLine($"---------尝试验证时的协议错误:{0}------------" + ex.Message); 40 } 41 catch (Exception ex) 42 { 43 Console.WriteLine($"---------账户认证错误:{0}------------" + ex.Message); 44 } 45 46 var clientImplementation = new ImapImplementation 47 { 48 Name = "xxxxe", 49 Version = "2.0" 50 }; 51 var serverImplementation = imapClient.Identify(clientImplementation); 52 53 List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[0]).ToList(); 54 if (mailFolderList != null) 55 { 56 IMailFolder InBoxFolder = mailFolderList.Find(o => o.FullName.ToUpper() == "INBOX"); 57 }
注意下面这段代码:
var clientImplementation = new ImapImplementation
{
Name = "sssssd",
Version = "2.0"
};
var serverImplementation = imapClient.Identify(clientImplementation);
这句代码在登录完后需要执行,不然无法拉取文件夹。
mailkit还提供查询是否支持命令的语句,如果你不知道邮箱是否支持这个命令可以使用下面的函数来判断:
private static bool HasImapCapabilitiesId(ImapCapabilities sourceFlag, ImapCapabilities targetFlag)
{
return ((sourceFlag | targetFlag) == sourceFlag);
}
如上面的例子:则可以这样写:
//判断是否 添加ID COMMOND命令
if (HasImapCapabilitiesId(imapClient.Capabilities, ImapCapabilities.Id))
{
var clientImplementation = new ImapImplementation
{
Name = "dddddd",
Version = "2.0"
};
var serverImplementation = imapClient.Identify(clientImplementation);
}
则判断是否支持ID COMMAND,
这个命令主要是表面客户端身份的,参数name和version的值,可以按照需要去写,如上面的163邮箱就没有要求,可以随便填,但有些邮件服务器是有要求的,只有服务器认可的客户端和版本才可以正常使用,服务器会拒绝非法客户端的,一切看邮件服务端的要求。