当前位置: 首页 > news >正文

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

序言:

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

介绍:

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

需求:

        1、实现访问电子邮箱;

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

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

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

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

实现步骤:

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

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

        二、访问电子邮箱

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

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

//获取各个邮箱目录的概要信息
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;

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

//代表该文件夹下有邮件存在
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;}}}#endregionif (index == 0)//excel附件找不到 "aaa" 的列名信息{errorMessage += "标题为'" + emailTitle + "'的邮件,在附件信息中找不到aaa的列名信息";isSuccees = false;break;}#region 获取 需要保存数据库的数据var cellIndex = index + 1;//对应Excel中 开始获取aaa数据的行索引var code = "";//codevar 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

	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);}

相关文章:

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

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

谷粒商城-商品服务-新增商品功能开发(商品图片无法展示问题没有解决)

在网关配置路由 - id: member_routeuri: lb://gulimemberpredicates:- Path/api/gulimember/**filters:- RewritePath/api/(?<segment>.*),/$\{segment}并将所有逆向生成的工程调式出来 获取分类关联的品牌 例如&#xff1a;手机&#xff08;分类&#xff09;-> 品…...

Open3D 点云数据处理基础(Python版)

Open3D 点云数据处理基础&#xff08;Python版&#xff09; 文章目录 1 概述 2 安装 2.1 PyCharm 与 Python 安装 2.3 Anaconda 安装 2.4 Open3D 0.13.0 安装 2.5 新建一个 Python 项目 3 点云读写 4 点云可视化 2.1 可视化单个点云 2.2 同一窗口可视化多个点云 2.3…...

使用vue-qr,报错in ./node_modules/vue-qr/dist/vue-qr.js

找到node_modules—>vue-qr/dist/vue-qr.js文件&#xff0c;搜…e,将…去掉&#xff0c;然后重新运行项目。...

百川2大模型微调问题解决

之前用https://github.com/FlagAlpha/Llama2-Chinese微调过几个模型&#xff0c;总体来说llama2的生态还是比较好的&#xff0c;过程很顺利。微调百川2就没那么顺利了&#xff0c;所以简单做个记录 1. 数据准备&#xff0c;我的数据是单轮对话&#xff0c;之前微调llama2已经按…...

MySQL的事务-原子性

MySQL的事务处理具有ACID的特性&#xff0c;即原子性&#xff08;Atomicity)、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;和持久性&#xff08;Durability&#xff09;。 1. 原子性指的是事务中所有操作都是原子性的&#xff0c;要…...

D3839|完全背包

完全背包&#xff1a; 首先01背包的滚动数组中的解法是内嵌的循环是从大到小遍历&#xff0c;为了保证每个物品仅被添加一次。 for(int i 0; i < weight.size(); i) { // 遍历物品for(int j bagWeight; j > weight[i]; j--) { // 遍历背包容量dp[j] max(dp[j], dp[j…...

Java之Synchronized与锁升级

Synchronized与锁升级 一、概述 在多线程并发编程中 synchronized 一直是元老级角色&#xff0c;很多人都会称呼它为重量级锁。但是&#xff0c;随着 Java SE 1.6 对 synchronized 进行了各种优化之后&#xff0c;有些情况下它就并不那么重了。 本文详细介绍 Java SE 1.6 中为…...

kitex出现:open conf/test/conf.yaml: no such file or directory

open conf/test/conf.yaml: no such file or directory https://github.com/cloudwego/cwgo/issues/120 https://github.com/cloudwego/cwgo/issues/29 在使用Kitex生成的代码中&#xff0c;单元测试时回报错&#xff0c;如标题所示。出现该错的原因是&#xff0c;biz/servic…...

sql server多表查询

查询目标 现在有学生表和学生选课信息表&#xff0c;stu和stuSelect&#xff0c;stu中包含学生用户名、名字&#xff0c;stuSelect表中包含学生用户名&#xff0c;所选课程名 学生表&#xff1a; nameusername李明Li Ming李华Li Hua 学生选课表&#xff1a; usernameCourse…...

