Envío de correo electrónico desde una extensión de entrega personalizada de SQL Server Reporting Services

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

  •  09-06-2019
  •  | 
  •  

Pregunta

He desarrollado mi propia extensión de entrega para Reporting Services 2005, para integrarla con nuestra solución de marketing SaaS.

Toma la suscripción y toma una instantánea del informe con un conjunto personalizado de parámetros.Luego genera el informe, envía un correo electrónico con un enlace y el informe adjunto como XLS.

Todo funciona bien, hasta la entrega del correo...

Aquí está mi código para enviar correo electrónico:

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

Los valores para SmtpServerHostname son localhost y el puerto es 25.

Verifiqué que realmente puedo enviar correo utilizando Telnet.Y funciona.

Aquí está el mensaje de error que recibo de SSRS:

ReportingServicesService!notificación!4!28/08/2008-11:26:17::Notificación 6ab32b8d-296e-47a2-8d96-09e81222985c completada.Éxito:Falso, Estado:Mensaje de excepción:Error en el envio de correo.Seguimiento de pila:en myDeliveryExtension.MailDelivery.SendMail (Datos de SenscriptionData, Stream ReportStream, String ReportName, String SmPTServerHostName, INT32 SMTPSERVERPORT) en C: inetpub wwwwroot CustomReporting myDeliveryExtension mailDelivere.cs: línea 48 en mydelivery.myDeliveryenge (notification) En C: inetpub wwwroot customReporting myDeliveryExtension myDelivery.cs: línea 153, entregaxtension:Mi Entrega, Informe:¡Desarrollo de clics, intento 1 reportingServiceSservice! Dbpolling! 4! 08/28/2008-11: 26: 17 ::NotificaciónEl sondeo finalizó el procesamiento del elemento 6ab32b8d-296e-47a2-8d96-09e81222985c

¿Podría esto tener algo que ver con la confianza/seguridad de acceso al código?

Mi extensión de entrega tiene plena confianza en 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> 

¿Podría la confianza ser un problema aquí?

Otra teoría:SQL Server y SSRS se instalaron en el contexto de seguridad del sistema local.¿Estoy en lo cierto o esta cuenta de servicio tiene acceso restringido a cualquier recurso de red?¿Incluso su propio servidor SMTP?

Intenté cambiar todos los inicios de sesión de Servicios de SQL Server a Administrador, pero aún sin éxito.

También intenté iniciar sesión en el servidor SMTP en mi código, proporcionando:NetworkCredential("Administrador", "contraseña") y también NetworkCredential("Administrador", "contraseña", "MyRepServer")

¿Alguien puede ayudar aquí, por favor?

¿Fue útil?

Solución

¿Qué hay en:

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

También parece que está desechando la secuencia de informes, pero eso debe hacerlo cualquier persona que haya abierto esa secuencia, no su método (no será obvio que adjuntar una secuencia la elimine).

Estás perdiendo parte del seguimiento de tu pila debido a la forma en que vuelves a generar excepciones.No arrojes la variable ex, simplemente tirarla es suficiente.

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

Otros consejos

Intenté eliminar el archivo adjunto reportStream:

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

Y ahora funciona bien.

Entonces tiene algo que ver con reportStream.

Después de jugar con la funcionalidad que obtiene reportStream, pude solucionar el problema de envío de correo.

El error no estaba en el método SendMail, sino en otro lugar.Sin embargo, la excepción se produjo en el contexto de SendMail.¡Jodido!

Por eso hay que evitar:

catch (Exception ex)
{
    throw ex;
}

Ya que eso básicamente encubre su excepción con una nueva.

Si utiliza:

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

Mantiene la excepción original y el seguimiento de la pila.

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top