Answered by:
help understanding pluging and what is possible

Question
-
CRM 2011 on premisis & SQL2008R2
We currently import about 100 xml files from a third party into our CRM system on a daily basis into a custom entity. I have written a SSRS report that currently is manually executed for each new entry and the report is saved as a PDF and emailed out to our customers. I have been trying to write a plugin that would auto create the PDF files, but can not get it to work.
When a record is imported into the entity, I have a process that extracts parts of the data and creates a record in a monitoring entity
Question.
1. If a plugin is registered on 'create', will it be fired if the entity record is imported?
2. does anyone know of a step by step tutorial that i can follow.
The code below for my attempt at a plugin, causes the import to fail. The report is a simple report for testing and does not take any parameters ( well i need to walk before I run ) . Any help or suggestions would be appreciated
attempt at plugin
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Text Imports System.IO Imports System.Web Imports System.Web.Services Imports System.Xml Imports System.Xml.Serialization Imports Crm2011_Plugins.ReportingService Imports System.Web.Services.Protocols Imports System.Diagnostics Imports Microsoft.Xrm.Sdk Namespace ARUDDPDFGenerator Public Class pluginAruddReports Implements IPlugin Public Sub Execute(serviceProvider As System.IServiceProvider) Implements Microsoft.Xrm.Sdk.IPlugin.Execute Dim context As IPluginExecutionContext = DirectCast(serviceProvider.GetService(GetType(IPluginExecutionContext)), IPluginExecutionContext) If context.InputParameters.Contains("Target") AndAlso TypeOf context.InputParameters("Target") Is Entity Then Dim entity As Entity = DirectCast(context.InputParameters("Target"), Entity) 'new_licence() 'new_addacsreportsid() ' 290c9065-5742-e311-8565-00155d01d303} Dim rs As New ReportExecutionService() rs.Credentials = System.Net.CredentialCache.DefaultCredentials rs.Url = "http://xxxxxxxxx/reportserver/ReportExecution2005.asmx" ' Render arguments Dim result As Byte() = Nothing Dim reportPath As String = "/xxxxCRM_MSCRM/{290c9065-5742-e311-8565-00155d01d303}" Dim format As String = "PDF" Dim historyID As String = Nothing Dim devInfo As String = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>" ' Prepare report parameter. 'Dim parameters(2) As ParameterValue 'parameters(0) = New ParameterValue() 'parameters(0).Name = "EmpID" 'parameters(0).Value = "288" 'parameters(1) = New ParameterValue() 'parameters(1).Name = "ReportMonth" 'parameters(1).Value = "6" ' June 'parameters(2) = New ParameterValue() 'parameters(2).Name = "ReportYear" 'parameters(2).Value = "2004" Dim credentials As DataSourceCredentials() = Nothing Dim showHideToggle As String = Nothing Dim encoding As String = "" Dim mimeType As String = "" Dim warnings As Warning() = Nothing Dim reportHistoryParameters As ParameterValue() = Nothing Dim streamIDs As String() = Nothing Dim execInfo As New ExecutionInfo Dim execHeader As New ExecutionHeader() ' Dim SessionId As String Dim extension As String = "" rs.ExecutionHeaderValue = execHeader execInfo = rs.LoadReport(reportPath, historyID) Try result = rs.Render(format, devInfo, extension, _ encoding, mimeType, warnings, streamIDs) execInfo = rs.GetExecutionInfo() Catch e As SoapException Throw New InvalidPluginExecutionException("Error generating ARUDD Report - " & e.Message.ToString) End Try ' Write the contents of the report to an MHTML file. Try Dim stream As FileStream = File.Create("C:\REPORT TEST IGNORE\report.PDF", result.Length) stream.Write(result, 0, result.Length) stream.Close() Catch e As Exception Throw New InvalidPluginExecutionException("Error generating ARUDD Report - " & e.Message.ToString) End Try End If End Sub End Class End Namespace
Dont ask me .. i dont know
Tuesday, November 12, 2013 12:32 AM
Answers
-
HI,
I have tried following those two links but am getting nowhere
Plugin code
Imports System Imports System.Diagnostics Imports System.Linq Imports Microsoft.Xrm.Sdk Imports Microsoft.Xrm.Client Imports CRM2011Plugins.SSRSReportConnection Imports System.Net Imports System.IO Imports System.ServiceModel Imports Microsoft.Crm.Sdk.Messages Imports System.Globalization Public Class ClsArudd Implements IPlugin Public Sub Execute(serviceProvider As System.IServiceProvider) Implements Microsoft.Xrm.Sdk.IPlugin.Execute Dim context As IPluginExecutionContext = DirectCast(serviceProvider.GetService(GetType(IPluginExecutionContext)), IPluginExecutionContext) Try Dim parameters As ParameterValue() = Nothing Dim service As IOrganizationService Dim datasourceCredentials As DataSourceCredentials() = GetDataSourceCredentials(service) Dim networkCredentials As New NetworkCredential("xxx", "xxxxxx", "xxxxx") Dim reportPath As String = "/xxxxxx_MSCRM/CustomReports/{290c9065-5742-e311-8565-00155d01d303}" Dim bytes As [Byte]() = RenderReport(networkCredentials, datasourceCredentials, reportPath, parameters, "PDF") 'do something with your bytes like write to pdf file or attach to email etc: 'simple example to write to pdf file: Using fs As New FileStreamC:\temp\REPORT TEST IGNORE\Test1.pdf", FileMode.Create) Using bw As New BinaryWriter(fs) bw.Write(bytes) End Using End Using Catch ex As Exception Throw New InvalidPluginExecutionException("Error generating ARUDD File - " & ex.Message.ToString) End Try End Sub Private Function GetDataSourceCredentials(service As IOrganizationService) As DataSourceCredentials() Dim request As New WhoAmIRequest() Dim whoami = TryCast(service.Execute(request), WhoAmIResponse) Dim userName As String = whoami.UserId.ToString() Dim password As String = whoami.OrganizationId.ToString() 'Create DataSourceCredentials for SRS Dim dsc As New DataSourceCredentials() dsc.DataSourceName = "CRM" 'this is DataSource name in the actual Report. dsc.Password = password 'orgId dsc.UserName = userName 'userId Dim dsCredentials As DataSourceCredentials() = New DataSourceCredentials() {dsc} Return dsCredentials End Function Private Function RenderReport(clientCredentials As NetworkCredential, dataSourceCredentials As DataSourceCredentials(), reportPath As String, parameters As ParameterValue(), renderFormat As String) As [Byte]() Dim resultBytes As Byte() = Nothing Dim encoding As String = String.Empty Dim mimeType As String = String.Empty Dim warnings As Warning() = Nothing Dim streamids As String() = Nothing Dim extension As String = String.Empty Dim binding As BasicHttpBinding = GetBinding() 'some use Basic Dim deviceInfo As String = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>" Dim endpoint As New EndpointAddress("http://xxxx.xxxxxxxx.xxxx/reportserver/ReportServer/ReportExecution2005.asmx") Dim client As New ReportExecutionServiceSoapClient(binding, endpoint) client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation client.ClientCredentials.Windows.ClientCredential = clientCredentials Dim executionInfo As ExecutionInfo = Nothing Dim executionHeader As ExecutionHeader = Nothing Dim serverInfoHeader As ServerInfoHeader = Nothing Dim trustedUserHeader As TrustedUserHeader = Nothing 'load the report executionHeader = client.LoadReport(trustedUserHeader, reportPath, Nothing, serverInfoHeader, executionInfo) executionHeader.ExecutionID = executionInfo.ExecutionID 'add the data source credentials client.SetExecutionCredentials(executionHeader, trustedUserHeader, dataSourceCredentials, executionInfo) 'add any report parameters If parameters IsNot Nothing Then client.SetExecutionParameters(executionHeader, trustedUserHeader, parameters, CultureInfo.CurrentCulture.Name, executionInfo) End If 'render the report to the selectef format ie PDF Dim Info As ServerInfoHeader = client.Render(executionHeader, trustedUserHeader, renderFormat, deviceInfo, resultBytes, extension, _ mimeType, encoding, warnings, streamids) Return resultBytes End Function Private Function GetBinding() As BasicHttpBinding Dim binding As New BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly) binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None binding.Security.Transport.Realm = String.Empty binding.MaxReceivedMessageSize = 2147483647 Return binding End Function End Class
Error
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Error generating ARUDD File - Unable to cast object of type 'Microsoft.Crm.Extensibility.PipelineExecutionContext' to type 'Microsoft.Xrm.Sdk.IOrganizationService'.Detail: <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts"> <ErrorCode>-2147220891</ErrorCode> <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic"> <KeyValuePairOfstringanyType> <d2p1:key>OperationStatus</d2p1:key> <d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">0</d2p1:value> </KeyValuePairOfstringanyType> </ErrorDetails> <Message>Error generating ARUDD File - Unable to cast object of type 'Microsoft.Crm.Extensibility.PipelineExecutionContext' to type 'Microsoft.Xrm.Sdk.IOrganizationService'.</Message> <Timestamp>2013-11-14T17:27:54.8336558Z</Timestamp> <InnerFault i:nil="true" /> <TraceText> [CRM2011Plugins: CRM2011Plugins.ClsArudd] [b1d2fe7f-804c-e311-b2ea-00155d01d303: CRM2011Plugins.ClsArudd: Create of new_aatest] </TraceText> </OrganizationServiceFault>
Dont ask me .. i dont know
- Marked as answer by Pete Newman Monday, November 25, 2013 2:28 PM
Thursday, November 14, 2013 5:34 PM
All replies
-
The answer to your first question is yes, if you register a Create plugin on an entity it will fire when a record is created as part of a data import. I recommend making it an Asynchronous plug-in so that execution does not impact the data import process, causing a possible time-out error.
Rendering a report in a plug-in is something I have less experience with and is something I intentionally try to avoid. That said, these are the best references I know on making it successfully work:
http://www.dowawado.com/2012/10/19/crm-2011-render-ssrs-report-from-plugin/
http://icircusmonkey.wordpress.com/2012/12/24/rendering-crm-2011-report-programmatically/
I would look at ways to eliminate having to run the report, if possible. For example, could you generate and format the e-mail in code - instead of creating a PDF? I can think of lots of ways to approach this requirement - depending on the details, without having to call SSRS.
In addition, I would test it outside of the import process - manually creating the record created by the import process - until you work out all the bugs. This will make it a bit easier to attach the debugger and see what is happening.
Nicolas Nowinski (nicknow.net) Dynamics CRM...if it can't be done with Dynamics CRM, SharePoint, SQL, and C# you don't need to be doing it!
- Edited by Nicolas Nowinski Tuesday, November 12, 2013 4:58 AM sig error
- Proposed as answer by Nicolas Nowinski Tuesday, November 12, 2013 4:59 AM
Tuesday, November 12, 2013 4:58 AM -
HI,
I have tried following those two links but am getting nowhere
Plugin code
Imports System Imports System.Diagnostics Imports System.Linq Imports Microsoft.Xrm.Sdk Imports Microsoft.Xrm.Client Imports CRM2011Plugins.SSRSReportConnection Imports System.Net Imports System.IO Imports System.ServiceModel Imports Microsoft.Crm.Sdk.Messages Imports System.Globalization Public Class ClsArudd Implements IPlugin Public Sub Execute(serviceProvider As System.IServiceProvider) Implements Microsoft.Xrm.Sdk.IPlugin.Execute Dim context As IPluginExecutionContext = DirectCast(serviceProvider.GetService(GetType(IPluginExecutionContext)), IPluginExecutionContext) Try Dim parameters As ParameterValue() = Nothing Dim service As IOrganizationService Dim datasourceCredentials As DataSourceCredentials() = GetDataSourceCredentials(service) Dim networkCredentials As New NetworkCredential("xxx", "xxxxxx", "xxxxx") Dim reportPath As String = "/xxxxxx_MSCRM/CustomReports/{290c9065-5742-e311-8565-00155d01d303}" Dim bytes As [Byte]() = RenderReport(networkCredentials, datasourceCredentials, reportPath, parameters, "PDF") 'do something with your bytes like write to pdf file or attach to email etc: 'simple example to write to pdf file: Using fs As New FileStreamC:\temp\REPORT TEST IGNORE\Test1.pdf", FileMode.Create) Using bw As New BinaryWriter(fs) bw.Write(bytes) End Using End Using Catch ex As Exception Throw New InvalidPluginExecutionException("Error generating ARUDD File - " & ex.Message.ToString) End Try End Sub Private Function GetDataSourceCredentials(service As IOrganizationService) As DataSourceCredentials() Dim request As New WhoAmIRequest() Dim whoami = TryCast(service.Execute(request), WhoAmIResponse) Dim userName As String = whoami.UserId.ToString() Dim password As String = whoami.OrganizationId.ToString() 'Create DataSourceCredentials for SRS Dim dsc As New DataSourceCredentials() dsc.DataSourceName = "CRM" 'this is DataSource name in the actual Report. dsc.Password = password 'orgId dsc.UserName = userName 'userId Dim dsCredentials As DataSourceCredentials() = New DataSourceCredentials() {dsc} Return dsCredentials End Function Private Function RenderReport(clientCredentials As NetworkCredential, dataSourceCredentials As DataSourceCredentials(), reportPath As String, parameters As ParameterValue(), renderFormat As String) As [Byte]() Dim resultBytes As Byte() = Nothing Dim encoding As String = String.Empty Dim mimeType As String = String.Empty Dim warnings As Warning() = Nothing Dim streamids As String() = Nothing Dim extension As String = String.Empty Dim binding As BasicHttpBinding = GetBinding() 'some use Basic Dim deviceInfo As String = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>" Dim endpoint As New EndpointAddress("http://xxxx.xxxxxxxx.xxxx/reportserver/ReportServer/ReportExecution2005.asmx") Dim client As New ReportExecutionServiceSoapClient(binding, endpoint) client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation client.ClientCredentials.Windows.ClientCredential = clientCredentials Dim executionInfo As ExecutionInfo = Nothing Dim executionHeader As ExecutionHeader = Nothing Dim serverInfoHeader As ServerInfoHeader = Nothing Dim trustedUserHeader As TrustedUserHeader = Nothing 'load the report executionHeader = client.LoadReport(trustedUserHeader, reportPath, Nothing, serverInfoHeader, executionInfo) executionHeader.ExecutionID = executionInfo.ExecutionID 'add the data source credentials client.SetExecutionCredentials(executionHeader, trustedUserHeader, dataSourceCredentials, executionInfo) 'add any report parameters If parameters IsNot Nothing Then client.SetExecutionParameters(executionHeader, trustedUserHeader, parameters, CultureInfo.CurrentCulture.Name, executionInfo) End If 'render the report to the selectef format ie PDF Dim Info As ServerInfoHeader = client.Render(executionHeader, trustedUserHeader, renderFormat, deviceInfo, resultBytes, extension, _ mimeType, encoding, warnings, streamids) Return resultBytes End Function Private Function GetBinding() As BasicHttpBinding Dim binding As New BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly) binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None binding.Security.Transport.Realm = String.Empty binding.MaxReceivedMessageSize = 2147483647 Return binding End Function End Class
Error
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Error generating ARUDD File - Unable to cast object of type 'Microsoft.Crm.Extensibility.PipelineExecutionContext' to type 'Microsoft.Xrm.Sdk.IOrganizationService'.Detail: <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts"> <ErrorCode>-2147220891</ErrorCode> <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic"> <KeyValuePairOfstringanyType> <d2p1:key>OperationStatus</d2p1:key> <d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">0</d2p1:value> </KeyValuePairOfstringanyType> </ErrorDetails> <Message>Error generating ARUDD File - Unable to cast object of type 'Microsoft.Crm.Extensibility.PipelineExecutionContext' to type 'Microsoft.Xrm.Sdk.IOrganizationService'.</Message> <Timestamp>2013-11-14T17:27:54.8336558Z</Timestamp> <InnerFault i:nil="true" /> <TraceText> [CRM2011Plugins: CRM2011Plugins.ClsArudd] [b1d2fe7f-804c-e311-b2ea-00155d01d303: CRM2011Plugins.ClsArudd: Create of new_aatest] </TraceText> </OrganizationServiceFault>
Dont ask me .. i dont know
- Marked as answer by Pete Newman Monday, November 25, 2013 2:28 PM
Thursday, November 14, 2013 5:34 PM