.Net 访问电子邮箱-LumiSoft.Net,好用

序言:

网上找了很多关于.Net如何访问电子邮箱的方法,但是大多数都达不到想要的需求,只有一些 收发邮件。因此 花了很大功夫去看 LumiSoft.Net.dll 的源码,总算做出自己想要的结果了,果然学习诗人进步。

介绍:

LumiSoft.Net.dll 是 C# 下的 免费开源 的关于网络 编程 的 一个类库,功能强大,包含FTP、FTP.Client、ICMP、IMAP、POP3、SMTP,如下图:

需求:

1、实现访问电子邮箱;

2、获取具体的某个文件夹下的邮箱,得到邮件的标题;

3、解析邮件的附件,并数据导入到数据库;

4、返回具体的邮件报错信息,发给相关人;

5、将导入数据库成功的邮件移入到另一个文件夹,失败的邮件 移入到另一个文件夹

实现步骤:

一、定义需要用到的信息变量

cs 复制代码
private string server = 服务器地址;
private int port = 端口号;
private bool useSsl = true;//是否跳过SSL验证
private string username = 邮件帐户;
private string password = 邮箱密码; 

二、访问电子邮箱

cs 复制代码
IMAP_Client client = new IMAP_Client();
useSsl = false;
client.Connect(server, port, useSsl);
//登录获取授权操作
client.Login(username, password);

三、获取各个邮箱的概要信息

cs 复制代码
//获取各个邮箱目录的概要信息
client.GetFolders(null).ToList().ForEach(f =>
{
	fileNameStrs = fileNameStrs + ";" + f.FolderName;
	var list = client.FolderStatus(f.FolderName).ToList();
	foreach (var item in list)
	{
		emailInfo = emailInfo + ";" + "总数:" + item.MessagesCount + ",未读:" + item.MessagesCount + ",最近" + item.UnseenCount;
	}
});
//选择邮箱下的文件夹,这里面有自己需要的邮件
client.SelectFolder(邮箱下的文件夹);
//取出收件箱
var folder = client.SelectedFolder;
//邮件总数
var MessagesCount = folder.MessagesCount;
//未读邮件总数
var RecentMessagesCount = folder.RecentMessagesCount;

四、解析某个文件夹下的邮件信息,并导入数据库,移动相关邮件

