CRM 2013 – Leveraging Actions to get around JavaScript cross-domain challenges

Last year, I wrote about the challenge of cross-domain calls from JavaScript with CRM 2011. The issue was related to fact that from a security perspective, you could not have JavaScript functions executing on a CRM form event or when a ribbon button is clicked calling web services outside of the CRM domain. I proposed a few workarounds here but the bottom line is that in all cases, there was some sort of a negative impact in each solution. With CRM 2013, actions processes are a great way to get around the browsers’ cross domain restriction.

In this article, I am providing an example of how actions can be used to make a request to a web service outside of the CRM domain from a record’s form event.

Scenario

When users call an incident management center, the agents need to capture the temperature at the time of the incident in the city where it occurred. In order to do so, we decide to create a button on the command bar that agents can click on and that will perform the following tasks:

  • Read the City and Country information from the form
  • Call an Action that
    • Takes the City and Country as parameters
    • Use an external web service to get the temperature in the city
    • Returns the temperature as output parameters
  • Sets the temperature field value on the form

Note: In order to achieve this directly with JavaScript, performing Step 2 of the action would require to make a cross-domain call from JavaScript.

Process Configuration

To start things off, let’s start be creating an Action of type process. This action will have 2 input values (City and Country) and 2 output values (Temperature in Fahrenheit and in Celsius).

The steps are really simple. The action needs to a custom workflow activity that will connect to a weather web service and return the temperature in two output values of its own.

Custom Workflow Activity

Here you can see what the custom workflow activity code looks like. It’s very straight forward in that it only has 3 steps:

  1. Read the city and country inputs
  2. Initialize the web service client object and make the web service call
  3. Set the values back in the output fields to be available in the process

Calling Action from JavaScript

This is the last piece of the puzzle. At this point, we simply need to call the action created from a JavaScript event (ribbon button clicked, on change of a value etc.). In order to achieve this, create a function that is called when the client even occurs. That function should execute the Action, read the output values and set the field values on the form. This has to be done with a SOAP call. There are two ways to do this. You can:

  • use Deepak’s example as show in his blog post here or
  • use the CRM 2013 Sdk.Soap.js action message generator published by the Microsoft CRM SDK team to generate a request and response class you can use in your call to call the action using JavaScript.

Wrap up

This is another great example of how actions can be leveraged to work around challenges that we’ve dealt with in the pre-CRM 2013 era. Keep in mind that in order to call an external web service from the custom workflow activity, there are server security elements to take into consideration (e.g. can my server talk to the web service? etc.)

Hope this helps!

Advertisements

6 thoughts on “CRM 2013 – Leveraging Actions to get around JavaScript cross-domain challenges

  1. Pingback: Making Cross Domain AJAX calls from CRM Form JScript | Salim Adamon - Dynamics CRM Blog

  2. Hi Salim, Thanks for this great post!
    I have a question about this possible solution for cross domain webservice. In my scenario I could have more than one result in my response from the webservice. Then the user should be able to select the correct record / row. So it might that I need to have something like an array with the values. Is something like this also possible with this approach?
    Look forward to hear from you!

    • Hi Nico,

      Yes, you can have your action return an array with your values in a single string, or the number or records returned is known, you can just add output values in the action process. Your challenge and/or additional work will be around figuring out a way to display the results and to enable your users to select a record a do something with it. You can use an approach with an HTML/Javascript based web resourcce to achieve this.

      Have fun!

      • Hi Salim,

        I was indeed thinking about doing something like that with an HTML page where we will parse the result to (with javascript).
        When I look at the point where you create your webservice object I am loosing you a litte. How and where do I build up xml request to be send, because this is not visible to me in current screen and of course because I am not a core developer. 😉
        Another thing and just out of curiosity. Does this also work in create state and can I make it synchronous?

        Thanks

  3. Yes, you can make it somewhat synchronous in the sense that you’ll make a SOAP request from javascript. You can use ajax to send the request and process the result in a callback method, or you can use the XMLHttpRequest object directly and parse the response within a single method. There are pros and cons for both methods.

    As to you other question (how to build the XML request), you can either “guess” by looking at Deepak’s blog post above, put in right values for your entity type, ID, parameters etc. The Sdk.Soap.js action message generator published from the SDK team is actually a tool that you need to compile and use to generate the XML request for you. Check out the documentation on the download page.

    Cheers!

  4. Hello,
    I Have a custom Action called: new_actionTest and I Have a custom plugin registered with message new_actionTest. In plugin i am setting output Parameter dependant on input Parameter’s value.

    I am requesting my action from external Console Application, just for test. In the response i get expected value.
    But I am also setting this value in steps of an Action, and this is disappointing, because it simply doesn’t work.
    Let’s say I have an Argument definied in Action called OutputArgument. I am setting it in my Custom Plugin and I can see correct value in respons after my request in Console Application. But In my action I have some extra steps which I wanted to use this value which was set in Plugin. This is similar to your solution, but I am using Custom Plugin instead of workflow, and it is not working. What I am doing wrong?
    Please help me find out what is wrong, regards

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s