In visual studio 2008, asp.net / vb.net, I want to be able to generate an mhtml Report Server report, then read it into the body of an email message, and send the email.

I know how to initiate the report, and how to generate/send the email message.

What I'm confused about, is how to 1) retrieve the report, and 2) load the report into an email "body variable."

The report is returned as a link.

An example would be great.

Thanks,
Randy

Dani AI

Generated

Short answer: render the SSRS report with the server execution API, build an HTML AlternateView (not a raw MHTML blob) and add any report resource streams (images) as LinkedResource items on that view, then send with System.Net.Mail. This follows the direction suggested (use the report web service) and avoids the legacy CDO approach that mentioned (CDO still works for classic ASP but is not ideal inside ASP.NET). (learn.microsoft.com)

Suggested workflow (high level)

  • Call the SSRS execution web service and Render the report as HTML (or MHTML if you must). The Render call returns the main output plus a list of stream IDs for secondary streams (images, charts). For each stream ID call RenderStream to get the binary for that image. (learn.microsoft.com)
  • Create an HTML AlternateView from the rendered HTML string and add each image as a LinkedResource (set each LinkedResource.ContentId and update the HTML <img src="..."> references to use cid:contentid). Add the AlternateView to MailMessage.AlternateViews and send via SmtpClient. System.Net.Mail supports AlternateView/LinkedResource for inline images. (learn.microsoft.com)

Minimal VB.NET sketch (focuses on the mail-side; assume htmlString and imageBytes were obtained from Render/RenderStream)

Dim av = AlternateView.CreateAlternateViewFromString(htmlString, New System.Net.Mime.ContentType("text/html"))
Dim img As New System.Net.Mail.LinkedResource(New IO.MemoryStream(imageBytes), "image/png")
img.ContentId = "img1"
av.LinkedResources.Add(img)
Dim mail As New System.Net.Mail.MailMessage(from, [to], subject, "")
mail.AlternateViews.Add(av)
mail.IsBodyHtml = True
Dim smtp As New System.Net.Mail.SmtpClient(smtpHost)
smtp.Send(mail)

Notes, pitfalls and troubleshooting

  • MHTML is a multipart MIME document (RFC 2557). Dropping an entire MHTML blob straight into MailMessage.Body often yields base64/mime junk in the recipient because MHTML contains MIME headers and boundaries; you either need to extract the HTML part or build a proper multipart message (or use AlternateView + LinkedResources). (datatracker.ietf.org)
  • Pay attention to the encoding string returned by Render and set BodyEncoding/AlternateView content type accordingly. If renders are long, you may need to increase SSRS client timeouts. (learn.microsoft.com)

These steps give a robust, server-side way (no COM/CDO) to put a rendered SSRS report into the actual HTML body of an email that Outlook and other clients can display.

Recommended Answers

All 7 Replies

Hi,
You can do it using CDO.Message
You can generate the report in a seperate file and call the file in CreateMHTMLBody() method.

Here is an example

CDO.Message msg=new CDO.Message()
msg.to= toaddress
msg.cc=
msg.from= fromaddress
msg.subject= msg.CreateMHTMLBody(reportpageurl,CDO.CdoMHTMLFlags.cdoSuppressNone,"","");
msg.send()

Use the ReportingService Class which contains the methods and properties that can be used to call the Reporting Services Web service.

Using the Render method, you can generate the report as mhtml content.

Assign this mhtml content in the Body of a MailMessage class in asp.net. You need to set IsBodyHtml property to true. Also send it as an e-mail using SmtpClient class.

Praveenkumarm,
This looks good.... but how do I dim the msg variable in vb?
There is no "cdo.message" object type available, so I can't instantiate it.
Do I need to include additional libraries?

Thanks,
Randy

I added the CDO service.
the following is the code...

Dim myMail As New CDO.Message
			myMail = CreateObject("CDO.Message") '[is this necessary?]
			myMail.Subject = subject
			myMail.From = EmailFrom
			myMail.To = EmailTo
			myMail.CreateMHTMLBody("http://xxx.xxx.xxx.xxx/ReportServer?/AdHocReports/WelcomeLetter&rs:Command=Render&rs:Format=MHTML&LeadID=45250", CDO.CdoMHTMLFlags.cdoSuppressNone, "", "")
			myMail.Send()
			myMail = Nothing

I am getting the following CDO error...
------
The content type was not valid in this context. For example, the root of an MHTML message must be an HTML document.

stack trace...
CDO.IMessage.CreateMHTMLBody(String URL, CdoMHTMLFlags Flags, String UserName, String Password) +0

Yes you need to iport a namespace

imports CDO

dim msg as new CDO.Message()

All The Best

Yes you need to iport a namespace

But CDO object model is used to send mails from classic ASP application which is obsolete in ASP.NET.

Microsoft recommends to use System.Net.Mail namespace and related classes to send mail.

How would the code change with the System.Net.Mail namespace?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.