cs 复制代码
//代表该文件夹下有邮件存在
if (MessagesCount > 0)
{
	//首先确定取第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) =>
	{
		var isSuccees = true;
		//处理邮件的匿名函数内容
		var email = e.Value as IMAP_r_u_Fetch;
		if (email != null && email.Rfc822 != null)
		{
			email.Rfc822.Stream.Position = 0;
			var mime_message = Mail_Message.ParseFromStream(email.Rfc822.Stream);
			email.Rfc822.Stream.Close();

			//每封Email会有一个唯一的Id,检查这个Id是否存在就可以知道以前有没有接收过这封邮件
			var UID = email.UID.UID;

			//可能出现乱码问题,通过函数进行转换 //DecodeString(mime_header.Subject);
			var emailTitle = mime_message.Subject;//邮件标题
			var emailFrom = mime_message.From;//邮件发送人
			var emailTo = mime_message.To;//邮件抄送人

			//循环每个附件,并判断附件的后缀名是否满足要求
			var file = mime_message.GetAttachments(true, true);
			foreach (var entity in file)
			{
				if (entity.ContentDescription.IndexOf(".xlsx") <= 0 || entity.ContentDescription.IndexOf(".xls") <= 0)
				{
					errorMessage += "标题为'" + emailTitle + "'的邮件,附件格式错误,请检查邮件附件必须为(.xlsx/.xls)文件后缀格式";
					isSuccees = false;
				}
				else
				{
					try
					{
						#region 解析附件,得到 单据信息
						string fileName = "";
						//判断是普通附件还是嵌入的内容附件
						//if (entity.ContentDisposition != null && entity.ContentDisposition.DispositionType == MIME_DispositionTypes.Attachment)
							
						//邮件的附件名称
						fileName = entity.ContentDisposition.Param_FileName;
						
						//代表文件下载到本地
						//string localInbox = string.Format("{0}\\soEmail", Directory.GetCurrentDirectory());
						 If the folder is not existed, create it.
						//if (!Directory.Exists(localInbox))
						//{
						//    Directory.CreateDirectory(localInbox);
						//}
						//string fullPath = string.Format("{0}\\{1}", localInbox, fileName);

						//直接解析邮件里面的附件信息
						var byteObj = entity.Body as MIME_b_SinglepartBase;
						var stream = byteObj.GetDataStream();
						IWorkbook workbook = null;
						// 2007版本
						if (fileName.IndexOf(".xlsx") > 0)
						{
							workbook = new XSSFWorkbook(stream);
						}
						// 2003版本
						else if (fileName.IndexOf(".xls") > 0)
						{
							workbook = new HSSFWorkbook(stream);
						}
						var count = workbook.NumberOfSheets;
						ISheet sheet = null;
						for (int i = 0; i < count; i++)
						{
							//获取sheet表
							sheet = workbook.GetSheetAt(i);

							//这块根据自己的需求来写,
							#region 计算1-50行中 第一列包含第一个字符串 "aaa" 的行索引 index ; 
							int index = 0;
							for (int ro = 0; ro < 50; ro++)
							{
								IRow rows = sheet.GetRow(ro);
								if (rows.Cells != null && rows.Cells.Count > 0 && rows.GetCell(0) != null)
								{
									var cellValue = GetValueByType(rows.GetCell(0));
									if (cellValue.ToLower().Contains("aaa"))
									{
										index = ro;
										break;
									}
								}
							}
							#endregion
							if (index == 0)//excel附件找不到 "aaa" 的列名信息
							{
								errorMessage += "标题为'" + emailTitle + "'的邮件,在附件信息中找不到aaa的列名信息";
								isSuccees = false;
								break;
							}
							#region 获取 需要保存数据库的数据
							var cellIndex = index + 1;//对应Excel中 开始获取aaa数据的行索引
							var code = "";//code
							var name = "";//名称
							for (int ro = cellIndex; ro < 1000; ro++)
							{
								IRow rows = sheet.GetRow(ro);
								//判断是否为合并单元格
								if (rows.GetCell(0).IsMergedCell)
								{
									//读取合并单元格的值
									var cell = MergedCell(rows.GetCell(0));
									code = GetValueByType(cell);
								}
								else
								{
									code = GetValueByType(rows.GetCell(0));
								}
								//判断是否为合并单元格
								if (rows.GetCell(1).IsMergedCell)
								{
									//读取合并单元格的值
									var cell = MergedCell(rows.GetCell(1));
									name = GetValueByType(cell);
								}
								else
								{
									name = GetValueByType(rows.GetCell(1));
								}
								//如果 code和name都为空,则直接跳出循环
								if (string.IsNullOrEmpty(code) && string.IsNullOrEmpty(name))
								{
									//第一行
									if (ro == cellIndex)
									{
										errorMessage += "标题为'" + emailTitle + "'的邮件,在附件信息中第" + cellIndex + "行的数据信息全部为必填,不能为空,请检查邮件附件信息;";
										isSuccees = false;
									}
									break;
								}
								//Excel中第cellIndex行,第1-2列的字段不能为空值
								if (!string.IsNullOrEmpty(code) && !string.IsNullOrEmpty(name))
								{
									//将解析后的数据插入是list中
									Model model = new Model();
									model.code = code;
									model.name = name;
									list.Add(model);
								}

								if (list != null && list.Count > 0)
								{
									result.Succeeded = true;
									result.Data = list.Count + "条数据插入成功," + errorMessage;
									//执行插入数据库

								}
							}
							#endregion
						}
						sheet = null;
						workbook = null;
						stream.Close();
						stream.Dispose();
						#endregion
					}
					catch (Exception ex)
					{
						errorMessage += "标题为'" + emailTitle + "'," + ex.Message + ex.InnerException;
						isSuccees = false;
						break;
					}
				}
			}
			if (isSuccees)
			{
				trueUid.Add(UID);//表示 每封邮件成功解析
			}
			else
			{
				flaseUid.Add(UID);//表示 邮件存在错误信息
			}
		}
	});
	foreach (var item in trueUid)
	{
		//将成功的邮件移动到 另一个文件夹
		var value = "" + item + ":" + item + "";
		var setIndex = IMAP_t_SeqSet.Parse(value);
		client.MoveMessages(true, setIndex, "TestEmailComplete", true);
	}
	foreach (var item in flaseUid)
	{
		//将失败的邮件移动到 另一个文件夹
		var value = "" + item + ":" + item + "";
		var setIndex = IMAP_t_SeqSet.Parse(value);
		client.MoveMessages(true, setIndex, "TestEmailError", true);
	}
	client.Dispose();
}
else
{
	errorMessage = "操作成功";
}

五、邮件移动方法

IMAP_t_SeqSet.Parse(value)方法:

根据uid获取到第几封邮件,每一封邮件都有唯一的uid;格式 "1:3",代表1

cs 复制代码
	foreach (var item in trueUid)
	{
		//将成功的邮件移动到 另一个文件夹
		var value = "" + item + ":" + item + "";
		var setIndex = IMAP_t_SeqSet.Parse(value);
		client.MoveMessages(true, setIndex, "TestEmailComplete", true);
	}
	foreach (var item in flaseUid)
	{
		//将失败的邮件移动到 另一个文件夹
		var value = "" + item + ":" + item + "";
		var setIndex = IMAP_t_SeqSet.Parse(value);
		client.MoveMessages(true, setIndex, "TestEmailError", true);
	}
相关推荐
BingoGo8 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack8 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack3 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1234 天前
matlab画图工具
开发语言·matlab
dustcell.4 天前
haproxy七层代理
java·开发语言·前端