MailKit 将 HtmlBody 以字符串形式写入数据库

MailKit write HtmlBody to the database in string

型号

 public class Mail
{
    public int Id { get; set; }
    public string Tema { get; set; }
    public string Note { get; set; }
    public string Date { get; set; }
    public string Email { get; set; }
}

客户端 IMAP

using (var client = new ImapClient())
        {
            var Emails = _context.Settings.FirstOrDefault();
            client.ServerCertificateValidationCallback = (s, c, h, e) => true;
            client.Connect(Emails.Imap,Convert.ToInt32(Emails.ImapPort), true);
            client.Authenticate(Emails.Login, Emails.Password);
            client.Inbox.Open(FolderAccess.ReadOnly);

            var inbox = client.Inbox;
            var messages = inbox.Fetch(0, -1, MessageSummaryItems.All | MessageSummaryItems.Full | MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure);
            if (messages.Where(c => c.Flags.Value.HasFlag(MessageFlags.Seen) != true).Count() > 0)
            {

                foreach (var message in messages.Where(c => c.Flags.Value.HasFlag(MessageFlags.Seen) != true))
                {
                    var mime = inbox.GetBodyPart(message.UniqueId, message.HtmlBody);
                    Mail mail = new Mail();
                    mail.Date = DateTime.Now;
                    mail.Note = Convert.ToString(mime);
                    mail.Tema = message.Envelope.Subject.ToString();
                    mail.Email = Convert.ToString(message.Date);
                    _context.Add(mail);
                    await _context.SaveChangesAsync();
                    break;
                }
            }
            client.Disconnect(true);
        }

结果,我在注释中得到了一个不可读的字符串

   Content-Type: text/html; charset="utf-8"
 Content-Transfer-Encoding: base64

 PGh0bWw+PGhlYWQ+PG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50
 PSJ0ZXh0L2h0bWw7Ij48dGl0bGU+0JzQldCU0JjQkNCb0J7Qk9CY0K88L3RpdGxlPjxz
 dHlsZT4uYmR7Zm9udDogMTI1JS8xMTUlIGFyaWFsLCBzYW5zLXNlcmlmOyBjb2xvcjog
 IzAwM0U1MDsgbWFyZ2luLXRvcDogMTJweH0gcHtmb250OiAxMDAlIGFyaWFsLCBzYW5z
 LXNlcmlmOyBjb2xvcjogIzAwM0U1MDsgbWFyZ2luLXRvcDogMTJweH0gdGR7Zm9udDog
 ODAlLzExNSUgYXJpYWwsIHNhbnMtc2VyaWY7IGNvbG9yOiAjMDAzRTUwOyBtYXJnaW4t
 dG9wOiAxMnB4fSB0ZC5oZHJ7Zm9udDogYm9sZCAxMXB4LzE0cHggYXJpYWwsIHNhbnMt
 c2VyaWY7IGNvbG9yOiAjMWIxYjU2OyBtYXJnaW4tdG9wOiAxMnB4OyBsaW5lLWhlaWdo
 dDoxNXB4O30gLnNlYXJjaF9obHtjb2xvcjogI2ZmZmZmZjtiYWNrZ3JvdW5kLWNvbG9y
 OiAjMDAzODQ4O308L3N0eWxlPjwvaGVhZD48Ym9keSBiZ2NvbG9yPSNGRkZGRkY+PHRh
 ......

在 "Content-Transfer-Encoding: base64" 之后,我们在 bass64 中看到 html 文件。 MileKit 有什么办法只记录文件数据本身吗?

您实际上是在调用 MimePart.ToString()... 而且,据 MimeKit 所知,您希望 MIME 作为字符串。

但这不是你真正想要的。

你要的是实际的文字内容

这是您需要在循环中执行的操作:

var html = (TextPart) inbox.GetBodyPart (message.UniqueId, message.HtmlBody);
Mail mail = new Mail();
mail.Date = DateTime.Now;
mail.Note = html.Text;
...

A TextPartMimePart 的子类,表示 text/* MIME 部分(包括 text/html)并且有一些非常方便的 API可用于获取(或设置)MimePart 的文本内容作为字符串,而不必处理流 - 最值得注意的是,.Text 属性.

这应该可以回答您的问题,但我还没有完成,因为您的代码还可以进行一些更改。

与其让 MailKit Fetch() 收件箱中每封邮件的元数据,不如只请求您需要的内容?

既然您显然不关心已经看到的消息,您可以利用 IMAP 的搜索功能,如下所示:

var uids = inbox.Search (SearchQuery.NotSeen);
if (uids.Count > 0)
{
    var messages = inbox.Fetch (uids, MessageSummaryItems.UniqueId | MessageSummaryItems.Envelope | MessageSummaryItems.Flags | MessageSummaryItems.BodyStructure);
    foreach (var message in messages.Where (c => !c.Flags.Value.HasFlag (MessageFlags.Seen))
    {
        // ...
    }
}

注意:您仍然需要使用 Where() 过滤器,因为消息标志可能会在 Search()Fetch() 之间更改(由另一个客户端)。我还将 MessageSummaryItems 更改为 您实际使用的字段。

您也可以删除 if (messages.Where(c => c.Flags.Value.HasFlag(MessageFlags.Seen) != true).Count() > 0) 语句,因为它是多余的,并且当您接下来要做的就是循环遍历数据时,它需要对返回的数据进行完整传递。

既然您一发现第一条未被查看的消息就break; 退出了循环,为什么不这样做呢?

var message = messages.FirstOrDefault (x => !x.Flags.Value.HasFlag (MessageFlags.Seen));
if (message != null)
{
    var html = (TextPart) inbox.GetBodyPart(message.UniqueId, message.HtmlBody);
    Mail mail = new Mail();
    mail.Date = DateTime.Now;
    mail.Note = html.Text;
    mail.Tema = message.Envelope.Subject;
    mail.Email = Convert.ToString(message.Envelope.Date);
    _context.Add(mail);
    await _context.SaveChangesAsync();
}

最终结果是:

using (var client = new ImapClient())
{
    var Emails = _context.Settings.FirstOrDefault();
    client.ServerCertificateValidationCallback = (s, c, h, e) => true;
    client.Connect(Emails.Imap,Convert.ToInt32(Emails.ImapPort), true);
    client.Authenticate(Emails.Login, Emails.Password);
    client.Inbox.Open(FolderAccess.ReadOnly);

    var inbox = client.Inbox;
    var uids = inbox.Search (SearchQuery.NotSeen);
    if (uids.Count > 0)
    {
        var messages = inbox.Fetch (uids, MessageSummaryItems.UniqueId | MessageSummaryItems.Envelope | MessageSummaryItems.Flags | MessageSummaryItems.BodyStructure);
        var message = messages.FirstOrDefault (x => !x.Flags.Value.HasFlag (MessageFlags.Seen));
        if (message != null)
        {
            var html = (TextPart) inbox.GetBodyPart(message.UniqueId, message.HtmlBody);
            Mail mail = new Mail();
            mail.Date = DateTime.Now;
            mail.Note = html.Text;
            mail.Tema = message.Envelope.Subject;
            mail.Email = Convert.ToString(message.Envelope.Date);
            _context.Add(mail);
            await _context.SaveChangesAsync();
        }
    }

    client.Disconnect(true);
}

您需要对上述代码进行的最后一项更改是如果邮件 没有 HTML 正文,该怎么办。如果消息只有 text/plain 正文怎么办?或者如果它根本不包含 any text/* 部分怎么办?

你需要弄清楚发生这种情况时你想做什么...