текущий код не извлекает заголовки электронной почты для типа контента

Я использую код из этой ссылки для получения заголовков электронной почты из Outlook.

Но это неправильно извлекает тело электронной почты (тип содержимого). Все работает нормально. Если вы хотите сравнить, вы можете открыть gmail, посмотреть параметры gmail и нажать «показать оригинал», который правильно отображает заголовки.

Предоставление кода по ссылке выше:

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Office.Interop.Outlook;

public static class MailItemExtensions
{
    private const string HeaderRegex =
        @"^(?<header_key>[-A-Za-z0-9]+)(?<seperator>:[ \t]*)" +
            "(?<header_value>([^\r\n]|\r\n[ \t]+)*)(?<terminator>\r\n)";
    private const string TransportMessageHeadersSchema =
        "http://schemas.microsoft.com/mapi/proptag/0x007D001E";

    public static string[] Headers(this MailItem mailItem, string name)
    {
        var headers = mailItem.HeaderLookup();
        if (headers.Contains(name))
            return headers[name].ToArray();
        return new string[0];
    }

    public static ILookup<string, string> HeaderLookup(this MailItem mailItem)
    {
        var headerString = mailItem.HeaderString();
        var headerMatches = Regex.Matches
            (headerString, HeaderRegex, RegexOptions.Multiline).Cast<Match>();
        return headerMatches.ToLookup(
            h => h.Groups["header_key"].Value,
            h => h.Groups["header_value"].Value);
    }

    public static string HeaderString(this MailItem mailItem)
    {
        return (string)mailItem.PropertyAccessor
            .GetProperty(TransportMessageHeadersSchema);
    }
}

Выход:

MIME-Version: 1.0

Received: by someip with HTTP; Wed, 3 Dec 2014 10:04:00 -0800 (PST)

Date: Wed, 3 Dec 2014 23:34:00 +0530

Delivered-To: [email protected]

Message-ID: <[email protected]>

Subject: <subject here>

From: test name <test @gmail.com>

To: test name <test @gmail.com>

Content-Type: multipart/alternative; boundary=<somehash...>

Вывод из gmail (нажмите «показать оригинал» в параметрах сообщения gmail):

MIME-Version: 1.0
Received: by someiphere with HTTP; Wed, 3 Dec 2014 10:04:00 -0800 (PST)
Date: Wed, 3 Dec 2014 23:34:00 +0530
Delivered-To: [email protected]
Message-ID: <[email protected]>
Subject: subjecthere
From: test name <[email protected]>
To: test name <[email protected]>
Content-Type: multipart/alternative; boundary=somehash

--somehash
Content-Type: text/plain; charset=UTF-8

messagehere

--somehash
Content-Type: text/html; charset=UTF-8

<div dir="ltr">messagehere</div>

--somehash--

person user2349115    schedule 16.11.2014    source источник
comment
Когда вы выполняете свой код, что именно не работает? Правильно ли ваше регулярное выражение? Вы тестировали его, например, с regexpad.com/#p-javascript? Действительно ли заголовок содержит header_key или seperator› (так в оригинале)?   -  person Dmitry Streblechenko    schedule 03.12.2014
comment
mailitem.HeaderString() возвращает полные данные, кроме тела письма. Это связано с тем, что тело письма отображается в типе содержимого (по gmail) и содержит несколько новых строк, возможно, это не обрабатывается в коде. Кстати, это не мой код, я видел где-то в сети. Я еще не тестировал код в regexpad, я попробую   -  person user2349115    schedule 03.12.2014
comment
Я добавил вывод из Outlook, а также Gmail, чтобы вы могли сравнить.   -  person user2349115    schedule 03.12.2014
comment
Я отредактировал ваш заголовок. См. Должны ли вопросы включать «теги» в свои заголовки?, если нет единого мнения, не следует.   -  person John Saunders    schedule 03.12.2014


Ответы (2)


Свойство PR_TRANSPORT_MESSAGE_HEADERS возвращает только заголовки MIME основной части MIME. Фактические данные там не хранятся. Когда сообщение получено Outlook, заголовки анализируются в различных свойствах MAPI (например, «Тема» переходит в свойство PR_SUBJECT MAPI). Простое текстовое тело переходит в PR_BODY и т. д.

Просмотрите существующее сообщение с помощью OutlookSpy. Нажмите кнопку IMessage и выберите свойство PR_TRANSPORT_MESSAGE_HEADERS, чтобы просмотреть его содержимое.

ОБНОВЛЕНИЕ: вы можете преобразовать сообщение в формат MIME. Это не будет в точности то сообщение, которое пришло (порядок заголовков и частей сообщения MIME может отличаться). Вы также можете

  1. Используйте интерфейс MAPI IConverterSession (расширенный MAPI, поэтому только C++ или Delphi). Вы можете поиграть с этим интерфейсом в OutlookSpy (нажмите кнопку IConverterSession на ленте OutlookSpy).

  2. Создайте сообщение MIME явно в своем коде.

  3. Используйте Redemption и его RDOMail. Метод Save(..., olRfc822)

person Dmitry Streblechenko    schedule 03.12.2014
comment
Хорошо, я понял. В любом случае, я генерирую точное (почти) исходное сообщение? Мне удалось получить mailitem.htmlbody и body (html и простой). Итак, остались только те вещи, которые относятся к типу контента. Могу ли я получить и это? Если я могу получить, я могу вручную добавить вот так: r = headerstring. г += \n + get_text_content_type(); г += \n + mailitem.body; г += \n + get_html_content_type(); г += \n + mailitem.html_body; - person user2349115; 12.12.2014

Я знаю, что это очень старый вопрос, но я вижу его в верхней части поиска Google, поэтому я хочу поделиться своей находкой с другими парнями.

Я использовал приведенный ниже код для получения Content-Type в Outlook 2013/2016.

if (Globals.ThisAddIn.Application.Inspectors.Count > 0)
{
    Outlook.Inspector inspector = Globals.ThisAddIn.Application.ActiveInspector();
    if (inspector.CurrentItem is Outlook.MailItem)
    {
        Outlook.MailItem mail = (Outlook.MailItem)inspector.CurrentItem;
        string pidNameContentType = mail.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/content-type/0x0000001F");
    }
}
person coc2coc    schedule 28.12.2016