Aidan Garnish

Collaboration Not Competition

Using generic handlers in Dynamics CRM

Sometimes you need to add functionality to Microsoft Dynamics CRM that cannot be easily achieved by simply adding JavaScript to form and field events.

One way to add extra complex functionality to CRM is to use a generic handler .ashx code file.

For example if you want to copy a quote and it's quote products this is not easily achieved using JavaScript and is not possible using the standard CRM workflows.

To make use of a .ashx generic handler is a 3 step process:

  1. Create the .ashx handler that performs the required functions and deploy it to your CRM server
  2. Add a JavaScript function to a form that will call the .ashx and handle the returned result
  3. Update the ISV.config to add a button to the relevant entity so that the user can trigger the functionality

1. Create .ashx handler

To create the handler you will need a new Visual Studio project. Add a Generic Handler (.ashx) code file to the project and then add references to the CRM web services.

Add your code to provide the desired functionality.

Click this link to download the .ashx code files for copying a Dynamics CRM quote 

The application then needs to be deployed to IIS.

2. Add a JavaScript function to call the handler and display the returned result

Add the JavaScript to the onload event of the form where this functionality will be called. In this example of copying a quote add the function to the onload event of the Quote main form.

CopyQuote = function()
{
InitXmlHttp();
xmlhttp.onreadystatechange= XMLHttpRequestCompleted;
// use the url to your generic handler project here - in this case 
//I have deployed the project to the website that is running CRM
xmlhttp.open("GET", http://YourCRMServer/CRM.GenericHandlers/CopyQuote.ashx?id=
+crmFormSubmit.crmFormSubmitId.value , true );
xmlhttp.send(null);
function InitXmlHttp() {
  // Attempt to initialize xmlhttp object
    try
    {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
    {
        // Try to use different activex object
        try
        {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch (E)
        {
            xmlhttp = false;
        }
    }
    
    // If not initialized, create XMLHttpRequest object
    if (!xmlhttp && typeof XMLHttpRequest!='undefined')
      {     
            xmlhttp = new XMLHttpRequest();
      }
      // Define function call for when Request obj state has changed
      xmlhttp.onreadystatechange=XMLHttpRequestCompleted;
}
function XMLHttpRequestCompleted()
{
        if (xmlhttp.readyState==4)
        {
            try
            {
                alert(xmlhttp.responseText);
            }
            catch (e)
            {
           }
        }
    }
}
 

3. Update ISV.config to add a button to call the CopyQuote() JavaScript

Export the ISV.config file and add the following to the Quote section:

<Button JavaScript="CopyQuote();">
    <Titles>
            <Title LCID="1033" Text="Copy Quote" />
          </Titles>
              <ToolTips>
                <ToolTip LCID="1033" Text="Copy Quote" />
              </ToolTips>
        </Button>
 

Save the updated ISV.config file and import it back into CRM.

The result of this is that you now have a button on the Quote form called Copy Quote. When this button is clicked the JavaScript calls the .ashx file which copies the quote and then sends a message back to the JavaScript to let the user know if the operation has been successful.

Create Dynamics CRM entity mapping for lookup field

When editing attributes on CRM entities it is often necessary to pass that attribute through to the entity in the next stage in the sales process.

For example you add a contact name to the quote entity and you want that contact to be passed through to the order that is created from the quote.

To do this for standard fields it is simply a case of opening the customisation screen for the entity, adding a new attribute and then adding a new mapping to the relevant relationship. In the case of quotes and orders this would be the N:1 quote to order relationship.

Where things become a little bit trickier is if you want to create a mapping between two entities for an attribute that is a lookup. This is because it is not possible to simply add a lookup field as an attribute.

To do this for the case of the contact lookup being passed from quote to order do the following:

  • Create a new N:1 relationship on the order entity. The Primary Entity for the realtionship will be Contact.
  • Give it a display name of Contact and leave all the other fields as default.
  • Click Save and Close - this will have created a new attribute called Contact which we can now use to map the Quote Contact attribute to.
  • Edit the Quote to Order 1:N relationship and add a new mapping between Contact in the source and target entities.
  • Click OK.
  • Now you can add Contact to the forms and views where it needs to be visible.