пятница, 25 января 2008 г.

Немного про почту

Последние три дня при слове "почта" громко матерюсь и скреплю зубами :)

Собственно, начну с начала.

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

Как-то пару лет назад я уже работал с почтой, но в тот раз я занимался отправкой писем. И было это все очень просто. Наивный я как обычно лезу в MSDN на предмет нахождения класса во фреймворке для работы с протоколом POP3...

Облом. Нету. И не было. Т.е. SMTP - есть, а POP3 - нету! Громко ругаюсь и лезу в гугловский поиск по исходникам. Нахожу несколько вариантов, но... все с разными глюками и на нужных мне письмах - падают. Наконец, после некоторого времени мучений и экспериментов я собираю из двух проектов более-менее рабочую конструкцию.

И все было-бы хорошо, пока я не попытался отправить письмо стандартными средствами фреймворка самому себе.

А теперь читаем внимательно: в письмах, которые я получал от разных источников все заголовки писались с заглавной буквы (Причем так письма отсылало более десятка программ). Пиьмо, сформированное средствами фреймворка содержит заголовки, написанные со строчной буквы.

Естественно, хлипкая конструкция для получения писем начала падать :( Путем целого дня отладки выяснилось, что научить ее корректно обрабатывать заголовки сообщения, написанные с маленькой буквы невозможно - фактически пришлось бы переписать 90% кода парсинга сообщений.

Сегодня опять полез в гугл - на этот раз нашел кое что более полезное проект OpenPOP.Net. Удивительно, но он не упал ни на одном письме из почтового ящика, включая и подписанные сертификатами :)

P.S.: кстати, после формирования и отсылки письма, содержащего аттачмент средствами класса System.Net.Mail.SmtpClient необходимо вызвать метод MailMessage.Dispose (т.е. у переменной, в которой производилось формирование письма). В противном случае файл-вложение окажется заблокирован на неопределенное время и его нельзя будет ни удалить ни перезаписать пока не отработает сборщик мусора или программа не завершится.

6 комментариев:

  1. О, спасибо, пригодиться в хозяйстве
    :)

    ОтветитьУдалить
  2. Использую OpenPOP.dll и MIMEParser.dll из проекта OpenPOP.Net. Не получается получить ни один аттачмент, пишет кол-во 0 на любом сообщении. Подскажешь в чем проблема?
    aikimind@mail.ru заранее благодарен

    ОтветитьУдалить
  3. Все сам разобрался, оказывается я сообщение брал только в части заголовка pop.GetMessageHeader(i); а надо так OpenPOP.MIMEParser.Message _msg = pop.GetMessage(i, false); Библиотеки рабочие!

    ОтветитьУдалить
  4. Да, именно так - нельзя получить аттачмент не загрузив сообщение полностью. Особенности формата.

    Однако, все-таки небольшая ошибка при работе с аттачментами там есть. Не всегда парсер их видел. Я вроде бы ее пофиксил (по крайней мере больше сталкивался).

    В файл MIMEParser\MIME\Attachment.cs в 380 строку надо добавить вот такой код

    if ((strLine.ToLower() == "content-type: application/octet-stream;")
    && (strRet.IndexOf("name=") != -1))
    strLine = strRet;

    ОтветитьУдалить
  5. Столкнулся с аналогичной необходимостью - куча библиотек не умеет читать аттачменты как следует. Ещё попробуем и эту, спасибо за заметку!

    ОтветитьУдалить
  6. Спасибо Fahrain ! В моем случае помогло.

    ОтветитьУдалить