如何使用 C# 检查电子邮件中的文件?

How to check email for file using c#?

我每周都会收到一封包含 excel 文件的电子邮件。我知道可能有更好的方法来实现我的目标,但是是否有可能在 SSIS 中有一个脚本任务可以打开电子邮件,查找特定文件名作为附件,然后将该文件复制到另一个位置?

场景如下。这个 excel 文件对我的团队来说很重要 SQL 数据库,并且 excel 源的提供者只愿意每次通过电子邮件将这个 excel 文件发送给我们一次星期。然后我检查我的电子邮件,将文件复制到 SSIS 数据流任务可以拾取它并将其插入 SQL table 的位置。我想自动化这个。因此,如果我原来的方法不可行,那么如何实现自动化呢?除了使用共享网络位置。假设 excel 文件只能来自电子邮件。使用 outlook/office 365、SSIS、SSMS,我有 DBO 访问权限,并且可以使用 c#。

我承认我对电子邮件一无所知。如果有电子邮件客户端可以实际执行的程序来完成此操作,那么我会洗耳恭听!

编辑:我也可以访问网络驱动器,因为我意识到可能无法保存到本地计算机。

简单回答是的,这是可能的。

我已经编写了一个控制台程序来处理 Office365 上的电子邮件,我也正在与 SQL 交互,所以它绝对可以完成。它不一定是世界上最简单的事情,但也不是太难。

您可以使用托管的 Exchange Web 服务 (EWS) API

关于说明这是可能的文章和 API 文档 https://msdn.microsoft.com/en-us/library/office/dd877012(v=exchg.150).aspx

Github 可以找到 API 的位置(注意这个 link 直接来自 Microsoft 的站点) https://github.com/officedev/ews-managed-api

Link 关于如何引用包含上面第二个 link 的程序集: https://msdn.microsoft.com/en-us/library/office/dn528373(v=exchg.150).aspx

创建并连接到服务

string emailAddress = 'YourEmail@Domain.com';
ExchangeService exService = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exService.Credentials = new WebCredentials(emailAddress,"password");

您可以自动发现,或者如果您知道 URL 只需将其设置为其中 1 行

exService.AutodiscoverUrl(_emailAddress, delegate { return true; });
exService.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");

找到您的收件箱和一个文件夹,以便在处理后将文件移动到:

FolderView folderView = new FolderView(1);
folderView.PropertySet = new PropertySet(BasePropertySet.IdOnly);
folderView.PropertySet.Add(FolderSchema.DisplayName);
folderView.Traversal = FolderTraversal.Deep;
SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "ProcessedFolderName");
Folder Inbox = Folder.Bind(exService, WellKnownFolderName.Inbox);
FindFoldersResults folderResults = Inbox.FindFolders(searchFilter, folderView);
FolderId processedFolderId = folderResults.Folders[0].Id;

查找符合您条件的消息:

List<SearchFilter> searchFilterCollection = new List<SearchFilter();
searchFilterCollection.Add(new SearchFilter.ContainsSubstring(ItemSchema.Subject,"Words in Subject"));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(ItemSchema.HasAttachments,true));
searchFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema.From,new EmailAddress("From@SendersDomain.com")));
SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And,searchFilterCollection);

ItemView view = new ItemView(50, 0, OffsetBasePoint.Beginning);
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.DateTimeReceived, ItemSchema.Attachments);
view.Traversal = ItemTraversal.Shallow;
FindItemsResults<Item> findResults = exService.FindItems(WellKnownFolderName.Inbox,searchFilter,view);

处理结果并在完成后保存附件将邮件移动到另一个文件夹,这样您就不会继续导入同一个文件夹。

foreach (Item i in findResults.Items)
{
    foreach(FileAttachment attachment in i.Attachments)
    {
        attachment.Load(@"\FilePathDirectory\" + attachment.FileName);
    }

    i.Move(processedFolderId);
}

如果没有结果,您可以通过测试来扩展解决方案,向自己发送错误消息或抛出错误让 SSIS 拾取并使作业失败。如果您有多个消息要处理,您可能会多次覆盖该文件,因此您可以考虑在文件名中添加一些独特的内容,而不是只使用相同的名称,但这也会给 SSIS 带来其​​他挑战。

无论如何,这是一个开始希望它有所帮助。