Перехватить электронную почту перед отправкой (SmtpClient)

Я использую следующий код для отправки электронного письма:

using (var mailMessage = new MailMessage("[email protected]", "[email protected]"))
{
    mailMessage.Subject = "My topic";
    mailMessage.IsBodyHtml = true;
    mailMessage.Body = "My content";
    using (var smtpClient = new SmtpClient())
    {
        smtpClient.Send(mailMessage);
    }
}

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

<appSettings>
  [...]
  <add key="RedirectAllEmailsTo" value="[email protected]" />
</appSettings>

Если значение RedirectAllEmailsTo не пусто, я хочу, чтобы все электронные письма в моем приложении отправлялись на указанный адрес электронной почты, а не на назначенного получателя в моем экземпляре MailMessage.

Я также хотел бы изменить тему MailMessage, чтобы указать, кто должен получать электронное письмо, примерно так: «Моя тема (получатель: [email protected])».

Можно ли перехватывать электронные письма и изменять получателя, а также тему, или мне нужно написать свой собственный класс вместо прямого использования SmtpClient?

Это мой код. Надеюсь, есть лучший способ справиться с этим.

public static void SendEmail(MailMessage mailMessage)
{
    var redirectAllEmailsTo = ConfigurationManager.AppSettings["RedirectAllEmailsTo"];
    if (string.IsNullOrEmpty(redirectAllEmailsTo) == false)
    {
        mailMessage.Subject += string.Format(" (to: {0}, cc: {1}, bcc: {2})",
            string.Join(", ", mailMessage.To.Select(m => m.Address)),
            string.Join(", ", mailMessage.CC.Select(m => m.Address)),
            string.Join(", ", mailMessage.Bcc.Select(m => m.Address)));

        mailMessage.To.Clear();
        mailMessage.CC.Clear();
        mailMessage.Bcc.Clear();
        mailMessage.To.Add(redirectAllEmailsTo);
    }
    using (var smtpClient = new SmtpClient())
    {
        smtpClient.Send(mailMessage);
    }
}

person Martin    schedule 08.06.2013    source источник
comment
Почему бы не иметь файл конфигурации dev, который использует сервер smtp dev?   -  person Oded    schedule 08.06.2013
comment
@Oded: С таким же успехом ты мог бы дать ответ :)   -  person leppie    schedule 08.06.2013
comment
@leppie - достаточно честно. Сделанный.   -  person Oded    schedule 08.06.2013


Ответы (2)


Может быть, вам нужно просто создать простой класс-оболочку для SmtpClient с BeforeSend событием и / или желаемыми тематическими операциями, как это?

class SmtpClientWrapper
{
    SmtpClient _client = new SmtpClient();

    public event EventHandler BeforeSend;

    private void PreprocessMesage(MailMessage message)
    {
        //do something with the message topic, as you desire
    }

    public void Send(MailMessage message)
    {
        BeforeSend(this, EventArgs.Empty);
        PreprocessMessage(message);
        _client.Send(message);
    }
}
person hotkey    schedule 08.06.2013

Стандартный способ решения этой проблемы (то есть отказ от отправки электронной почты в среде разработки) - не перехватить электронную почту.

Он должен иметь отдельный *.config файл для вашей среды разработки, чем тот, который у вас есть в производственной среде - этим можно управлять с помощью преобразования конфигурации (с или без SlowCheetah) или любой другой раствор домашнего приготовления.

Этот файл конфигурации будет указывать на SMTP-сервер разработки - тот, который только принимает сообщения и не отправляет их. Есть множество способов сделать это.

person Oded    schedule 08.06.2013
comment
Очень интересно. В этом конкретном случае я хочу, чтобы все электронные письма отправлялись на определенный адрес электронной почты со списком получателей из исходного сообщения MailMessage в теме. Причина этого в том, что клиент этого проекта хочет поиграть с сайтом в среде разработки и получить все электронные письма с информацией о том, кто должен был получать каждое электронное письмо. - person Martin; 08.06.2013
comment
@Martin - Похоже, вы можете просто отправить дополнительное сообщение с диагностической информацией (например, список предполагаемых получателей) на указанный адрес. То, с чем можно использовать ConditionalAttribute. - person Oded; 08.06.2013
comment
@Martin: Это можно сделать разными способами. Основное предложение от меня - создать SmtpClient как локальную переменную. Затем примените то, что сказал Одед в терминах условной компиляции. - person leppie; 08.06.2013