Outlook MailItem: Как определить, является ли почта входящей или исходящей?
Я пишу VSTO Outlook надстройку в C#, и мне нужно различать, является ли данный MailItem входящим или исходящим (или ни один, когда это, например, черновик).
Есть ли надежный способ сделать это? Лучшее решение, которое у меня сейчас есть, - это получить список получателей, копии и скрытые копии, загрузить адреса электронной почты с активных учетных записей и проверить, пересекаются ли эти два списка, но мне это кажется довольно хрупким, и я надеюсь, что есть лучшее решение,
Вариант использования: Я хотел бы получить соответствующую дату для электронного письма, которое может быть или ReceivedTime, или SentOn, но чтобы узнать, какой из них мне следует использовать, я должен знать, было ли отправлено или получено письмо.
Спасибо за идеи:)
10 ответов
Пришел на эту страницу, потому что у меня была такая же проблема в VBA. Проверка родительских папок обременительна, поскольку сообщение может содержать несколько папок в глубину (и, следовательно, вам нужно перебрать несколько папок), или пользователь мог изменить папку. Крайний пример: папка удаленных элементов содержит элементы как входящей, так и исходящей почты.
Я выбрал похожее решение для другого человека (Ади Кини) выше, где я проверяю ReceivedByName (я думаю, что он выбрал ReceivedEntryID). Свойство ReceivedByName всегда имеет значение Null ("") для отправленного сообщения, где бы оно ни находилось в данный момент. Этот метод может найти отправленный элемент, который был перетащен во входящие! Это кажется довольно надежным методом проверки.
Кажется странным, что такая очевидная вещь, как проверка, является ли почта входящей или исходящей, может сбить нас с толку!
Так я проверяю тип почты, и она работает, даже если почта перемещается в любую папку. Это решение использует PROPERTY ACCESSOR, который доступен в outlook 2007. Ниже приведен код
string PR_MAIL_HEADER_TAG = "http://schemas.microsoft.com/mapi/proptag/0x007D001E";
Outlook.PropertyAccessor oPropAccessor = mItemProp.PropertyAccessor;
string strHeader = (string)oPropAccessor.GetProperty(PR_MAIL_HEADER_TAG);
if (strHeader == "")
{
// MAIL IS OF TYPE SENTBOX
}
else
{
// MAIL IS OF TYPE INBOX
}
Я решил эту проблему, добавив новый UserProperty после отправки электронной почты. Поэтому, когда мне нужно проверить, было ли отправлено электронное письмо, я проверяю это свойство. Это работает, даже если электронная почта была перемещена из папки "Отправленные". Конечно, это работает только для вновь созданных электронных писем, но вы можете добавить это свойство ко всем электронным письмам в папке "Отправленные" при первом запуске. Единственная ошибка в том, что UserProperties печатаются по умолчанию, но это может быть переопределено.
Я пришел сюда с той же проблемой. Поскольку я буду явно предлагать, чтобы пользователь перемещал почту в какую-то папку в моем сценарии использования, проверка Parent не помогла бы...
Относительно MailItem.Sent: вы уверены, что MailItem.Sent работает таким образом? Я только что написал простой код, который будет проходить через мои Входящие и SentItems, и для почти всех из них Отправлено верно. Я предполагаю, что это действительно только указание, было ли отправлено письмо (= не черновик)...
MailItem.sent также подходит для входящих.
Как насчет проверки MailItem.ReceivedByEntryID. Но я уверен, что это не удастся (ReceivedByEntryID будет нулевым для писем во входящих), если вы говорите, импорт из Outlook Express или, возможно, какой-либо другой почтовой программы
Как вы сказали, перебор почтовых учетных записей / senderemail может помочь, но это не защищает от ошибок (например, если вы переименуете адрес электронной почты)
Для простого отправленного / полученного контроля по SMTP-адресу я предлагаю подход проверки адреса. Это можно сделать следующим образом:
'Get mail address sender
Dim mailSender As String = GetSenderSMTPAddress(outMailItem)
'Get current user mail address
Dim mailUser As String = OutlookMail2DocScriba.GetUserSMTPAddress(oNameSpace.CurrentUser.AddressEntry)
'If sender and current user matches is a sended mail, otherwise received
If String.Compare(mailSender, mailUser, True) = 0 Then
Return "Sended"
Else
Return "Received"
End If
Public Shared Function GetSenderSMTPAddress(ByVal mail As Outlook.MailItem) As String
'http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.oladdresslisttype.aspx
If mail Is Nothing Then
Throw New ArgumentNullException()
End If
If mail.SenderEmailType = "EX" Then
Dim sender As Outlook.AddressEntry = Nothing
Try
sender = mail.Sender
Catch ex As Exception
'Se non è stato in grado di reperire il sender (Outlook 2007),
'ignoro l'eccezione e procedo.
End Try
If sender IsNot Nothing Then
Return GetUserSMTPAddress(sender)
Else
Return Nothing
End If
Else
Return mail.SenderEmailAddress
End If
End Function
Public Shared Function GetUserSMTPAddress(ByVal sender As Outlook.AddressEntry) As String
'Now we have an AddressEntry representing the Sender
'http://msdn.microsoft.com/en-us/library/office/ff868214(v=office.15).aspx
Const EXCHANGE_USER_ADDRESS_ENTRY As Int32 = 0
Const EXCHANGE_REMOTE_USER_ADDRESS_ENTRY As Int32 = 5
Dim PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
If sender.AddressEntryUserType = EXCHANGE_USER_ADDRESS_ENTRY OrElse _
sender.AddressEntryUserType = EXCHANGE_REMOTE_USER_ADDRESS_ENTRY Then
'Use the ExchangeUser object PrimarySMTPAddress
Dim exchUser As Object = sender.GetExchangeUser()
If exchUser IsNot Nothing Then
Return exchUser.PrimarySmtpAddress
Else
Return Nothing
End If
Else
Return TryCast(sender.PropertyAccessor.GetProperty(PR_SMTP_ADDRESS), String)
End If
End Function
Посмотрите на свойство MailPtem.Parent - проверьте свойства папки, чтобы определить, являются ли они входящими, исходящими, черновиками, отправленными элементами и т. Д.
Я противоречу SenderName vs CurrentUser, чтобы различать электронные письма во входящих или отправленных папках.
Вы можете проверить, находится ли он внутри Outlook.OlDefaultFolders.olFolderInbox
или же olFolderOutbox
, тогда должны быть другие методы, которые вы можете использовать, чтобы проверить, находится ли он внутри одной из этих папок!
Outlook.Application _application = new Outlook.Application();
Outlook.MAPIFolder folder = _application.GetNamespace("MAPI").GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Вы пробовали свойство MailItem.Sent?
Это верно для входящих и ложных для исходящих.