After migration from CRM 4 to CRM 2011 my plugin written for custom email with PDF report won't work anymore so i rebuild my previous solution from CRM 4 with necessary changes for new CRM 2011:
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 SendReport.ReportService;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Sdk.Query;
namespace SendReport
{
public class SendReport : CodeActivity
{
protected override void Execute(CodeActivityContext executionContext)
{
try
{
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
Guid incidentId = context.PrimaryEntityId;
byte[] result = null;
ReportService.ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
rs.Url = "http://crmserver/ReportServer/ReportExecution2005.asmx";
string reportPath = "/Reports/reportname";
string format = "PDF";
string historyID = null;
string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
ParameterValue[] parameters = new ParameterValue[1];
parameters[0] = new ParameterValue();
parameters[0].Name = "incidentid";
parameters[0].Value = incidentId.ToString();
DataSourceCredentials[] credentials = null;
string showHideToggle = null;
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
ParameterValue[] reportHistoryParameters = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, historyID);
rs.SetExecutionParameters(parameters, "en-us");
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
try
{
result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out
streamIDs);
}
catch (Exception err)
{
throw new Exception(err.Message.ToString());
}
Entity email = new Entity();
email.LogicalName = "email";
EntityReference regardingObject = new EntityReference("incident", incidentId);
email.Attributes.Add("regardingobjectid", regardingObject);
Guid senderUserId = Sender.Get<EntityReference>(executionContext).Id;
Guid recieverUserId = Recipient.Get<EntityReference>(executionContext).Id;
Guid recieverCCUserId = RecipientCC.Get<EntityReference>(executionContext).Id;
EntityReference from = new EntityReference("systemuser", senderUserId);
EntityReference to = new EntityReference("contact", recieverUserId);
EntityReference cc = new EntityReference("contact", recieverCCUserId);
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";
collFromParty.Entities.Add(fromParty);
EntityCollection collToParty = new EntityCollection();
collToParty.EntityName = "systemuser";
collToParty.Entities.Add(toParty);
EntityCollection collccParty = new EntityCollection();
collccParty.EntityName = "systemuser";
collccParty.Entities.Add(ccParty);
var entity = service.Retrieve("incident", incidentId, new ColumnSet(new[] { "ticketnumber", "customerid", "title"}));
var ticket = entity.GetAttributeValue<string>("ticketnumber");
var customer = entity.GetAttributeValue<EntityReference>("customerid");
var customername = customer.Name;
var title = entity.GetAttributeValue<string>("title");
email.Attributes.Add("from", collFromParty);
email.Attributes.Add("to", collToParty);
email.Attributes.Add("cc", collccParty);
email.Attributes.Add("subject", "Here goes subject message.. : " + ticket);
email.Attributes.Add("description", "Here goes description text..");
Guid emailID = service.Create(email);
// Attaching Pdf report
CrmNumber crmNextActorID = new CrmNumber();
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", new CrmNumber(Convert.ToInt32(result.Length.ToString())));
attachment.Attributes.Add("mimetype", "text/plain");
attachment.Attributes.Add("attachmentnumber", crmNextActorID.Value);
attachment.Attributes.Add("objectid", new EntityReference("email", new Guid(email.Id.ToString())));
attachment.Attributes.Add("objecttypecode", objecttypecode);
service.Create(attachment);
SendEmailRequest reqSendEmail = new SendEmailRequest();
reqSendEmail.EmailId = emailID;
reqSendEmail.TrackingToken = "";
reqSendEmail.IssueSend = true;
SendEmailResponse res = (SendEmailResponse)service.Execute(reqSendEmail);
}
catch (Exception err)
{
throw new Exception(err.ToString());
}
}
[RequiredArgument]
[Input("Sender input")]
[ReferenceTarget("systemuser")]
public InArgument<EntityReference> Sender { get; set; }
[RequiredArgument]
[Input("Recipient input")]
[ReferenceTarget("contact")]
public InArgument<EntityReference> Recipient { get; set; }
[RequiredArgument]
[Input("RecipientCC input")]
[ReferenceTarget("contact")]
public InArgument<EntityReference> RecipientCC { get; set; }
}
}
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Crm.Sdk.Messages;
using SendReport.ReportService;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Sdk.Query;
namespace SendReport
{
public class SendReport : CodeActivity
{
protected override void Execute(CodeActivityContext executionContext)
{
try
{
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
Guid incidentId = context.PrimaryEntityId;
byte[] result = null;
ReportService.ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
rs.Url = "http://crmserver/ReportServer/ReportExecution2005.asmx";
string reportPath = "/Reports/reportname";
string format = "PDF";
string historyID = null;
string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
ParameterValue[] parameters = new ParameterValue[1];
parameters[0] = new ParameterValue();
parameters[0].Name = "incidentid";
parameters[0].Value = incidentId.ToString();
DataSourceCredentials[] credentials = null;
string showHideToggle = null;
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
ParameterValue[] reportHistoryParameters = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, historyID);
rs.SetExecutionParameters(parameters, "en-us");
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
try
{
result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out
streamIDs);
}
catch (Exception err)
{
throw new Exception(err.Message.ToString());
}
Entity email = new Entity();
email.LogicalName = "email";
EntityReference regardingObject = new EntityReference("incident", incidentId);
email.Attributes.Add("regardingobjectid", regardingObject);
Guid senderUserId = Sender.Get<EntityReference>(executionContext).Id;
Guid recieverUserId = Recipient.Get<EntityReference>(executionContext).Id;
Guid recieverCCUserId = RecipientCC.Get<EntityReference>(executionContext).Id;
EntityReference from = new EntityReference("systemuser", senderUserId);
EntityReference to = new EntityReference("contact", recieverUserId);
EntityReference cc = new EntityReference("contact", recieverCCUserId);
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";
collFromParty.Entities.Add(fromParty);
EntityCollection collToParty = new EntityCollection();
collToParty.EntityName = "systemuser";
collToParty.Entities.Add(toParty);
EntityCollection collccParty = new EntityCollection();
collccParty.EntityName = "systemuser";
collccParty.Entities.Add(ccParty);
var entity = service.Retrieve("incident", incidentId, new ColumnSet(new[] { "ticketnumber", "customerid", "title"}));
var ticket = entity.GetAttributeValue<string>("ticketnumber");
var customer = entity.GetAttributeValue<EntityReference>("customerid");
var customername = customer.Name;
var title = entity.GetAttributeValue<string>("title");
email.Attributes.Add("from", collFromParty);
email.Attributes.Add("to", collToParty);
email.Attributes.Add("cc", collccParty);
email.Attributes.Add("subject", "Here goes subject message.. : " + ticket);
email.Attributes.Add("description", "Here goes description text..");
Guid emailID = service.Create(email);
// Attaching Pdf report
CrmNumber crmNextActorID = new CrmNumber();
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", new CrmNumber(Convert.ToInt32(result.Length.ToString())));
attachment.Attributes.Add("mimetype", "text/plain");
attachment.Attributes.Add("attachmentnumber", crmNextActorID.Value);
attachment.Attributes.Add("objectid", new EntityReference("email", new Guid(email.Id.ToString())));
attachment.Attributes.Add("objecttypecode", objecttypecode);
service.Create(attachment);
SendEmailRequest reqSendEmail = new SendEmailRequest();
reqSendEmail.EmailId = emailID;
reqSendEmail.TrackingToken = "";
reqSendEmail.IssueSend = true;
SendEmailResponse res = (SendEmailResponse)service.Execute(reqSendEmail);
}
catch (Exception err)
{
throw new Exception(err.ToString());
}
}
[RequiredArgument]
[Input("Sender input")]
[ReferenceTarget("systemuser")]
public InArgument<EntityReference> Sender { get; set; }
[RequiredArgument]
[Input("Recipient input")]
[ReferenceTarget("contact")]
public InArgument<EntityReference> Recipient { get; set; }
[RequiredArgument]
[Input("RecipientCC input")]
[ReferenceTarget("contact")]
public InArgument<EntityReference> RecipientCC { get; set; }
}
}
Thanks a lot for such a great post on CRM 2011 Custom Email with Pdf report attachment. This is very helpful for a newbie like me.
ReplyDeletewhere is the ReportService namespace?
ReplyDeleteSendReport.ReportService;
DeleteReportService is web refernce
which link is to connect to web reference
DeleteThanks for wonderfulpost. Is there anyway i can avoid hard coded password for rs.Credentials
ReplyDeleteI tried default and it is not working.
I want the CRM user password username and credentials to be passed and able to run report.
Hello, how to do to connect my report in reporting services and send email with pdf result?
ReplyDeleteHi Veronica, if I understand you correctly you have to upload your report rdl file to report server and then set path to it in your solution like in my example string reportPath = "/Reports/reportname";
DeleteHi,
ReplyDeletei tried your code with our crm but i am experiencing problems when setting the parameters.
without performing the
rs.SetExecutionParameters(parameters, "en-us");
the report is working. but when i want to set it the following error occurs:
Workflow paused due to error: Unhandled Exception: System.Xml.XmlException: There are multiple root elements. Line 1, position 98.
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
at System.Xml.XmlDocument.Load(XmlReader reader)
at Microsoft.Crm.SharedUtil.CreateXmlDocument(String xml)
at Microsoft.Crm.CrmException.ExtractPluginTraceFromSoapException(SoapException exception)
at Microsoft.Crm.CrmException.ConvertPluginException(Exception originalException, Boolean isAsync, Boolean unwrapTargetInvocationException)
at Microsoft.Crm.Workflow.ActivityHostBase.AddPluginTrace(Activity customActivity, Exception exception, ICommonWorkflowContext context)
at Microsoft.Crm.Workflow.ActivityHostBase.OnWorkflowTerminated(WorkflowApplicationUnhandledExceptionEventArgs args, WorkflowApplication activityInstance, ICommonWorkflowContext context)
at System.Activities.WorkflowApplication.UnhandledExceptionEventHandler.OnStage1Complete(IAsyncResult lastResult, WorkflowApplication instance, Exception exception, Activity source, String sourceInstanceId)
at System.Activities.WorkflowApplication.UnhandledExceptionEventHandler.Run(WorkflowApplication instance, Exception exception, Activity exceptionSource, String exceptionSourceInstanceId)
at System.Activities.WorkflowApplication.OnNotifyUnhandledException(Exception exception, Activity exceptionSource, String exceptionSourceInstanceId)
do you have any idea where the problem is??
thanks
Fabian
Hi Fabian! I think you have to check the lines where report parameters are set
DeleteHi,
ReplyDeleteWould this work for CRM online?
Hi, Paul
DeleteI hope that it's already possible to do this in CRM online if they released Q2 Service Update or in Q4 ??
http://gustafwesterlund.blogspot.com/2012/04/workflow-activities-in-crm-online.html
Thank you for this post. It is really helpful. I am trying out your code, but getting the following.
ReplyDeleteThe type or namespace name 'CrmNumber' could not be found (are you missing a using directive or an assembly reference?)
I am referencing microsoft.crm.sdk.proxy. Not sure why i am getting the error. Any ideas?
Have you find a resolution to this err? :/
Deletereplace crmnumber with int
Deletestill error. already replace it with int. now the error is "'int' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'int' could be found "
DeleteCan someone provide the updated code? i cannot get it to work?
ReplyDeleteare we using a Service Reference or Web Reference
use Web Reference like this http://your server name/ReportServer/ReportExecution2005.asmx
DeleteDoes this work for CRM 2011 online now?
ReplyDeletehi,
ReplyDeletecould you tell me how can I use it in crm 2011?I'm new at crm
For Online 2015 how to add web reference as ReportService???
ReplyDeletePLease help me
ReplyDelete@jeeva:
ReplyDeletedid u find solution?
This was so helpful. Thanks for posting!
ReplyDeleteusing SendReport.ReportService;
ReplyDeletewhere do we find this
SendReport in this example is namespace name (there will be yours) and ReportService is name of web refference which you have to add in your project (also give your name) ashttp://crmserver/ReportServer/ReportExecution2005.asmx
Deleteby adding the webreference it is showing this error
DeleteValue cannot be null.
Parameter name: discoveryError & mexError
send me please screenshot of your project, i need to see this error message
Deletek.o.n.c.i.s@inbox.lv