Senden von E-Mails von einer benutzerdefinierten SQL Server Reporting Services-Bereitstellungserweiterung

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

  •  09-06-2019
  •  | 
  •  

Frage

Ich habe meine eigene Bereitstellungserweiterung für Reporting Services 2005 entwickelt, um diese in unsere SaaS-Marketinglösung zu integrieren.

Es nimmt das Abonnement entgegen und erstellt einen Snapshot des Berichts mit einem benutzerdefinierten Parametersatz.Anschließend wird der Bericht gerendert, eine E-Mail mit einem Link gesendet und der Bericht als XLS-Datei angehängt.

Alles funktioniert einwandfrei, bis zur Postzustellung...

Hier ist mein Code zum Versenden von E-Mails:

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

Die Werte für „SmtpServerHostname“ sind „localhost“ und „Port“ ist 25.

Ich habe bestätigt, dass ich mit Telnet tatsächlich E-Mails versenden kann.Und es funktioniert.

Hier ist die Fehlermeldung, die ich von SSRS erhalte:

ReportingServicesService!notification!4!28.08.2008-11:26:17::Benachrichtigung 6ab32b8d-296e-47a2-8d96-09e81222985c abgeschlossen.Erfolg:Falsch, Status:Ausnahmemeldung:Fehler beim Senden der E-Mail.Stacktrace:bei mydeliveryextension Benachrichtigungsbenachrichtigung) In C: inetpub wwwroot CustomReporting MyDeliveryextsion MyDelivery.cs: Zeile 153, Lieferung: Lieferung:Meine Lieferung, Bericht:Klicksentwicklung, Versuch 1 ReportingServicesservice! DBPOLLING! 4! 08/28/2008-11: 26: 17::Benachrichtigung: Polling hat die Verarbeitung von Element 6ab32b8d-296e-47a2-8d96-09e81222985c abgeschlossen

Könnte das etwas mit Trust/Code Access Security zu tun haben?

Meiner Übermittlungserweiterung wird volles Vertrauen in rssrvpolicy.config gewährt:

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

Könnte Vertrauen hier ein Problem sein?

Eine andere Theorie:SQL Server und SSRS wurden im Sicherheitskontext des lokalen Systems installiert.Habe ich recht, oder ist der Zugriff dieses Dienstkontos auf Netzwerkressourcen eingeschränkt?Sogar ein eigener SMTP-Server?

Ich habe versucht, alle SQL Server Services-Anmeldungen auf Administrator zu ändern – aber immer noch ohne Erfolg.

Ich habe auch versucht, mich in meinem Code beim SMTP-Server anzumelden, indem ich Folgendes angegeben habe:NetworkCredential("Administrator", "Password") und auch NetworkCredential("Administrator", "Password", "MyRepServer")

Kann hier bitte jemand helfen?

War es hilfreich?

Lösung

Was gibt es hier:

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

Außerdem scheinen Sie den Berichtsstream zu entsorgen, aber das sollte von demjenigen erledigt werden, der diesen Stream geöffnet hat, nicht von Ihrer Methode (es ist nicht offensichtlich, dass das Anhängen eines Streams ihn entsorgt).

Sie verlieren einen Teil Ihres Stack-Trace aufgrund der Art und Weise, wie Sie Ausnahmen erneut auslösen.Werfen Sie die Ex-Variable nicht aus, werfen Sie einfach.

Probieren Sie diese Optimierung aus:

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

Andere Tipps

Ich habe versucht, den ReportStream-Anhang zu entfernen:

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

Und jetzt funktioniert es gut.

Es hat also etwas mit dem reportStream zu tun.

Nachdem ich mit der Tunctionallity herumgespielt hatte, die den ReportStream abruft, konnte ich das Problem beim E-Mail-Versand beheben.

Der Fehler lag nicht in der SendMail-Methode, sondern woanders.Die Ausnahme wurde jedoch im Kontext von SendMail ausgelöst.Verarscht!

Deshalb müssen Sie Folgendes vermeiden:

catch (Exception ex)
{
    throw ex;
}

Denn das hüllt Ihre Ausnahme im Grunde in eine neue.

Wenn du benutzt:

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

Es behält die ursprüngliche Ausnahme und den Stack-Trace bei.

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();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top