Custom WorkFlow to Send Email with PDF formatted Report as Attachment

20 Nov


In some cases, we have to send Email to customers with a Report in Pdf format as an attachment.


Once I had the same requirement. To do this, we have to follow three steps.

  1. First to retrieve the Report,
  2. Second to convert the Report to Pdf format and
  3. Last to send an Email with the Pdf as attachment.


To achieve this, I have written a Custom Workflow.
Here is the code snippet to get it done. This code is for CRM OnPremise only. I have not tried in CRM Online.

using System;
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Crm.Sdk.Messages;
using CustomWorkflows.ReportService; //Have to add the Reporting Service as Web Reference

namespace SendReport
    public class SendReport : CodeActivity
        protected override void Execute(CodeActivityContext executionContext)
                IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
                IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

                Guid accountId = context.PrimaryEntityId;
                byte[] result = null;

                CustomWorkflows.ReportService.ReportExecutionService rs = new ReportExecutionService();

                // Credential to connect with CRM
                rs.Credentials = new System.Net.NetworkCredential(username, password, domain);

                // Setting the URL of the Reporting Server
                rs.Url = "http://test10:80/ReportServer/ReportExecution2005.asmx";

                string reportPath = "/Test_MSCRM/TestReport";
                // Specify the report path from the reporting server
                // Note: To get the report name, report must be published for the external use.
                // To do this edit the report from CRM and publish it for external use.
                // After publishing it for external use report name will be visible in the reporting server instead of the report id.

                string format = "PDF";
                string historyID = null;
                string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
                string encoding;
                string mimeType;
                string extension;
                Warning[] warnings = null;
                string[] streamIDs = null;

                ExecutionInfo execInfo = new ExecutionInfo();
                ExecutionHeader execHeader = new ExecutionHeader();
                rs.ExecutionHeaderValue = execHeader;
                execInfo = rs.LoadReport(reportPath, historyID);

                String SessionId = rs.ExecutionHeaderValue.ExecutionID;

                result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);

                //Create email activity
                Entity email = new Entity();
                email.LogicalName = "email";
                email.Attributes.Add("regardingobjectid", new EntityReference("account", accountId);

                //Creating EntityReference for from, to and cc. Need to be changed according to your requirement
                EntityReference from = new EntityReference("systemuser", senderUserId);
                EntityReference to = new EntityReference("contact", recieverUserId);
                EntityReference cc = new EntityReference("contact", recieverCCUserId);

                //Creating party list
                Entity fromParty = new Entity("activityparty");
                fromParty.Attributes.Add("partyid", from);
                Entity toParty = new Entity("activityparty");
                toParty.Attributes.Add("partyid", to);
                Entity ccParty = new Entity("activityparty");
                ccParty.Attributes.Add("partyid", cc);

                EntityCollection collFromParty = new EntityCollection();
                collFromParty.EntityName = "systemuser";

                EntityCollection collToParty = new EntityCollection();
                collToParty.EntityName = "contact";

                EntityCollection collccParty = new EntityCollection();
                collccParty.EntityName = "contact";

                // Adding from, to and cc to the email
                email.Attributes.Add("from", collFromParty);
                email.Attributes.Add("to", collToParty);
                email.Attributes.Add("cc", collccParty);

                email.Attributes.Add("subject", "Here goes subject message.. : ");
                email.Attributes.Add("description", "Here goes description text..");
                Guid emailID = service.Create(email); // Create the email

                // Attaching Pdf Report
                int NextActorID = new int();
                RetrieveEntityRequest request = new RetrieveEntityRequest();
                request.LogicalName = "email";
                RetrieveEntityResponse response = (RetrieveEntityResponse)service.Execute(request);
                int objecttypecode = response.EntityMetadata.ObjectTypeCode.Value;

                Entity attachment = new Entity("activitymimeattachment");
                attachment.Attributes.Add("subject", "Report");
                attachment.Attributes.Add("filename", "Report.pdf");
                attachment.Attributes.Add("body", Convert.ToBase64String(result));
                attachment.Attributes.Add("filesize", Convert.ToInt32(result.Length.ToString()));
                attachment.Attributes.Add("mimetype", "text/plain");
                attachment.Attributes.Add("attachmentnumber", NextActorID);
                attachment.Attributes.Add("objectid", new EntityReference("email", new Guid(email.Id.ToString())));
                attachment.Attributes.Add("objecttypecode", objecttypecode);
                service.Create(attachment); //Create the attachment

                // Sending email
                SendEmailRequest reqSendEmail = new SendEmailRequest();
                reqSendEmail.EmailId = emailID;
                reqSendEmail.TrackingToken = "";
                reqSendEmail.IssueSend = true;
                SendEmailResponse res = (SendEmailResponse)service.Execute(reqSendEmail);
            catch (Exception err)
                // Throw error message

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions


Posted by on November 20, 2013 in CRM WorkFlow


Tags: , , , , , , , , , , , , , , , ,

9 responses to “Custom WorkFlow to Send Email with PDF formatted Report as Attachment

  1. arahman1970

    December 4, 2013 at 12:16 am

    hi. Does this work in CRM 2013 online ?

    • arahman1970

      December 4, 2013 at 12:17 am

      Also, can it be scheduled as well ?

      • DynamicsCRM@MindfireSolutions

        December 4, 2013 at 10:41 am

        Hi arahman1970,

        Generally, Custom Workflow is triggered with the help of a System Workflow.
        We can schedule the System Workflow containing this Custom Workflow according to our conditions and requirements.

        Thanks for commenting and asking question. Hope you liked the Blog. 🙂


    • DynamicsCRM@MindfireSolutions

      December 4, 2013 at 10:37 am

      Hi arahman1970,

      Thanks for taking time to read our Blog. 🙂

      Actually we have not tried this in CRM 2013 online.
      If possible, please try this in online CRM and let us know your views.


  2. Ivan

    December 13, 2013 at 1:49 pm


    I was trying to implement your solution as Custom Workflow Step. After many tryes still cant find ReportExecutionService. I tryed to add web resource like:
    http://server/ReportServer/ReportExecution2005.asmx or http://server/ReportServer/ReportExecution2010.asmx, and still cant find anywhere this class. Also tryed to find some Microsoft example of it, but still noting. What reporte server reference did you used? How to find this reportExecutor class.

    Many tnx,

  3. Simon Jackson

    December 30, 2013 at 12:02 am

    I’ve used this technique for a few years now, every time the report changes we need to Publish report for External Use again.

    I want to do this programatically via the sdk wcf web services, but I cant find an
    Microsoft.Crm.Sdk.Messages to achieve this.

    Do you know of a Microsoft.Crm.Sdk.Message?

    • DynamicsCRM@MindfireSolutions

      January 13, 2014 at 10:30 am

      Hi Simon Jackson,

      Thanks for reading our Blog. 🙂

      Sorry, we have not come across any such Sdk Message to publish the report for External use programatically. We will surely let you know if we come across it.


  4. Muhammad Sohail

    May 29, 2014 at 2:40 pm

    In the Code you uesd the
    EntityReference from = new EntityReference(“systemuser”, senderUserId); EntityReference to = new EntityReference(“contact”, recieverUserId);
    EntityReference cc = new EntityReference(“contact”, recieverCCUserId);

    here you used the senderUserId,recieverUserId,recieverCCUserid
    but not used the Input Paramter for workflow is this we also add or it has no need of worklfow
    input paramter as
    [Input(“Sender input”)]
    public InArgument senderUserId { get; set; }


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: