Веб-сервис C # Exchange - отправьте и немедленно получите отправленное сообщение - PullRequest
0 голосов
/ 20 февраля 2019

В системе, с которой я работаю, есть требование, чтобы MimeContent только что отправленного электронного письма сохранялось в локальной базе данных.Насколько я понимаю, как работает Exchange, я создаю MimeContent на сервере, и я не могу получить к нему доступ, пока не запросю у службы только что отправленное сообщение.

Итак, я предпринимаю следующие шаги:

- Отправьте электронное письмо и получите его Id

message.SendAndSaveCopy();
return message.Id.UniqueId;

- Используйте новый идентификатор, чтобы получить только что отправленного EmailMessage

ExchangeService exchangeService = ExchangeService;

var properties = new List<PropertyDefinitionBase>
{
    ItemSchema.MimeContent
};

EmailMessage message = EmailMessage.Bind(exchangeService, new ItemId(messageId), new PropertySet(BasePropertySet.IdOnly, properties));

Когдаэтот код работает без перерыва, он работает.Возвращенный Id все еще действителен (возможно, сообщение находится в папке «Исходящие»), и я получаю результат.Однако, если я замедляю его даже на секунду, идентификатор больше не действителен (я думаю, он теперь перемещен в отправленную папку).

Я не могу оставить его таким, так как нет гарантии, что я получувернуться на сервер вовремя, чтобы получить сообщение с этим Id.

. Если есть решение, при котором мне не нужно снова запрашивать службу для сообщения, это было бы здорово.Однако, если нет, могу ли я использовать Id и ChangeKey для получения только что отправленного электронного письма?

1 Ответ

0 голосов
/ 20 февраля 2019

В конце концов ответил на мой вопрос.Я сделал это, добавив пользовательское свойство к каждому электронному письму, которым я управляю.Затем я использую это же значение для поиска электронной почты.У меня были некоторые проблемы с перемещением электронной почты между папками между запросами, но теперь она сортируется.

  • Определите это где-нибудь, у меня оно есть в моем классе EmailProvider:

    private readonly PropertyDefinitionBase _TempEmailId = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "TempEmailId", MapiPropertyType.String);
    
  • Затем добавьте его непосредственно перед отправкой электронного письма:

    string messageId = null;
    if (getTempId)
    {
        messageId = Guid.NewGuid().ToString();
        message.SetExtendedProperty((ExtendedPropertyDefinition) _TempEmailId, messageId);
    }
    
    message.SendAndSaveCopy();
    return messageId;
    
  • Наконец, используйте messageId, чтобы получить MimeContent (или любые другие свойстваВы желаете):

    /// <summary>
    /// Get the mime content for an email just sent
    /// </summary>
    /// <param name="messageId"></param>
    /// <returns></returns>
    public byte[] GetJustSentMimeContent(string messageId)
    {
        ExchangeService exchangeService = ExchangeService;
    
        // Use the following search filter to get mail with TempEmailId set to what we just got
        var searchCriteria = new SearchFilter.IsEqualTo(_TempEmailId, messageId);
    
        var itemView = new ItemView(1) {PropertySet = new PropertySet(BasePropertySet.IdOnly)};
    
        byte[] GetMimeContent(WellKnownFolderName folder)
        {
            var items = exchangeService.FindItems(folder, searchCriteria, itemView);
    
            if (items.TotalCount > 0)
            {
                // if it's still in there, try and load the properties for it
                exchangeService.LoadPropertiesForItems(items,
                    new PropertySet(BasePropertySet.IdOnly,
                        ItemSchema.MimeContent));
    
                var emailMessage = (EmailMessage) items.First();
    
                // if the content has been loaded, return it
                if (emailMessage.MimeContent != null)
                    return emailMessage.MimeContent.Content;
            }
    
            return null;
        }
    
        // check the drafts folder to see if it's still in there
        var mimeContent = GetMimeContent(WellKnownFolderName.Drafts);
    
        if (mimeContent != null)
            return mimeContent;
    
        // if at this point, either: 
        // - email was moved to SentItems before the first search was done
        // - or email was found in Drafts but then moved to SentItems but before the MimeContent could be loaded. Need to restart the process and find the email in SentItems instead
    
        // should be in here (sentItems) now, try and load the properties for it
        return GetMimeContent(WellKnownFolderName.SentItems);
    }
    
...