从自定义SQL Server Reporting Services传递扩展发送电子邮件
我已经为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!通知!4!08/28 / 2008-11:26:17 ::通知6ab32b8d-296e-47a2-8d96-09e81222985c已完成。成功:错误,状态:异常消息:发送邮件失败。 Stacktrace:位于C:\ inetpub \ wwwroot \ CustomReporting \ MyDeliveryExtension \ MailDelivery.cs:line 48中的MyDeliveryExtension.MailDelivery.SendMail(SubscriptionData数据,Stream reportStream,String reportName,String smptServerHostname,Int32 smtpServerPort)
在C:\ inetpub \ wwwroot \ CustomReporting \ MyDeliveryExtension \ MyDelivery.cs:line 153中的MyDeliveryExtension.MyDelivery.Deliver(通知通知):行153,DeliveryExtension:我的交付,报告:单击开发,尝试1
ReportingServicesService!dbpolling!4!08/28 / 2008-11:26:17 :: NotificationPolling完成处理项目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 Services登录更改为Administrator,但仍然没有成功。
我还尝试通过提供以下代码来登录我的代码中的SMTP服务器:NetworkCredential(" Administrator"," password")以及NetworkCredential(" Administrator"," password"," 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有关。
回答
弄乱了获取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();