Как отправить электронное письмо с вложением, если вы олицетворяете и не имеете почтового ящика - PullRequest
0 голосов
/ 25 мая 2018

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

var service = new ExchangeService
{
    TraceEnabled = true,
    ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, Resources.EmailUsername)
};

service.AutodiscoverUrl(Resources.EmailUsername, RedirectionUrlValidationCallback);

var email = new EmailMessage(service);

if (!string.IsNullOrWhiteSpace(recipients))
{
    foreach (var recipient in recipients.Split(','))
    {
        email.ToRecipients.Add(recipient.Trim());
    }
}

email.Subject = subject;
email.Body = new MessageBody(BodyType.HTML, body);

if (attachmentName != null && attachment != null)
{
    email.Attachments.AddFileAttachment(attachmentName, attachment);                        
}

email.Send();

Сбой, и я получаю исключение, говорящее:

При отправке запроса в качестве учетной записи, у которой нет почтового ящика, необходимо указать основной SMTP-адрес почтового ящика для любых выделенных идентификаторов папок.

1 Ответ

0 голосов
/ 25 мая 2018

Часть TraceEnabled заставила меня заметить, что MessageDisposition=SaveOnly установлено в xml.Я посмотрел MessageDisposition и решил, что хочу SendOnly.

После долгих поисков я оказался здесь: https://github.com/OfficeDev/ews-managed-api/blob/master/Core/ServiceObjects/Items/EmailMessage.cs
Что показывает:

public void Send()
{
    this.InternalSend(null, MessageDisposition.SendOnly);
}

Ну, это похоже на то, что я хотел в первую очередь ... Но потом:

private void InternalSend(FolderId parentFolderId, MessageDisposition messageDisposition)
{
    this.ThrowIfThisIsAttachment();

    if (this.IsNew)
    {
        if ((this.Attachments.Count == 0) || (messageDisposition == MessageDisposition.SaveOnly))
        {
            this.InternalCreate(
                parentFolderId,
                messageDisposition,
                null);
        }
        else
        {
            // If the message has attachments, save as a draft (and add attachments) before sending.
            this.InternalCreate(
                null,                           // null means use the Drafts folder in the mailbox of the authenticated user.
                MessageDisposition.SaveOnly,
                null);

            this.Service.SendItem(this, parentFolderId);
        }
    }
    ...

Два комментария являются наиболее поучительными.Вложение сохраняется в папке черновиков пользователя, выполняющего процесс.
Чтобы обойти это, сообщение уже должно быть сохранено, когда мы вызываем команду Отправить.Давайте удостоверимся, что это сохранено в почтовом ящике, который, как мы знаем, существует.Поэтому мы удаляем олицетворение, добавляем шаг для его сохранения и изменяем поле От.Тогда мы сможем безопасно отправить сообщение, и оно удалит себя из черновой папки.

var service = new ExchangeService
{
    TraceEnabled = true
};

service.AutodiscoverUrl(Resources.EmailUsername, RedirectionUrlValidationCallback);

var email = new EmailMessage(service);

if (!string.IsNullOrWhiteSpace(recipients))
{
    foreach (var recipient in recipients.Split(','))
    {
        email.ToRecipients.Add(recipient.Trim());
    }
}

email.Subject = subject;
email.Body = new MessageBody(BodyType.HTML, body);

if (attachmentName != null && attachment != null)
{
    email.Attachments.AddFileAttachment(attachmentName, attachment);                        
}

var folderId = new FolderId(WellKnownFolderName.SentItems, Resources.EmailUsername);

email.Save(folderId);
email.From = Resources.EmailUsername;
email.Send();
...