如何利用PPT绘图并导出清晰图片

在写论文的过程中&#xff0c;免不了需要绘图&#xff0c;但是visio等软件绘图没有在ppt上绘图比较熟练&#xff0c;尤其流程图结构图. 但是ppt导出的图片也不够清晰&#xff0c;默认分辨率是96dpi&#xff0c;而杂志投稿一般要求至300dpi。解决办法如下&#xff1a; 1.打开注…...

1.倒排索引 2.逻辑斯提回归算法

1.倒排索引 https://help.aliyun.com/zh/open-search/retrieval-engine-edition/introduction-to-inverted-indexes 倒排索引&#xff08;Inverted Index&#xff09;是一种数据结构&#xff0c;用于快速查找包含某个特定词或词语的文档。它主要用于全文搜索引擎等应用&#…...

Kafka消费者组

消费者总体工作流程 Consumer Group&#xff08;CG&#xff09;&#xff1a;消费者组&#xff0c;由多个consumer组成。形成一个消费者组的条件&#xff0c;是所有消费者的groupid相同。 • 消费者组内每个消费者负责消费不同分区的数据&#xff0c;一个分区只能由一个组内消费…...

四. 基于环视Camera的BEV感知算法-BEVDepth

目录 前言0. 简述1. 算法动机&开创性思路2. 主体结构3. 损失函数4. 性能对比总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Cam…...

CentOS系统环境搭建(二十五)——使用docker compose安装mysql

centos系统环境搭建专栏&#x1f517;点击跳转 文章目录 使用docker compose安装mysqlMySQL81.新建文件夹2.创建docker-compose.yaml3.创建my.cnf4.mysql容器的启动和关闭 MySQL5.71.新建文件夹2.创建docker-compose.yaml3.创建my.cnf4.mysql容器的启动和关闭 使用docker comp…...

协作机器人(Collaborative-Robot)安全碰撞的速度与接触力

协作机器人&#xff08;Collaborative-Robot&#xff09;的安全碰撞速度和接触力是一个非常重要的安全指标。在设计和使用协作机器人时&#xff0c;必须确保其与人类或其他物体的碰撞不会对人员造成伤害。 对于协作机器人的安全碰撞速度&#xff0c;一般会设定一个上限值&…...

第11章 GUI Page400~402 步骤二 画直线

运行效果&#xff1a; 源代码&#xff1a; /**************************************************************** Name: wxMyPainterApp.h* Purpose: Defines Application Class* Author: yanzhenxi (3065598272qq.com)* Created: 2023-12-21* Copyright: yanzhen…...

华为gre隧道全部跑静态路由

最终实现&#xff1a; 1、pc1能用nat上网ping能pc3 2、pc1能通过gre访问pc2 3、全部用静态路由做&#xff0c;没有用ospf&#xff0c;如果要用ospf&#xff0c;那么两边除了路由器上跑ospf&#xff0c;核心交换机也得用ospf r2配置&#xff1a; acl number 3000 rule 5 deny…...

【c++】入门1

c关键字 命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c;以避免命名冲突或名字污染&#xff…...

Python之Django项目的功能配置

1.创建Django项目 进入项目管理目录&#xff0c;比如&#xff1a;D盘 执行命令&#xff1a;diango-admin startproject demo1 创建项目 如果提示diango命令不存在&#xff0c;搜索diango-admin程序的位置&#xff0c;然后加入到环境变量path中。 进入项目&#xff0c;cd demo…...

跨平台鼠标控制库ez-cursor-free:原理、实现与自动化实战

1. 项目概述与核心价值如果你是一名开发者&#xff0c;尤其是经常需要处理跨平台UI自动化、游戏脚本或者桌面应用交互的开发者&#xff0c;那么你一定对“鼠标控制”这个基础但又充满细节的环节感到过头疼。不同的操作系统&#xff08;Windows, macOS, Linux&#xff09;提供了…...

