如何用C#读取带MAPI .pst的POP3 Outlook账户完整邮件正文
问题:POP3邮件正文无法完整读取(Mac环境)
背景
- 连接配置了MAPI个人存储文件夹(.pst)的Outlook POP3账户,因MAPI未同步文件夹,所有邮件集中显示,通过IF语句筛选特定发件人(
no-reply@property24.com)的邮件,已成功读取邮件头、发件人、主题,但非目标邮件不处理。 - 尝试用
Console.WriteLine(message.FindFirstPlainTextVersion().GetBodyAsText());读取正文时,仅能获取第一段,无法读取完整内容。 - 运行环境为Mac系统,无法使用
Microsoft.Office.Interop.Outlook命名空间。
当前代码
using System; using OpenPop.Pop3; using OpenPop.Pop3.Exceptions; using OpenPop.Mime.Header; using OpenPop.Mime; using Org.BouncyCastle.Asn1.X509; using MimeKit; namespace Ada_Buyers { class Program { static void Main(string[] args) { // Create an instance of the Pop3Client class Pop3Client client = new Pop3Client(); // Specify host, username, password, Port and SecurityOptions for your client client.Connect("hostnumber", port, true); // Authenticate with the server using username and password client.Authenticate("name@email.com", "password"); // Print message after connection Console.WriteLine(Environment.NewLine + "Connected to POP3 server."); // Get the number of messages in the inbox folder int messageCount = client.GetMessageCount(); Console.WriteLine($"Number of messages in inbox folder: {messageCount}"); // Print message before looping through messages Console.WriteLine("Looping through messages..."); int PrivatePropertyCount = 0; int PropertyTwentyFour = 0; int notapplicable = 0; for (int i = 1; i <= messageCount; i++) { try { // Get the message headers for the current message MessageHeader headers = client.GetMessageHeaders(i); // Check if the message is from the desired sender(s) if (headers.From != null && (headers.From.Address.Equals("no-reply@property24.com", StringComparison.OrdinalIgnoreCase))) { // Get the message using the message number var message = client.GetMessage(i); PropertyTwentyFour++; // Print the entire email Console.WriteLine("From: " + message.Headers.From.Address); Console.WriteLine("To: " + message.Headers.To[0].Address); Console.WriteLine("Subject: " + message.Headers.Subject); Console.WriteLine("Email Body:"); // 此处原本调用FindFirstPlainTextVersion().GetBodyAsText()仅能读取第一段 } else if (headers.From != null && (headers.From.Address.Equals("no-reply@property24.com", StringComparison.OrdinalIgnoreCase))) { // Get the message using the message number Message message = client.GetMessage(i); PropertyTwentyFour++; // Print the entire email Console.WriteLine("From: " + message.Headers.From.Address); Console.WriteLine("To: " + message.Headers.To[0].Address); Console.WriteLine("Subject: " + message.Headers.Subject); Console.WriteLine("Email Body:"); } else { notapplicable++; Console.WriteLine("Email number: " + i + " was not in private property or property 24 folder."); } } catch (Exception ex) { Console.WriteLine($"Error processing message {i}: {ex.Message}"); } } // Print the number of emails that contain the header no-reply@gumtree-protool.com Console.WriteLine($"Number of emails containing the header private Property: {PrivatePropertyCount}"); Console.WriteLine($"Number of emails containing the header Property 24 Alert: {PropertyTwentyFour}"); Console.WriteLine($"Number of emails not send from private property of property 24 is: {notapplicable}"); } } }
注:出于安全考虑,主机名、端口号、邮箱地址和密码已修改。
解决方案
问题原因
FindFirstPlainTextVersion()仅返回邮件中第一个找到的纯文本部分,若邮件是多部分结构(比如正文分段存储、或包含附件+正文),则无法获取完整内容。
修复方法
替换原有的正文读取代码,改为以下两种方式之一:
方法1:直接获取完整纯文本正文
使用Message.GetBodyAsText()方法可直接提取邮件的完整纯文本内容,无需手动查找文本部分:
Console.WriteLine("Email Body:"); // 获取完整纯文本正文 string fullBody = message.GetBodyAsText(); Console.WriteLine(fullBody);
方法2:遍历所有文本部分(适用于复杂多部分邮件)
如果GetBodyAsText()仍有异常,可手动遍历邮件的所有MIME部分,提取所有纯文本内容:
Console.WriteLine("Email Body:"); // 遍历所有文本类型的MIME部分 foreach (var part in message.FindAllTextParts()) { if (part.ContentType.MediaType.Equals("text/plain", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine(part.GetBodyAsText()); } }
额外代码优化
原代码中存在重复的IF判断逻辑(两个条件完全一致),可合并为一个分支,减少冗余:
// 合并重复的判断逻辑 if (headers.From != null && headers.From.Address.Equals("no-reply@property24.com", StringComparison.OrdinalIgnoreCase)) { var message = client.GetMessage(i); PropertyTwentyFour++; Console.WriteLine("From: " + message.Headers.From.Address); Console.WriteLine("To: " + message.Headers.To[0].Address); Console.WriteLine("Subject: " + message.Headers.Subject); Console.WriteLine("Email Body:"); string fullBody = message.GetBodyAsText(); Console.WriteLine(fullBody); } else { notapplicable++; Console.WriteLine("Email number: " + i + " was not in private property or property 24 folder."); }
内容的提问来源于stack exchange,提问作者Joruhan de Wit
相关产品推荐
相关产品推荐

