Отправка электронной почты из расширения доставки пользовательских служб отчетов SQL Server - PullRequest
2 голосов
/ 28 августа 2008

Я разработал собственное расширение для Reporting Services 2005, чтобы интегрировать его с нашим маркетинговым решением SaaS.

Он принимает подписку и снимок отчета с настраиваемым набором параметров. Затем он отображает отчет, отправляет электронное письмо со ссылкой и отчет в виде XLS.

Все отлично работает, до доставки почты ...

Вот мой код для отправки электронной почты:

 public static List<string> SendMail(SubscriptionData data, Stream reportStream, string reportName, string smptServerHostname, int smtpServerPort)
{
  List<string> failedRecipients = new List<string>();

  MailMessage emailMessage = new MailMessage(data.ReplyTo, data.To);
  emailMessage.Priority = data.Priority;
  emailMessage.Subject = data.Subject;
  emailMessage.IsBodyHtml = false;
  emailMessage.Body = data.Comment;

  if (reportStream != null)
  {
    Attachment reportAttachment = new Attachment(reportStream, reportName);
    emailMessage.Attachments.Add(reportAttachment);
    reportStream.Dispose();
  }

  try
  {
    SmtpClient smtp = new SmtpClient(smptServerHostname, smtpServerPort);

    // Send the MailMessage
    smtp.Send(emailMessage);
  }
  catch (SmtpFailedRecipientsException ex)
  {
    // Delivery failed for the recipient. Add the e-mail address to the failedRecipients List
    failedRecipients.Add(ex.FailedRecipient);
  }
  catch (SmtpFailedRecipientException ex)
  {
    // Delivery failed for the recipient. Add the e-mail address to the failedRecipients List
    failedRecipients.Add(ex.FailedRecipient);
  }
  catch (SmtpException ex)
  {
    throw ex;
  }
  catch (Exception ex)
  {
    throw ex;
  }

  // Return the List of failed recipient e-mail addresses, so the client can maintain its list.
  return failedRecipients;
}

Значения для SmtpServerHostname - это localhost, а порт - 25.

Я очень уверен, что могу отправлять почту, используя Telnet. И это работает.

Вот сообщение об ошибке, которое я получаю от SSRS:

УведомлениеServicesService! Уведомление! 4! 08/28 / 2008-11: 26: 17 :: Уведомление 6ab32b8d-296e-47a2-8d96-09e81222985c завершено. Успех: Ложь, Статус: Исключение Сообщение: Ошибка при отправке почты. Stacktrace: at MyDeliveryExtension.MailDelivery.SendMail (данные SubscriptionData, Stream reportStream, String reportName, строка smptServerHostname, Int32 smtpServerPort) в C: \ inetpub \ wwwroot \ CustomReporting \ MyDeliveryExtension \ MailDelivery. в MyDeliveryExtension.MyDelivery.Deliver (Уведомление об уведомлении) в C: \ inetpub \ wwwroot \ CustomReporting \ MyDeliveryExtension \ MyDelivery.cs: строка 153, DeliveryExtension: Моя доставка, Отчет: Разработка кликов, Попытка 1 ReportingServicesService! Dbpolling! 4! 08/28 / 2008-11: 26: 17 :: УведомлениеПоллинг завершил обработку элемента 6ab32b8d-296e-47a2-8d96-09e81222985c

Может ли это быть как-то связано с безопасностью доступа через доверие / код?

Мое расширение доставки полностью доверяет rssrvpolicy.config:

   <CodeGroup 
    class="UnionCodeGroup"
    version="1"
    PermissionSetName="FullTrust"
    Name="MyDelivery_CodeGroup"
    Description="Code group for MyDelivery extension">
    <IMembershipCondition class="UrlMembershipCondition" version="1" Url="C:\Program Files\Microsoft SQL Server\MSSQL.2\Reporting Services\ReportServer\bin\MyDeliveryExtension.dll" />
   </CodeGroup> 

Может ли доверие быть проблемой здесь?

