Debugging, Logging and Tracing in Callouts
The best way to show how to test and debug callouts is to create a sample Windows application and step through the code. The downloadable sample code
contains a project you can use; however, if you build one yourself, be sure to add references to the CRM web service and to Microsoft.Crm.Platform.Callout.Base. Then you can add the callout class to the project and call its method to debug the code.
If you want to debug the callout beyond the callout code at the platform level, consider turning tracing on using the registry. There are keys available for this purpose at the following locations:
- HKEY_LOCAL_MACHINE\Software\Microsoft\MSCRM (applies to CRM web server)
- HKEY_CURRENT_USER\Software\Microsoft\MSCRMClient (applies to CRM Outlook client)
You may set those registry keys to any of the possible values shown in Table 1.
Table 1. Registry Callout-Tracing Key Values: You can set the two CRM registry key values to these values.
||An existing directory
Configure the CRM UI to Display Detailed Error Messages
|Author's Note: Applying incorrect registry values can bring the entire CRM server down or even cause Windows to crash. Enabling tracing also affects performance. Use tracing only while debugging, and turn it off after you're done.
In case there is a platform-level issue with your callout code and you want detailed error messages rather than the friendly but not always informative message displayed by CRM, consider changing the web.config
file on your CRM server. You can do this by following these steps:
- On the CRM server, navigate to the web root directory (the default is C:\inetpub\wwwroot).
- Locate and open the web.config file.
- Change the value of the DevErrors key to On.
- Save the file.
- Use the Event log to view errors.
You can also use log error messages from your callout code to the Event log. Logging the messages typically provides sufficient information to debug the code effectively. Be sure to wrap your message-logging code in a try/catch/finally
block when you log messages to the event log as shown in Listing 1
In Listing 1
, the post-callout method is PostUpdate()
, and the method body is wrapped in a try/catch/finally
block. Because callouts do not call Dispose
methods, you must clean up all resources in the finally
block to avoid memory leaks. The WriteTolog
method called in the catch
block writes the messages to the Event log. The code logs only inside the catch
block using the error type EventLogEntryType.Error
It is also a good idea to log any informational messages (values of important variables, etc.) in the Event log after each important step in the code. Doing so will help you nail down the problem precisely when debugging an issue.
Logging to Event log can degrade the performance, so you might consider creating an app.config file and adding a key called debug to it. You can set debug to true when you are debugging on your local server and then set it to false when you deploy to your production server.
Understanding Workflows and Callouts
Like callouts, MSCRM workflows also provide you with the ability to plug in a custom assembly using the configuration file. When to use callouts and when to use workflows requires a careful decision. Here are few points that can help you decide between workflows and callouts
- If you need synchronous processing consider using callouts instead of workflows.
- If you need asynchronous processing, use workflows.
- Workflow assemblies work only with entities that they own, so if you want to access customer entities (which are owned by the organization), use callouts.
- Many actions—such as sending email—are already defined in the Workflow Manager. If your need fits well into one of those scenarios, you won't have to write any code, and you should prefer workflows in such cases.
- Callouts cannot be executed manually. If you want your users to execute some rules manually, use workflows.
- If you need to modify data before it gets inserted or updated, prefer callouts.
For example, suppose you wanted to implement a rule in the CRM server that whenever an account entity gets updated, the system should send an email to the sales team. That kind of scenario is best implemented using a post callout, because it requires immediate action, and the transaction should be synchronous.
Limitations of Callouts
Callouts have several limitations, including:
Building Light Callouts
- No support for asynchronous processing
- "Heavier" callouts adversely affect performance
- No supports for failover
If you must
use a callout you can work around the limitations by following these general guidelines. Try to minimize the code as much as possible. In most cases, you can read the incoming XML message (preImageEntityXml
) and store it in some data store, such as a database, a text file, MSMQ, etc., referred to hereafter as a "message store." That way, you can create a Windows service to poll the message store periodically, read any new messages, and perform any required processing on them.
For example, you could write the Windows service to read the polling interval from a configuration file. The Windows service will then process records at a predefined interval, essentially making the callout processing asynchronous. Following this approach, all the callout does is store the incoming message; the Windows service handles all other processing, which makes the callout "light."
In addition, because the messages are saved in a message store, if an error occurs while processing a message, you can recover it later.
Alternatively, you could use a Windows Communication Foundation (WCF) service in place of the Windows service. Another approach is to replace the message store/Windows service combination with SQL Server 2005 broker services, if those meet your needs.