.net6 core Worker Service项目,使用Exchange Web Services (EWS) 分页获取电子邮件收件箱列表,邮件信息字段

Program.cs

安装包:Microsoft.AspNetCore.Hosting.WindowsServices、Microsoft.Extensions.Hosting、Microsoft.Extensions.Hosting.WindowsServices、Microsoft.Extensions.Logging.Log4Net.AspNetCore
新建Configs/log4net.config

using Com.Chinahorn.Exchange.WorkerService;IHost host = Host.CreateDefaultBuilder(args).UseWindowsService().ConfigureLogging(logging => logging.AddLog4Net("Configs/log4net.config")).ConfigureServices(services =>{services.AddHostedService<Worker>();}).Build();await host.RunAsync();

log4net.config

<?xml version="1.0" encoding="utf-8" ?>
<log4net><!-- Define some output appenders --><appender name="rollingAppender" type="log4net.Appender.RollingFileAppender"><!--    value="logs/log.log"--><file value="logs/" /><!--追加日志内容--><appendToFile value="true" /><!--防止多线程时不能写Log,官方说线程非安全--><lockingModel type="log4net.Appender.FileAppender+MinimalLock" /><!--可以为:Once|Size|Date|Composite--><!--Composite为Size和Date的组合--><rollingStyle value="Composite" /><!--当备份文件时,为文件名加的后缀--><datePattern value="yyyyMMddhh'.log'" /><!--日志最大个数,都是最新的--><!--rollingStyle节点为Size时,只能有value个日志--><!--rollingStyle节点为Composite时,每天有value个日志--><maxSizeRollBackups value="20" /><!--可用的单位:KB|MB|GB--><maximumFileSize value="3MB" /><!--置为true,当前最新日志文件名永远为file节中的名字--><staticLogFileName value="false" /><!--输出级别在INFO和ERROR之间的日志--><filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="ALL" /><param name="LevelMax" value="FATAL" /></filter><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/></layout></appender><root><!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--><!--OFF:0--><!--FATAL:FATAL--><!--ERROR: ERROR,FATAL--><!--WARN: WARN,ERROR,FATAL--><!--INFO: INFO,WARN,ERROR,FATAL--><!--DEBUG: INFO,WARN,ERROR,FATAL--><!--ALL: DEBUG,INFO,WARN,ERROR,FATAL--><priority value="ALL"/><level value="INFO"/><!--使用上面配置的那个规则,ref指定上面的规则名称--><appender-ref ref="rollingAppender" /></root>
</log4net>

Worker.cs

