Отправка электронной почты из пользовательского расширения доставки служб SQL Server Reporting Services
-
09-06-2019 - |
Вопрос
Я разработал собственное расширение для служб 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, а port - 25.
Я убедился, что действительно могу отправлять почту, используя Telnet.И это работает.
Вот сообщение об ошибке, которое я получаю от SSRS:
ReportingServicesService!уведомление!4!08/28/2008-11:26:17::Уведомление 6ab32b8d-296e-47a2-8d96-09e81222985c завершено.Успех:Ложь, Статус:Сообщение Об исключении:Сбой при отправке почты.Отслеживание стека:в MyDeliveryExtension.MailDelivery.SendMail(данные SubscriptionData, поток reportStream, строка ReportName, строка smptServerHostname, Int32 smtpServerPort) в C:\inetpub\wwwroot\CustomReporting\MyDeliveryExtension\MailDelivery.cs:line 48 в MyDeliveryExtension.MyDelivery.Доставить (уведомление об уведомлении) в C:\inetpub\wwwroot\CustomReporting\MyDeliveryExtension\MyDelivery.cs:line 153, DeliveryExtension:Моя Доставка, Отчет:Разработка кликов, попытка 1 ReportingServicesService!опрос базы данных!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 на Administrator, но по-прежнему без какого-либо успеха.
Я также попытался войти на SMTP-сервер в своем коде, предоставив:NetworkCredential ("Администратор", "пароль"), а также NetworkCredential ("Администратор", "пароль", "MyRepServer")
Кто-нибудь может здесь помочь, пожалуйста?
Решение
Что находится на:
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, достаточно просто выбросить.
Попробуйте эту настройку:
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;
}
Другие советы
Я попытался удалить вложение reportStream:
//if (reportStream != null)
//emailMessage.Attachments.Add(new Attachment(reportStream, reportName));
И теперь это работает нормально.
Так что это как-то связано с потоком отчетов.
Повозившись с настройкой, которая получает reportStream, я смог устранить проблему с отправкой почты.
Ошибка была не в методе SendMail, а где-то еще.Однако исключение было сгенерировано в контексте SendMail.Ублюдок!
Вот почему вы должны избегать:
catch (Exception ex)
{
throw ex;
}
Поскольку это в основном скрывает ваше исключение в новом.
Если вы используете:
catch (Exception ex)
{
throw; //note: no ex
}
Он сохраняет исходное исключение и трассировку стека.
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();