إرسال بريد إلكتروني من ملحق تسليم خدمات تقارير SQL Server المخصص

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

  •  09-06-2019
  •  | 
  •  

سؤال

لقد قمت بتطوير ملحق التسليم الخاص بي لـ 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 هي المضيف المحلي، والمنفذ هو 25.

لقد شعرت جدًا أنه يمكنني بالفعل إرسال البريد باستخدام Telnet.ويعمل.

إليك رسالة الخطأ التي أتلقاها من SSRS:

ReportingServicesService!notification!4!08/28/2008-11:26:17::اكتمل الإشعار 6ab32b8d-296e-47a2-8d96-09e81222985c.نجاح:غير صحيح، الحالة:رسالة الاستثناء:فشل في إرسال البريد.تتبع المكدس:في myDeliveryextension.maildelivery.sendmail (بيانات الاشتراك ، دفق تقرير ، تقرير السلسلة ، سلسلة smptserverhostname ، int32 smtpserverport) في c: inetpub wwwroot في c: inetpub wwwroot customReporting myDelivery extense mydelivery.cs: السطر 153 ، التسليم:التسليم الخاص بي، التقرير:نقرات التنمية ، محاولة 1 تقارير reporteserviceStervice! dbpolling! 4! 08/28/2008-11: 26: 17 ::إشعار انتهاء معالجة عنصر الاقتراع 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 إلى المسؤول - ولكن دون أي نجاح.

لقد حاولت أيضًا تسجيل الدخول إلى خادم 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

يبدو أيضًا أنك تتخلص من دفق التقرير، ولكن يجب أن يتم ذلك عن طريق أي شيء فتح هذا الدفق، وليس طريقتك (لن يكون من الواضح أن إرفاق دفق يتخلص منه).

أنت تفقد جزءًا من تتبع المكدس الخاص بك بسبب كيفية إعادة طرح الاستثناءات.لا ترمي المتغير السابق، فقط رمي يكفي.

جرب هذا التعديل:

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

نصائح أخرى

حاولت إزالة مرفق التقرير:

  //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();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top