构建个人技能图谱:从结构化设计到自动化可视化的实践指南

1. 项目概述&#xff1a;一个技能图谱的诞生最近在GitHub上看到一个挺有意思的项目&#xff0c;叫dortort/skills。初看这个仓库名&#xff0c;你可能会有点懵&#xff0c;dortort是作者&#xff0c;那skills是什么&#xff1f;点进去一看&#xff0c;发现它不是一个具体的工具…...

3个技巧让SD-PPP插件提升Photoshop设计效率300%

3个技巧让SD-PPP插件提升Photoshop设计效率300% 【免费下载链接】sd-ppp A Photoshop AI plugin 项目地址: https://gitcode.com/gh_mirrors/sd/sd-ppp 还在为Photoshop和AI工具之间的频繁切换而烦恼吗&#xff1f;每次都要导出PSD、上传到AI平台、等待生成、再导回Phot…...

基于Stellar的智能体经济安全与效率优化框架解析

1. 项目概述&#xff1a;一个面向智能体经济的安全与效率优化框架最近在探索智能体&#xff08;Agent&#xff09;应用生态时&#xff0c;我遇到了一个普遍存在的痛点&#xff1a;如何在一个去中心化、多智能体协作的网络中&#xff0c;既保证交互的安全与可信&#xff0c;又能…...

安卓客户端架构解析:从MVVM到网络通信的完整实践

1. 项目概述&#xff1a;一个面向安卓设备的智能客户端最近在整理手头的开源项目时&#xff0c;发现了一个挺有意思的仓库&#xff0c;名字叫TOM88812/xiaozhi-android-client。光看这个标题&#xff0c;你可能会有点摸不着头脑&#xff0c;这“小智”到底是个啥&#xff1f;是…...

微服务架构实战:从DDD设计到K8s部署的完整指南

1. 项目概述与核心价值最近几年&#xff0c;微服务架构的热度一直居高不下&#xff0c;从互联网大厂到初创团队&#xff0c;几乎人人都在谈微服务。但说实话&#xff0c;真正能把微服务玩转、落地&#xff0c;并且能稳定支撑业务发展的团队&#xff0c;其实并不多。很多项目要么…...

AI异步任务编排引擎:从原理到实战,构建可靠工作流系统

1. 项目概述&#xff1a;AI驱动的异步任务编排引擎在当今的软件开发领域&#xff0c;尤其是涉及数据处理、机器学习模型训练、自动化工作流等场景时&#xff0c;我们常常会面临一个核心挑战&#xff1a;如何高效、可靠地编排和管理一系列耗时且可能相互依赖的异步任务。传统的解…...

构建高质量Awesome清单:开源项目精选与维护实践指南

1. 项目概述&#xff1a;为什么我们需要一个“Awesome”清单&#xff1f;在开源的世界里&#xff0c;信息过载是每个开发者、技术爱好者乃至项目经理都面临的共同挑战。每天&#xff0c;GitHub、GitLab等平台上都会涌现出成千上万个新项目&#xff0c;从精巧的工具库到庞大的系…...

NeoPixel电源设计全攻略:从电流估算到多电源分配

1. 项目概述&#xff1a;为什么NeoPixel电源设计是成败关键如果你玩过NeoPixel或者类似的WS2812B可编程LED&#xff0c;大概率经历过这样的场景&#xff1a;精心设计的动画点亮了十几个灯珠&#xff0c;效果惊艳&#xff1b;但当你兴冲冲地把灯珠数量加到一百个&#xff0c;准备…...

绿色AI能耗优化:从模型架构到MLOps实践

1. 绿色AI能耗研究的现实意义在深度学习模型参数量呈指数级增长的今天&#xff0c;AI系统的能源消耗已成为不可忽视的环境负担。根据最新研究&#xff0c;训练一个大型语言模型的碳排放量相当于五辆汽车整个生命周期的排放总量。这种惊人的能源消耗与全球减碳目标形成了尖锐矛盾…...