Правильный способ отправки электронной почты из службы Windows - PullRequest
7 голосов
/ 10 марта 2010

Мне нужно отправлять много писем (возможно, сотни в день) по расписанию. Я думаю сделать это следующим образом, но проблема в том, что мое поле Body может стать очень большим, и, если я добавлю его в виде строки, оно будет ужасным.

        SmtpClient client = new SmtpClient(); //host and port picked from web.config
        client.EnableSsl = true;

        MailMessage message = new MailMessage();

        message.Body = "test from winservice"; // HERE IS MY PROBLEM
        message.IsBodyHtml = true;
        message.From = new MailAddress("donotreply@abcde.com");
        message.Subject = "My subject";
        message.To.Add(new MailAddress("piniusha@abcde.com"));
        try
        {
            client.Send(message);
        }
        catch (Exception)
        {

        }

Когда я должен был сделать это со страницы aspx, я использовал

    MailDefinition message = new MailDefinition();  

    message.BodyFileName = @"~\EmailTemplate\Template1.htm";
    ListDictionary replacements = new ListDictionary();
    replacements.Add("<% Name %>", this.txtName.Text);
    replacements.Add("<% PhoneOrEmail %>", this.txtPhoneOrEmail.Text);
    replacements.Add("<% Message %>", this.txtMessage.Text);
    MailMessage msgHtml = message.CreateMailMessage(RECIPIENTS, replacements, new LiteralControl());

Я думаю, что это элегантное решение, но я не хочу ссылаться на System.Web.UI.WebControls.MailDefinition потому что я нахожусь в winservice.

Мои вопросы:

  1. Как лучше всего отправлять грузы? письма от winservice?
  2. Можно ли отправить его из gmail? учетная запись? или они собираются заблокировать меня через некоторое время?

спасибо за любую помощь.

Ответы [ 4 ]

5 голосов
/ 10 марта 2010

Почему бы вам не использовать ту же концепцию, что и MailDefinition? Загрузите тело из вашего файла шаблона, замените некоторые маркеры текстом из другого списка - стиль слияния почты?

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

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

message.IsBodyHtml = true;
message.From = new MailAddress("MailSender@MyCompany.com");
message.Subject = "My bogus email subject";

string[] lines = File.ReadAllLines(@"~\MergeData.csv");
string originalTemplate = File.ReadAllText(@"~\Template.htm");

foreach(string line in lines)
{
    /* Split out the merge data */
    string[] mergeData = line.Split(',');

    /* Reset the template - to revert changes made in previous loop */
    string currentTemplate = originalTemplate;

    /* Replace the merge tokens with actual data */
    currentTemplate = currentTemplate.Replace("[[FullNameToken]]", mergeData[0]); 
    currentTemplate = currentTemplate.Replace("[[FirstNameToken]]", mergeData[1]);
    currentTemplate = currentTemplate.Replace("[[OtherToken]]", mergeData[2]);

    /*... other token replacements as necessary.
     * tokens can be specified as necessary using whatever syntax you choose
     * just make sure that there's something denoting the token so you can
     * easily replace it */

    /* Transfer the merged template to the message body */
    message.Body = currentTemplate;

    /* Clear out the address from the previous loop before adding the current one */
    message.To.Clear();
    message.To.Add(new MailAddress(mergeData[3]));
    client.Send(message);
}
0 голосов
/ 10 марта 2010

Что не так с использованием

"messageBody".Replace("<% Name %>", curr.Name).Replace(....)...
?

Что касается sendign от gMail, вы можете сделать это через SMTP, но они не позволяют вам подделывать другой адрес «от», поэтому получатели увидят его как поступающий с адреса gMail.

0 голосов
/ 10 марта 2010

Я бы использовал какой-нибудь шаблонизатор. StringTemplate например.

0 голосов
/ 10 марта 2010

Простой ответ таков:

message.Body = File.ReadAllText(@"~\EmailTemplate\Template1.htm");

Я не уверен насчет ваших конкретных моментов, но я уверен, что кто-то еще ответит на них:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...