Другая теория: SQL Server и SSRS были установлены в контексте безопасности локальной системы. Я прав, или эта учетная запись службы ограничивает доступ к любому сетевому ресурсу? Даже свой собственный SMTP-сервер?

Я попытался изменить все учетные записи служб SQL Server на «Администратор», но все равно безуспешно.

Я также попытался войти на SMTP-сервер в своем коде, указав: NetworkCredential ("Администратор", "пароль"), а также NetworkCredential ("Администратор", "пароль", "MyRepServer")

Может кто-нибудь помочь здесь, пожалуйста?

Ответы [ 5 ]

0 голосов
/ 14 января 2010
FileStream m_fileStream = null;

m_files = notification.Report.Render(format, null);
RenderedOutputFile m_renderedOutputFile = m_files[0];
m_fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write);
m_renderedOutputFile.Data.Seek((long)0, SeekOrigin.Begin);
byte[] arr = new byte[(int)m_renderedOutputFile.Data.Length + 1];

m_renderedOutputFile.Data.Read(arr, 0, (int)m_renderedOutputFile.Data.Length);

m_fileStream.Write(arr, 0, (int)m_renderedOutputFile.Data.Length);

m_fileStream.Close();
0 голосов
/ 29 августа 2008

Вот почему вы должны избегать:

catch (Exception ex)
{
    throw ex;
}

Поскольку это в основном скрывает ваше исключение в новом.

Если вы используете:

catch (Exception ex)
{
    throw; //note: no ex
}

Сохраняет исходное исключение и трассировку стека.

0 голосов
/ 28 августа 2008

Я пытался удалить отчет Stream Attachment:

  //if (reportStream != null)    
     //emailMessage.Attachments.Add(new Attachment(reportStream, reportName));

А теперь работает нормально.

Так что это как-то связано с reportStream.

0 голосов
/ 28 августа 2008

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

Ошибка не в методе SendMail, а в другом месте. Исключение было брошено в контексте, хотя SendMail. Содомия!

0 голосов
/ 28 августа 2008

Что на:

at MyDeliveryExtension.MailDelivery.SendMail(SubscriptionData data, Stream reportStream, String reportName, String smptServerHostname, Int32 smtpServerPort) 
  in C:\inetpub\wwwroot\CustomReporting\MyDeliveryExtension\MailDelivery.cs:line 48 

at MyDeliveryExtension.MyDelivery.Deliver(Notification notification) 
  in C:\inetpub\wwwroot\CustomReporting\MyDeliveryExtension\MyDelivery.cs:line 153

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

Вы теряете часть трассировки стека из-за того, что вы перезапускаете исключения. Не бросайте переменную ex, достаточно просто throw.

Попробуйте этот твик:

public static List<string> SendMail(SubscriptionData data, Stream reportStream, string reportName, string smptServerHostname, int smtpServerPort)
{
  List<string> failedRecipients = new List<string>();

  MailMessage emailMessage = new MailMessage(data.ReplyTo, data.To) {
      Priority = data.Priority,
      Subject = data.Subject,
      IsBodyHtml = false,
      Body = data.Comment
  };

  if (reportStream != null)
    emailMessage.Attachments.Add(new Attachment(reportStream, reportName));

  try
  {
      SmtpClient smtp = new SmtpClient(smptServerHostname, smtpServerPort);

      // Send the MailMessage
      smtp.Send(emailMessage);
  }
  catch (SmtpFailedRecipientsException ex)
  {
    // Delivery failed for the recipient. Add the e-mail address to the failedRecipients List
    failedRecipients.Add(ex.FailedRecipient);

    //are you missing a loop here? only one failed address will ever be returned
  }
  catch (SmtpFailedRecipientException ex)
  {
    // Delivery failed for the recipient. Add the e-mail address to the failedRecipients List
    failedRecipients.Add(ex.FailedRecipient);
  }

  // Return the List of failed recipient e-mail addresses, so the client can maintain its list.
  return failedRecipients;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...