namespace Com.Chinahorn.Exchange.WorkerService
{public class Worker : BackgroundService{private readonly ILogger<Worker> _logger;public Worker(ILogger<Worker> logger){_logger = logger;}protected override async Task ExecuteAsync(CancellationToken stoppingToken){while (!stoppingToken.IsCancellationRequested){_logger.LogInformation("Com.Chinahorn.Exchange.Service Worker running Start: {time}", DateTimeOffset.Now);IConfiguration configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appsettings.json").Build();try{ExchangeMailFind exchangeMail = new ExchangeMailFind(_logger);exchangeMail.doWork();}catch (Exception ex){_logger.LogError("Com.Chinahorn.Exchange.Service Worker error: {ex}", ex);}_logger.LogInformation("Com.Chinahorn.Exchange.Service Worker running End : {time}", DateTimeOffset.Now);int workSplit = Convert.ToInt32(configuration.GetConnectionString("workSplit"));//workSplit = workSplit <= 5 ? 5 : workSplit;await Task.Delay(workSplit * 1000, stoppingToken);}}}
}

ExchangeMailFind.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Web;
using Com.Chinahorn.Exchange.DBHelper;
using Com.Chinahorn.Exchange.WorkerService;
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;public class ExchangeMailFind
{private readonly ILogger<Worker> _logger;public ExchangeMailFind(ILogger<Worker> logger){_logger = logger;}public void doWork(){IConfiguration configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appsettings.json").Build();string[] exchangeUrl = configuration.GetConnectionString("EWSUrl").Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);string[] username = configuration.GetConnectionString("MailUserName").Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);string[] password = configuration.GetConnectionString("MailPWD").Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);string[] MailDateFilter = configuration.GetConnectionString("MailDateFilter").Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);if (exchangeUrl.Length != username.Length && username.Length != password.Length && password.Length != MailDateFilter.Length){_logger.LogInformation("配置信息:EWSUrl、MailUserName、MailPWD设置有误,多套需对应设置");return;}int pagerSize = Convert.ToInt32(configuration.GetConnectionString("MailPagerSize"));SQLHelper db_helper = new SQLHelper();for (int k = 0; k < exchangeUrl.Length; k++){try{ServicePointManager.ServerCertificateValidationCallback = (RemoteCertificateValidationCallback)Delegate.Combine(ServicePointManager.ServerCertificateValidationCallback, (RemoteCertificateValidationCallback)((object sender, X509Certificate? cert, X509Chain? chain, SslPolicyErrors sslPolicyErrors) => true));ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);service.Url = new Uri(exchangeUrl[k]);string pwd = password[k];service.Credentials = new WebCredentials(username[k], pwd);_logger.LogInformation("doWork ExchangeService EWSUrl:" + exchangeUrl[k] + " 凭据验证成功");DateTime startDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));if (MailDateFilter.Length > 0 && !string.IsNullOrWhiteSpace(MailDateFilter[k])){startDate = Convert.ToDateTime(MailDateFilter[k]);}SearchFilter.IsGreaterThanOrEqualTo timeFilter = new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, startDate);ItemView view = new ItemView(pagerSize);view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.Subject, ItemSchema.DateTimeReceived);int offset = 0;//int i = 1;FindItemsResults<Item> findResults;do{view.Offset = offset;findResults = service.FindItems(WellKnownFolderName.Inbox, timeFilter, view);_logger.LogInformation("doWork 获取收件箱Count:" + findResults.Items.Count);foreach (Item item in findResults){EmailMessage email = EmailMessage.Bind(service, item.Id, new PropertySet(BasePropertySet.FirstClassProperties));//Console.WriteLine("序号: " + i);//Console.WriteLine("发件人: " + email.Sender.Name);//Console.WriteLine("发件邮箱: " + email.Sender.Address);//Console.WriteLine("主题: " + email.Subject);//Console.WriteLine("内容: " + email.Body);//Console.WriteLine("发送时间: " + email.DateTimeSent);//Console.WriteLine("收件人: " + email.ReceivedBy.Name);//Console.WriteLine("收件邮箱: " + email.ReceivedBy.Address);string AttachmentName = string.Empty;string AttachmentStream = string.Empty;try{foreach (Attachment attachment in email.Attachments){if (attachment is FileAttachment){FileAttachment fileAttachment = attachment as FileAttachment;Console.WriteLine("附件名称: " + fileAttachment.Name);AttachmentName = AttachmentName + fileAttachment.Name + ";";// 使用内存流读取文件内容using (MemoryStream ms = new MemoryStream()){fileAttachment.Load(ms);byte[] buffer = ms.ToArray();Console.WriteLine("附件文件流: " + Convert.ToBase64String(buffer));AttachmentStream = AttachmentStream + Convert.ToBase64String(buffer) + ";";}}}}catch (Exception ex){_logger.LogError("doWork email.Attachments循环报错:" + ex.Message, ex);}string CcRecipientsMail = string.Empty;foreach (EmailAddress cc in email.CcRecipients){Console.WriteLine("抄送人: " + cc.Address);CcRecipientsMail = CcRecipientsMail + cc.Address + ";";}string messageId = email.InternetMessageHeaders.Find("Message-ID").Value;_logger.LogInformation("doWork Message-ID:" + messageId);//Console.WriteLine("Message-ID:" + messageId);  }offset += findResults.Items.Count;Thread.Sleep(1000);}while (findResults.MoreAvailable);}catch (Exception ex){_logger.LogError("doWork exchangeUrl for k:" + k.ToString() + "报错:" + ex.Message, ex);}}}

appsettings.json

{"Logging": {"LogLevel": {"Default": "Information","Microsoft.Hosting.Lifetime": "Information"}},"ConnectionStrings": {"SQLConnStr": "server=.;uid=sa;pwd=xx;database=xx;Encrypt=True;TrustServerCertificate=True;",//Exchange WebService,多套用;标识(多套需对应设置)"EWSUrl": "https://mail.xx.com/EWS/Exchange.asmx",//Exchange用户名,多套用;标识(多套需对应设置)"MailUserName": "xx",//Exchange密码,多套用;标识(多套需对应设置)"MailPWD": "Vm1GbFkyNDNPREl3TWpJeEl5UndZWE56Y0c5eWRBPT0=",//获取特定时间之后的邮件(如果为空则获取当天的),多套用;标识(多套需对应设置)"MailDateFilter": "2024-04-28",//分页获取邮件数"MailPagerSize": "50","WorkSplit": "60" //服务轮询时间,秒}
}

项目结构图

项目结构图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1484106.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

poetry 使用

文心一言 "Poetry"一词在多个领域有不同的含义和用途。 1. 作为英语单词的“Poetry” 基本含义&#xff1a;主要用作名词&#xff0c;意为“诗歌&#xff1b;诗一般的美丽&#xff0c;诗的意境”等。它还可以指&#xff08;学校或大学里的&#xff09;诗歌课&…

C++基础语法:STL之容器(5)--序列容器中的list(二)

前言 "打牢基础,万事不愁" .C的基础语法的学习 引入 序列容器的学习.以<C Prime Plus> 6th Edition(以下称"本书")内容理解 本书中容器内容不多只有几页.最好是有数据结构方面的知识积累,如果没有在学的同时补上 接上一篇C基础语法:STL之容器…

鸿蒙开发StableDiffusion绘画应用

Stable Diffusion AI绘画 基于鸿蒙开发的Stable Diffusion应用。 Stable Diffusion Server后端代码 Stable Diffusion 鸿蒙应用代码 AI绘画 ​ 使用Axios发送post网络请求访问AI绘画服务器 api &#xff0c;支持生成图片保存到手机相册。后端服务是基于flaskStable Diffusion …

防火墙内容安全综合实验

一、实验拓扑 二、实验要求 1&#xff0c;假设内网用户需要通过外网的web服务器和pop3邮件服务器下载文件和邮件&#xff0c;内网的FTP服务器也需要接受外网用户上传的文件。针对该场景进行防病毒的防护。 2&#xff0c;我们需要针对办公区用户进行上网行为管理&#xff0c;要…

Linux云计算 |【第一阶段】SERVICES-DAY1

主要内容&#xff1a; Web基础应用、Web虚拟主机、NFS服务基础、自动触发挂载 实操环境准备&#xff1a; ① 设置SELinux运行模式 [rootsvr7 ~]# getenforce Permissive [rootsvr7 ~]# cat /etc/selinux/config SELINUXpermissive ... ② 停止防火墙服务 [rootsvr7 ~]# sy…

Elasticsearch:Retrievers 介绍 - Python Jupyter notebook

在今天的文章里&#xff0c;我是继上一篇文章 “Elasticsearch&#xff1a;介绍 retrievers - 搜索一切事物” 来使用一个可以在本地设置的 Elasticsearch 集群来展示 Retrievers 的使用。在本篇文章中&#xff0c;你将学到如下的内容&#xff1a; 从 Kaggle 下载 IMDB 数据集…

压缩pdf大小的方法 指定大小软件且清晰

在数字化时代&#xff0c;pdf文件因其良好的兼容性和稳定性&#xff0c;已成为文档分享的主流格式。然而&#xff0c;高版本的pdf文件往往体积较大&#xff0c;传输和存储都相对困难。本文将为您详细介绍几种简单有效的方法&#xff0c;帮助您减小pdf文件的大小&#xff0c;让您…

Direct3D入门指南:创建对象、绘制几何体

DirectX是一个复杂但功能强大的API集&#xff0c;掌握了DirectX&#xff0c;特别是Direct3D&#xff0c;就意味着能够开发出高性能的图形应用和游戏。下面为大家讲解Direct3D的基础入门知识&#xff0c;以便大家能够快速上手。 创建设备 在Direct3D中&#xff0c;所有图形渲染…

API vs 网页抓取:获取数据的最佳方式

获取准确和及时的数据对于大多数项目至关重要无论是对于企业、研究人员&#xff0c;还是开发人员来说&#xff0c;获取准确和及时的数据都至关重要。收集网页数据主要有两种方法&#xff1a;使用API&#xff08;应用程序接口&#xff09;和网页抓取——哪种方法更适合你的项目呢…

随手记:vsCode修改主题色为自定义颜色

因为工作需要长时间面对vscode&#xff0c;视力不好&#xff0c;想要把工具改成护眼色&#xff0c;于是就把vscode改成了自定义的护眼色 效果图&#xff1a; 操作步骤&#xff1a; 快捷键打开设置页面&#xff1a; 按住ctrlshiftp 选择Open setting 按回车键 打开setting页面编…

大数据黑名单是怎么回事?是如何形成的?

在金融借贷过程中&#xff0c;不少人都或多或少的听说过网贷黑名单&#xff0c;也就是大数据黑名单&#xff0c;如果自己的大数据设计黑名单了的话&#xff0c;正常的申贷一定会受到影响的&#xff0c;很多人都纳闷了&#xff0c;大数据黑名单是怎么回事?是如何形成的?下面小…

docker的学习(一):docker的基本概念和命令

简介 docker的学习&#xff0c;基本概念&#xff0c;以及镜像命令和容器命令的使用 docker docker的基本概念 一次镜像&#xff0c;处处运行。 在部署程序的过程中&#xff0c;往往是很繁琐的&#xff0c;要保证运行的环境&#xff0c;软件的版本&#xff0c;配置文件&…

MF173:将多个工作表转换成PDF文件

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

5.java操作RabbitMQ-简单队列

1.引入依赖 <!--rabbitmq依赖客户端--> <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId> </dependency> 操作文件的依赖 <!--操作文件流的一个依赖--> <dependency><groupId>c…

CH01_WPF概述

第1章&#xff1a;WPF概述 本章目标 了解Windows图形演化了解WPF高级API了解分辨率无关性概念了解WPF体系结构了解WPF 4.5 WPF概述 ​ 欢迎使用 Windows Presentation Foundation (WPF) 桌面指南&#xff0c;这是一个与分辨率无关的 UI 框架&#xff0c;使用基于矢量的呈现引…

【STM32】TIM定时中断(江科大)

1.定时器最基本功能&#xff1a;定时触发中断 2.定时器就是一个计数器&#xff0c;当这个计数器的输入是一个准确可靠的基准时钟的时候&#xff0c;它在对这个基准时钟进行计数的过程&#xff0c;实际上就是计时的过程&#xff08;比如在STM32中&#xff0c;定时器的基准时钟一…

verilog实现ram16*8 (vivado)

module ram_16x2 (input clk, // 时钟信号input we, // 写使能input en, // 使能信号input [3:0] addr, // 地址线input [1:0] datain, // 输入数据线output reg [1:0] dataout // 输出数据线 );// 定义存储器数组reg [1:0] mem [15:0];always (posedge…

JAVA基础:运用分包思想编写汽车管理系统

目录 前言 分包 主界面 添加页面 service层 domain层 查看界面 总结 前言 在编写Java业务的时候我们应该充分运用分包思想将不同功能的类放在不同的包里&#xff0c;如果我们将所有的类都放在同一个包中&#xff0c;以后维护起来也会很麻烦。我们今天就要用这种思想编写…

前端组件化探索与实践:Vue自定义暂无数据组件的开发与应用

摘要 随着前端开发技术的不断进步&#xff0c;组件化开发已成为提升开发效率、降低维护成本的关键手段。本文旨在通过介绍一款Vue自定义暂无数据组件的开发与实践&#xff0c;深入探讨前端组件化开发的重要性、优势及其在实际项目中的应用。 一、引言 在前端开发中&#xff0…

【杰理蓝牙开发】AC695x 按键 I/O key 互推接法接口分析

本文主要记录 杰理蓝牙AC695x 按键I/O key 互推接法接口分析 【杰理蓝牙开发】AC695x 按键 I/O key 互推接法接口分析 0. 个人简介 && 授权须知1. IOKEY 使用硬件设计1.1 一个按键接一个 IO1.1 一个按键接两个 IO2. IOKEY 【互推】接法原理分析2.1 定义按键的三个属性2…