mailkit----163邮箱登录拉取邮件的坑

时间:2021-09-28 14:20:37

在使用mailkit的ImapClient拉取邮件的时候,如果我们使用的是网易的邮箱(如:163、126等),如果你没有按照网易的设置去打开IMAP协议,那么将无法登录邮箱,并且发送一封使用不安全的客户端登录邮箱的邮件到你的邮箱,但是使用网易自己的邮箱大师的话,可以轻易的登录,并不会提示。

这其实是网易故意设置的障碍,其实是网易需要我们表明我们登录的客户端身份,具体的原理和命令参照我上一篇文章查看IMAP ID COMMAND命令,下面只具体说说mailkit如何使用到这条命令,其实mailkit是提供这个命令的,足见mailkit的强大。

 ImapClient client = new ImapClient();

 string account = "xxxxxx@163.com";
string passWord = "xxxxxx"; try
{
client.Connect("imap.163.com", , true);
}
catch (ImapCommandException ex)
{
Console.WriteLine($"---------尝试连接时出错:{0}------------" + ex.Message);
}
catch (ImapProtocolException ex)
{
Console.WriteLine($"---------尝试连接时的协议错误:{0}------------" + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine($"---------服务器连接错误:{0}------------" + ex.Message);
} try
{
client.Authenticate(account, passWord);
}
catch (AuthenticationException ex)
{
Console.WriteLine($"---------无效的用户名或密码:{0}------------" + ex.Message);
}
catch (ImapCommandException ex)
{
Console.WriteLine($"---------尝试验证错误:{0}------------" + ex.Message);
}
catch (ImapProtocolException ex)
{
Console.WriteLine($"---------尝试验证时的协议错误:{0}------------" + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine($"---------账户认证错误:{0}------------" + ex.Message);
} var clientImplementation = new ImapImplementation
{
Name = "xxxxe",
Version = "2.0"
};
var serverImplementation = imapClient.Identify(clientImplementation); List<IMailFolder> mailFolderList = imapClient.GetFolders(imapClient.PersonalNamespaces[]).ToList();
if (mailFolderList != null)
{
IMailFolder InBoxFolder = mailFolderList.Find(o => o.FullName.ToUpper() == "INBOX");
}

注意下面这段代码:

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邮箱就没有要求,可以随便填,但有些邮件服务器是有要求的,只有服务器认可的客户端和版本才可以正常使用,服务器会拒绝非法客户端的,一切看邮件服务端的要求。