.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"));
        for (int k = 0; k < exchangeUrl.Length; k++)
        {
            int offset = 0;
            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 = getDecodeBase64(Encoding.UTF8, 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 maxOffset = Int32.MaxValue - pagerSize; //考虑页大小的影响,避免溢出
                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);
                        StringBuilder AttachmentName = new StringBuilder();
                        StringBuilder AttachmentStream = new StringBuilder();
                        try
                        {
                            foreach (Attachment attachment in email.Attachments)
                            {
                                if (attachment is FileAttachment)
                                {
                                    FileAttachment fileAttachment = attachment as FileAttachment;
                                    Console.WriteLine("附件名称: " + fileAttachment.Name);
                                    AttachmentName.Append(fileAttachment.Name).Append(";");
                                    //使用内存流读取文件内容
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        fileAttachment.Load(ms);
                                        byte[] buffer = ms.ToArray();
                                        Console.WriteLine("附件文件流: " + Convert.ToBase64String(buffer));
                                        AttachmentStream.Append(Convert.ToBase64String(buffer)).Append(";");
                                    }
                                }
                            }
                        }
                        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 + ";";
                        }
                        try
                        {
                            string messageId = email.InternetMessageHeaders.Find("Message-ID").Value;
                            _logger.LogInformation("doWork Message-ID:" + messageId);
                            //Console.WriteLine("Message-ID:" + messageId);
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError("doWork sql拼接报错:" + ex.Message, ex);
                        }
                        //i++;
                    }
                    offset += findResults.Items.Count;

                    Thread.Sleep(1000);
                }
                while (findResults.MoreAvailable && offset <= maxOffset);
            }
            catch (Exception ex)
            {
                _logger.LogError("doWork exchangeUrl for k:" + k.ToString() + "报错:" + ex.Message+ " offset:"+ offset, 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" //服务轮询时间,秒
  }
}

项目结构图

项目结构图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小步快跑-

如有帮到您,给个赞赏(^.^)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值