Enviando email de uma extensão de entrega personalizada do SQL Server Reporting Services

StackOverflow https://stackoverflow.com/questions/31930

  •  09-06-2019
  •  | 
  •  

Pergunta

Desenvolvi minha própria extensão de entrega para o Reporting Services 2005, para integrá-la à nossa solução de marketing SaaS.

Ele pega a assinatura e tira um instantâneo do relatório com um conjunto personalizado de parâmetros.Em seguida, ele renderiza o relatório, envia um e-mail com um link e o relatório anexado em XLS.

Tudo funciona bem, até a entrega do correio...

Aqui está o meu código para enviar e-mail:

 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;
}

Os valores para SmtpServerHostname são localhost e a porta é 25.

Verifiquei que posso realmente enviar e-mails usando Telnet.E funciona.

Aqui está a mensagem de erro que recebo do SSRS:

ReportingServicesService!notification!4!08/28/2008-11:26:17::Notificação 6ab32b8d-296e-47a2-8d96-09e81222985c concluída.Sucesso:Falso, Estado:Mensagem de exceção:Falha no envio do e-mail.Rastreamento de pilha:em mydeliveryextension.maildelivery.sendmail (dados de subscriptionData, stream reportStream, string reportName, string smptServerHostName, int32 smtpServerport) em c: inetpub wwwroot alfabeting mydeliversenvienstension maildelivery.cs.cs: linhagem de MyDeliveriVer. Em C: inetpub wwwroot CustomReporting MyDeliveryExtension MyDelivery.cs: Linha 153, DeliveryExtension:Minha entrega, relatório:Cliques em desenvolvimento, tentativa 1 relatórios servicesserve! Dbpolling! 4! 08/28/2008-11: 26: 17 ::NotificaçãoPolling finalizou o processamento do item 6ab32b8d-296e-47a2-8d96-09e81222985c

Isso poderia ter algo a ver com segurança de acesso confiável/código?

Minha extensão de entrega recebe total confiança em 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> 

A confiança poderia ser um problema aqui?

Outra teoria:SQL Server e SSRS foram instalados no contexto de segurança do Sistema Local.Estou certo ou esta conta de serviço tem acesso restrito a qualquer recurso de rede?Até mesmo seu próprio servidor SMTP?

Tentei alterar todos os logons do SQL Server Services para Administrador - mas ainda sem sucesso.

Também tentei fazer login no servidor SMTP em meu código, fornecendo:NetworkCredential("Administrador", "senha") e também NetworkCredential("Administrador", "senha", "MyRepServer")

Alguém pode ajudar aqui, por favor?

Foi útil?

Solução

O que está em:

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

Além disso, você parece estar descartando o fluxo de relatório, mas isso deve ser feito por quem abriu esse fluxo, não pelo seu método (não será óbvio que anexar um fluxo o descarta).

Você está perdendo parte do rastreamento de pilha devido à forma como lança novamente as exceções.Não jogue a variável ex, apenas jogue é o suficiente.

Experimente este ajuste:

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;
}

Outras dicas

Tentei remover o anexo reportStream:

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

E agora funciona bem.

Portanto, tem algo a ver com o reportStream.

Depois de brincar com a funcionalidade que obtém o reportStream, consegui corrigir o problema de envio de e-mail.

O erro não estava no método SendMail, mas em outro lugar.A exceção foi lançada no contexto do SendMail.Arrasado!

É por isso que você deve evitar:

catch (Exception ex)
{
    throw ex;
}

Como isso basicamente esconde sua exceção em uma nova.

Se você usar:

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

Ele mantém a exceção original e o rastreamento de pilha.

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();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top