locked
help understanding pluging and what is possible RRS feed

  • 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!


    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