Wednesday, March 29, 2006

Setting up Callouts

As I go and set up callouts I find that there are a lot of steps to remember on the set up and I always miss at least one and then I have to troubleshoot for the next 15 to 30 minutes something that should be rather simple. So, for you callout experts this may be simple and second nature to you. But for those of you who found callouts a little daunting at first I'm hoping to make them not so scary and daunting.


I used to always try and push as much custom stuff into workflow work arounds or something else because I could never get my callouts to fire correctly. But now that I have done it enough times and have the set up together I must say that I am sold on callouts and will be ready to do them whenever needed. And since they are so powerful I find that sometimes its better and easier to skip workflow and just use callouts.


Most of the items on this list don't have to be done in this order but this is the order that makes the most sense to me. So, here's the set up:

1. Make a Windows Library project in Visual Studio

a. Choose whatever language you prefer (C# or VB)

2. Change the name of the Class and Namespace if desired.

3. Create a reference to the Microsoft.Crm.Platform.Callout.Base.dll

a. In the code you also need to add this line of code:

using Microsoft.Crm.Callout;

4. Create a web reference to the CrmService and call it CrmSdk

a. The URL to the CrmService is (just with and http at the front):

([crmserver]/mscrmservices/2006/crmservice.asmx)

5. Decide what kind of callout you want. You can either have Pre or Post (unless otherwise specified) to the following events listed below:

a. Create

b. Update

c. Delete

d. Assign

e. Set State

f. MergePersonally

g. PreSend

h. PostDeliver


I always refer the "calloutsample2" code from the CRM SDK sample code because it has all of the constructors for each of the available events and I can just copy and paste the correct constructor into my code. This way I avoid unnecessary errors later on. Also, its a good template to compare your basic code set up against.

6. Also be sure to include the interface call to the CrmCalloutBase or else none of your callouts will work. You need to do this on the same line as your class constructor. From the calloutsample2 code it looks something like this:

class CalloutComponent: CrmCalloutBase

Or more generally:class

[name of your class]:CrmCalloutBase


7. I also always add these methods of code for troubleshooting purposes (also from calloutsample2):

private string GetPath(){

string retval = null;

RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\MSCRM", true);

retval = (string)key.GetValue("CRM_Server_InstallDir");

retval = Path.Combine(retval, @"server\bin\assembly\");

key.Close(); return retval;

}

private void WriteToFile(string message){

using (StreamWriter sw = File.CreateText( Path.Combine(GetPath(), "callout_test_output.txt")))

{ sw.WriteLine(message);

}

}


This code will give you the ability to output your code into a text file. This is the only way I've seen how to troubleshoot your callout code properly. You can look in the event log for errors but generally they are so generic that they aren't very useful. However, there are some useful errors so don't NOT use the event logs. Any source of error reporting with callouts is welcome in my book.


8. Code wise you're just about there. Now all you have to do with this part is code what want the callout to do. However, even once the callout is coded it won't work unless to continue on with the rest of the perparations below.


9. Callout.config.xml

a. This is the file that links the code with the application. If this file is not set up correctly then your callout (no matter how beautifully coded) will never fire.

b. Here's what it looks like in its basic element:

<callout.config version="3.0" xmlns=" http://schemas.microsoft.com/crm/2006/callout/">

<callout entity="[entity name]" event="[event name]">

<subscription assembly="[name of dll].dll" class="[namespace].[classname]"/>

</callout>

</callout.config>


This file needs to be saved on the server at this location:
"C:\Program Files\Microsoft CRM\Server\bin\assembly"

10. Once that's done you will need to copy over your dll to the same location:
"C:\Program Files\Microsoft CRM\Server\bin\assembly"

11. Now run your callout and troubleshoot as necessary. That's the basic set up.

12. A few words about Troubleshooting

a. Whenever you change your code you must recompile your code and then copy your dll to the server.

b. But the dll will be in use and not be able to be overwritten until it is not in use. So, here's the best practice method of getting your most up to date code onto the server. Note, this only needs to be done when you are overwriting your dll that is already on the server.

i. Do an IISRESET on the CRM server.

ii. Stop the CRM Workflow service

iii. Copy the dll onto the server

iv. Do another IISRESET - this is necessary for the server to recognize the new dll

v. Restart the CRM Workflow service

c. Now your code is updated and you are ready to test your code again. Just go to the entity and fire the event you set up your code to do.

That's callouts in a nutshell. A lot to remember at first but once you get it all together and get it working they are VERY powerful.

Happy coding!

David Fronk


Dynamic Methods Inc.

7 comments:

Dynamic Methods said...

As pointed out to me by John O'Donnell, the latest SDK has included new logical events to fire callouts from. They are:

PreSend
PostDeliver

Both for Emails obviously.

charan said...

Hi David,
I am totally new to Callouts & your article helped me a lot.
I have followed all the steps,however i do not know how to run the callouts & where i can see the outputs?
Basically my requirement is to capture all fields that have been updated in CRM UI to use in a .net program

Vishwas said...

Hi david,

The article helped me a lot,in understanding about callouts in a easy way., thank you..
but as i am new to callouts wher can i see the output.....and also how can i complie it......
please let me know on vishwasar_ece@yahoo.com

Dynamic Methods said...

Your output will be through either the WriteToFile method or through the debugging capabilities of Visual Studio. Debugging is really nice, just a pain to set up. The WriteToFile is a simple way to pass values from your code as text into a text file that you specify the location of. If you want to see more about that look in the CRM SDK and it goes over that in more detail.

darshan said...

Any idea if post delete callout works in cascade delete scenario? I am having trouble firing a post delete callout when the parent entity is deleted (and in turn deleting the refernce entoty for which post callout is written).
If i delte the child enity directly the callout works just fine. Please reply me on darshanparekh@gmail.com
Regards,
Darshan

darshan said...

Want to know if post delete callout work in case of cascade delete?
Regards,
Darshan

Dynamic Methods said...

PostDeletes are an interesting ball of wax because the record gets deleted and you can no longer reference the record that has been deleted, so as long as your actions do not require any data from that record you should be okay.

I haven't played with the PostDelete too much but as far as cascade deletes go I don't think they trigger callouts to fire. I could be wrong because I haven't checked it out for awhile, what did you find Darshan?

David Fronk
Dynamic Methods Inc.

Post a Comment