Я разработал собственное расширение доставки для 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:
ReportingServicesService! Notification! 4! 28.08.2008-11: 26: 17 :: Уведомление 6ab32b8d-296e-47a2-8d96-09e81222985c завершено. Успех: Ложь, Статус: Сообщение об исключении: Ошибка отправки почты. Stacktrace: в MyDeliveryExtension.MailDelivery.SendMail (данные SubscriptionData, Stream reportStream, String reportName, String smptServerHostname, Int32 smtpServerPort) в C: \ inetpub \ wwwroot \ CustomReporting \ MyDeliveryExtension \ MailDelivery.cs: строка 48 в MyDeliveryExtension.MyDelivery.Deliver (уведомление об уведомлении) в C: \ inetpub \ wwwroot \ CustomReporting \ MyDeliveryExtension \ MyDelivery.cs: строка 153, DeliveryExtension: Моя доставка, Отчет: Разработка кликов, Попытка 1 ReportingServicesService! Dbpolling! 4! 28.08.2008-11: 26: 17 :: NotificationPolling завершил обработку элемента 6ab32b8d-296e-47a2-8d96-09e81222985c
Может ли это иметь какое-то отношение к Trust / Code Access Security?
Моему расширению доставки предоставлено полное доверие к 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»).
Кто-нибудь может здесь помочь, пожалуйста?





Что на:
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;
}
Я попытался удалить вложение reportStream:
//if (reportStream != null)
//emailMessage.Attachments.Add(new Attachment(reportStream, reportName));
И теперь работает нормально.
Так что это как-то связано с reportStream.
После того, как я пошутил с настройкой, которая получает 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();