Source Code Sample
CRM 1.2
![]() |
The following code example shows the implementation of pre-callouts and post-callouts. In order to build this sample, you must add a reference to the Microsoft.Crm.Platform.Callout.Base.dll assembly in the Microsoft Visual Studio .NET project and add a Web reference named 'CrmSdk' that points to the Microsoft CRM 3.0 Web service.
Note Microsoft CRM 3.0 callouts must be created with the .NET Framework version 1.1. Visual Studio 2003 supports this version of the .NET Framework.
using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Xml;
using System.IO;
using System.Security.Principal;
using Microsoft.Win32;
using Microsoft.Crm.Callout;
using CrmSdk;
namespace Microsoft.Crm.Sdk.FullSample.CalloutSample2
{
class CalloutComponent: CrmCalloutBase
{
private string GetPath()
{
string retval = null;
RegistryKey key = Registry.LocalMachine.OpenSubKey(
"Software\\Microsoft\\MSCRM", false);
retval = (string)key.GetValue("CRM_Server_InstallDir");
retval = Path.Combine(retval, @"server\bin\assembly\");
key.Close();
return retval;
}
/// <summary>
/// Note that the Network Service system user account under which
/// all callouts execut must have write permission to the
/// <CRM server install dir>\server\bin\assembly folder
/// in order for the following method to work.
/// </summary>
/// <param name="message"></param>
private void WriteToFile(string message)
{
using (StreamWriter sw = File.CreateText(
Path.Combine(GetPath(), "callout_test_output.txt")))
{
sw.WriteLine(message);
}
}
public override PreCalloutReturnValue PreCreate(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
ref string entityXml,
ref string errorMessage
)
{
try
{
XmlDocument xd = new XmlDocument();
xd.LoadXml(entityXml);
// Initialize a NameTable object.
NameTable nt = new NameTable();
// Initialize a namespace manager.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
// Add the required prefix/namespace pairs to the namespace
// manager. Add a default namespace first.
nsmgr.AddNamespace("crm",
"http://schemas.microsoft.com/crm/2006/WebServices");
nsmgr.AddNamespace("xsi",
"http://www.w3.org/2001/XMLSchema-instance");
// For a list of available Entity Type Codes, refer to the SDK
// documentation.
switch (entityContext.EntityTypeCode)
{
// Account
case 1:
// Use the Document Object Model (DOM) to locate and
// change the account's name.
foreach (XmlElement element in
xd.GetElementsByTagName("Property"))
{
if (element.Attributes.GetNamedItem("Name").Value == "name")
{
element.FirstChild.InnerText =
"Read account " + element.InnerText;
break;
}
}
break;
// Task
case 4212:
// To demonstrate an alternate technique, use an XPath
// query to locate value for task subject. You must prefix
// each element in the entity Xml with the Microsoft CRM
// namespace.
XmlNode node = xd.SelectSingleNode(
"//crm:Property[@Name='subject']/crm:Value", nsmgr);
// Set node's InnerText property to the new subject value.
if (node != null)
node.InnerText = "Read task " + node.InnerText;
break;
}
entityXml = xd.OuterXml;
}
catch(Exception e)
{
throw e;
}
return PreCalloutReturnValue.Continue;
}
public override PreCalloutReturnValue PreUpdate(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
ref string entityXml,
ref string errorMessage
)
{
return PreCalloutReturnValue.Stop;
}
public override PreCalloutReturnValue PreAssign(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
Guid assignedToId,
ref string errorMessage
)
{
return PreCalloutReturnValue.Stop;
}
public override PreCalloutReturnValue PreDelete(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
ref string errorMessage
)
{
errorMessage = "Aborting delete";
return PreCalloutReturnValue.Abort;
}
public override PreCalloutReturnValue PreSetState(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
ref int newStateCode,
ref int newStatusCode,
ref string errorMessage
)
{
return PreCalloutReturnValue.Continue;
}
public override PreCalloutReturnValue PreMerge(
CalloutUserContext userContext,
CalloutEntityContext masterEntityContext,
CalloutEntityContext subordinateEntityContext,
ref string mergeUpdateEntityXml,
ref string errorMessage
)
{
return PreCalloutReturnValue.Abort;
}
public override void PostCreate(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
String postImageEntityXml
)
{
WriteToFile(
String.Format("PostCreate called.\npostImage = {0}",
postImageEntityXml));
}
public override void PostUpdate(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
String preImageEntityXml,
String postImageEntityXml
)
{
WriteToFile( String.Format(
"PostUpdate called\n preImage = {0}\n postImage = {1}",
preImageEntityXml, postImageEntityXml));
}
public override void PostAssign(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
String preImageEntityXml,
String postImageEntityXml
)
{
WriteToFile(
String.Format(
"PostAssign called\n preImage = {0}\n postImage = {1}",
preImageEntityXml, postImageEntityXml));
}
public override void PostDelete(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
String preImageEntityXml
)
{
WriteToFile(
String.Format("PostDelete called\n preImage = {0}",
preImageEntityXml));
}
public override void PostSetState(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
String preImageEntityXml,
String postImageEntityXml
)
{
WriteToFile(
String.Format(
"PostSetState called\n preImage = {0}\n postImage = {1}",
preImageEntityXml, postImageEntityXml));
}
public override void PostMerge(
CalloutUserContext userContext,
CalloutEntityContext entityContext,
String preImageMasterEntityXml,
String preImageSubordinateEntityXml,
String postImageMasterEntityXml
)
{
WriteToFile( String.Format(
"PostMerge called\n preMasterImage = {0}\npreSubImage = {1}\n postMasterImage = {2}",
preImageMasterEntityXml,
preImageSubordinateEntityXml,
postImageMasterEntityXml));
}
}
}
© 2007 Microsoft Corporation. All rights reserved.

