基于Lumisoft.NET组件,使用IMAP协议收取邮件

简介: 基于Lumisoft.NET组件,使用IMAP协议收取邮件

在早期一直使用Lumisoft.NET组件来进行邮件的处理查找,对于邮件的处理非常方便,之前在随笔《基于Lumisoft.NET组件的POP3邮件接收和删除操作》中也介绍过基于POP3和SMPT进行邮件的收发处理,一般邮件服务器对于Pop3都是支持很好的,常规使用测试多个服务器都没问题,所以就没怎么研究IMAP协议的处理,本篇随笔基于原来POP3 的需求扩展了IMAP协议的处理。

1、创建IMAP收件辅助类

为了方便进行收取IMAP邮件的处理,我们创建一个ImapHelper,并传入相关用到的一些参数,用来封装收件的处理操作。

如下辅助类所示,传入服务器域名地址,端口,是否SSL,用户名和密码等信息。

 

 

接下来,我们需要连接服务器,并尝试获取授权信息,如果通过,则可以进行下一步获取邮件信息的操作,如下代码所示。

/// <summary>
        /// 收取邮件操作
        /// </summary>
        public void Receive()
        {
            using (var client = new IMAP_Client())
            {
                //创建日志处理
                client.Logger = new Logger();
                client.Logger.WriteLog += new EventHandler<WriteLogEventArgs>(WriteLog);//响应记录显示
                //使用账号密码,连接服务器
                client.Connect(server, port, useSsl);
                //登录获取授权操作
                client.Login(username, password);
                //var identity = client.AuthenticatedUserIdentity;
                //获取各个邮箱目录的概要信息
                client.GetFolders(null).ToList().ForEach(f =>
                {
                    Console.WriteLine(f.FolderName);
                    var s = client.FolderStatus(f.FolderName);
                    s.ToList().ForEach(sIt =>
                    {
                        Console.WriteLine("总数:{0},未读:{1},最近{2}", sIt.MessagesCount, sIt.MessagesCount, sIt.UnseenCount);
                    });
                });

我们登录获得授权后,测试获取各个目录的概要邮件信息,如总邮件数量,以及未读数量等等。

然后通过选择具体的邮箱目录,并设置返回信息包含的内容格式,以及从服务器返回那些序号的邮件等等,如下代码所示。

//选择邮箱
    client.SelectFolder("INBOX");
    //首先确定取第x到第n封邮件,"1:*"表示第1封到最后一封
    var seqSet = IMAP_t_SeqSet.Parse("1:*");
    var items = new IMAP_t_Fetch_i[]
    {
        new IMAP_t_Fetch_i_Envelope(),  //邮件的标题、正文等信息
        new IMAP_t_Fetch_i_Uid(),       //返回邮件的UID号,UID号是唯一标识邮件的一个号码
        new IMAP_t_Fetch_i_Flags(),     //此邮件的标志,应该是已读未读标志
        new IMAP_t_Fetch_i_InternalDate(),//貌似是收到的日期
        new IMAP_t_Fetch_i_Rfc822()     //Rfc822是标准的邮件数据流,可以通过Lumisoft.Net.Mail.Mail_Message对象解析出邮件的所有信息
    };

接着我们通过传入条件,并给他一个回调匿名函数处理相关的邮件信息,如下所示。

//Fetch 第一个参数false时seqSet有效
    client.Fetch(false, seqSet, items, (s, e) =>
    {
        //处理邮件的匿名函数内容
    });

接着我们处理邮件信息的转换,吧邮件信息转换为Mail_Message对象的信息,这个包含邮件相关的头部信息,正文,以及附件信息等全部内容。

var email = e.Value as IMAP_r_u_Fetch;
    if (email.Rfc822 != null)
    {
        email.Rfc822.Stream.Position = 0;
        var mime_message = Mail_Message.ParseFromStream(email.Rfc822.Stream);
        email.Rfc822.Stream.Close();

然后我们把邮件的信息进一步转换为我们需要存储在数据库的对象信息,最后写入数据库即可。

receiveInfo.ReceivedDate = DateTime.Now;//接收本地时间
    receiveInfo.Company_ID = this.companyId;
    receiveInfo.User_ID = this.userId;
    receiveInfo.Email = this.email;//接收Email账号
    receiveInfo.MailConfig_ID = this.mailConfig_ID;//接收Email账号的配置记录ID
    //每封Email会有一个在Pop3服务器范围内唯一的Id,检查这个Id是否存在就可以知道以前有没有接收过这封邮件
    receiveInfo.MailUid = email.UID.UID.ToString();
    try
    {
        //可能会出现【LumiSoft.Net.ParseException: Header field 'Date' parsing failed】异常错误。
        receiveInfo.SendDate = mime_message.Date;
    }
    catch (Exception ex)
    {
        receiveInfo.SendDate = Convert.ToDateTime("1900-1-1");//错误赋值一个日期
        error = string.Format("转换邮件的Date出错:账号{0} 邮件标题:{1}", username, mime_message.Subject);
        LogTextHelper.Error(error, ex);
    }
    //可能出现乱码问题,通过函数进行转换
    receiveInfo.Title = mime_message.Subject;//DecodeString(mime_header.Subject);
    receiveInfo.MailBody = mime_message.BodyText;
    try
    {
        if (!string.IsNullOrEmpty(mime_message.BodyHtmlText))
        {
            receiveInfo.MailBody = mime_message.BodyHtmlText;
        }
    }
    catch
    {
        //屏蔽编码出现错误的问题,错误在BodyText存在而BodyHtmlText不存在的时候,访问BodyHtmlText会出现
    }

写入数据库处理,调用我们通用处理类处理数据信息的存储即可。

#region 写入邮件信息到数据库
    int mailId = -1;
    try
    {
        mailId = BLLFactory<MailReceive>.Instance.Insert2(receiveInfo);
    }
    catch (Exception ex)
    {
        error = string.Format("写入邮件信息到数据库出错:账号{0}  邮件标题:{1}", username, mime_message.Subject);
        LogTextHelper.Error(error, ex);
    }
    if (mailId <= 0) return; //如果邮件没有保存,不要保存附件 
    #endregion

2、邮件的附件处理

邮件的附件,包含常规的邮件附件,以及嵌入正文的附件图片,因此需要进行不同类型的判断,并一起把附件获取下来存储,这样在显示的时候,才能正常显示相关的附件。

其中Mail_Message 对象有一个函数,可以获取全部这两类附件的信息到列表中。

public MIME_Entity[] GetAttachments(bool includeInline, bool includeEmbbedMessage)

这样我们来调用这个函数,然后进行附件的提取存储处理即可。

#region 邮件附件内容
    foreach (var entity in mime_message.GetAttachments(true, true))
    {
        string fileName = "";
        #region 判断是普通附件还是嵌入的内容附件
        if (entity.ContentDisposition != null &&
            entity.ContentDisposition.DispositionType == MIME_DispositionTypes.Attachment)
        {
            Console.WriteLine("Attachment: " + entity.ContentDisposition.Param_FileName);
            fileName = entity.ContentDisposition.Param_FileName;
        }
        else
        {
            string cid = entity.ContentID.Substring(1, entity.ContentID.Length - 2);
            if (entity.ContentType.Param_Name != null &&
                mime_message.BodyHtmlText.Contains(string.Format("cid:{0}", cid)))
            {
                Console.WriteLine("Embeded image: " + cid);
                fileName = cid;
            }
            else
            {
                Console.WriteLine("Unknown attachment.");
            }
        }

邮件的附件信息,entity对象需要转换为MIME_b_SinglepartBase进行处理的。

var byteObj = entity.Body as MIME_b_SinglepartBase;

因此我们可以通过文件方式存储它的字节数据,如下所示。

File.WriteAllBytes(filename, byteObj.Data);

或者调用附件信息进行存储处理(可以是本地存储、或者FTP上传等方式)

 

如对于测试带有嵌入图片,附件信息的邮件,这样处理能够顺利获取所有的附件信息。

 

因此可以使用邮件管理模块中的定时收发邮件的处理,实现邮件的接收和发送。

 

 

 

3、163邮箱对于IMAP协议不支持

在测试IMAP协议收取邮件的时候,对于POP3发现大多数邮箱都是支持的。

但虽然163邮箱对POP3的支持不错,对IMAP协议却不支持,都是使用授权码进行登录,也确实登录成功了,但是IMAP协议切换邮箱进行邮件收取的时候,就会提示

提示错误信息。

 00023 NO SELECT Unsafe Login. Please contact kefu@188.com for help

 

如有兴趣,了解Lumisoft.NET组件的相关使用内容,请参考我相关随笔,谢谢。

基于Lumisoft.NET组件和.NET API实现邮件发送功能的对比

基于Lumisoft.NET实现的邮件发送功能

基于Lumisoft.NET组件开发碰到乱码等一些问题的解决

基于Lumisoft.NET组件的SMTP账号登陆检测

邮件代收代发软件操作说明

邮件代收代发功能模块的操作界面设计和阶段性总结

专注于代码生成工具、.Net/.NetCore 框架架构及软件开发,以及各种Vue.js的前端技术应用。著有Winform开发框架/混合式开发框架、微信开发框架、Bootstrap开发框架、ABP开发框架、SqlSugar开发框架等框架产品。
 转载请注明出处:撰写人:伍华聪  http://www.iqidi.com

相关文章
|
7月前
|
前端开发 C# 数据库
.NET中使用BootstrapBlazor组件库Table实操篇
.NET中使用BootstrapBlazor组件库Table实操篇
179 0
|
7月前
|
开发框架 前端开发 .NET
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
169 3
|
2月前
使用的是.NET Framework 4.0,并且需要使用SMTP协议发送电子邮件
使用的是.NET Framework 4.0,并且需要使用SMTP协议发送电子邮件
59 1
|
1月前
|
消息中间件 Linux iOS开发
.NET 高性能异步套接字库,支持多协议、跨平台、高并发
【11月更文挑战第3天】本文介绍了高性能异步套接字库在网络编程中的重要性,特别是在处理大量并发连接的应用中。重点讨论了 .NET 中的 Socket.IO 和 SuperSocket 两个库,它们分别在多协议支持、跨平台特性和高并发处理方面表现出色。Socket.IO 基于 WebSocket 协议,支持多种通信协议和跨平台运行,适用于实时通信应用。SuperSocket 则通过事件驱动的异步编程模型,实现了高效的高并发处理,适用于需要自定义协议的场景。这些库各有特点,可根据具体需求选择合适的库。
|
2月前
.NET 4.0下实现.NET4.5的Task类相似功能组件
【10月更文挑战第29天】在.NET 4.0 环境下,可以使用 `BackgroundWorker` 类来实现类似于 .NET 4.5 中 `Task` 类的功能。`BackgroundWorker` 允许在后台执行耗时操作,同时不会阻塞用户界面线程,并支持进度报告和取消操作。尽管它有一些局限性,如复杂的事件处理模型和不灵活的任务管理方式,但在某些情况下仍能有效替代 `Task` 类。
|
7月前
|
搜索推荐 API C#
.NET开源快速、强大、免费的电子表格组件
.NET开源快速、强大、免费的电子表格组件
120 0
|
5月前
|
存储 对象存储 Python
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
|
6月前
|
NoSQL 大数据 Redis
分享5款.NET开源免费的Redis客户端组件库
分享5款.NET开源免费的Redis客户端组件库
106 1