After my last couple of blogs on Web API, I am being asked this question repeatedly. Can I use Web API from Plugins/ Custom workflows? And I keep on asking back, why do you need that? After all there is the almighty organization service which virtually allows you do anything and everything that you would need to do. Honestly I find very limited use of invoking Dynamics Web API from Plugins unless you want to get out of the transaction scope under which your plugin is running.
That said, I wondered why not give it a try. After all learning something new never hurts. So let’s see the feasibility for this in Dynamics CRM Online
CRM On-Premise (without IFD)
Honestly before I tried this code, I had doubts whether it would work at all. However it worked like a charm. In the below code, I am retrieving an account with a particular guid.
using (WebClient client = new WebClient())
client.UseDefaultCredentials = true;
byte responseBytes = client.DownloadData(new Uri(“<your web api url>/accounts(3C2D2712-E43F-E411-9402-005056AB452C)”));
string response = Encoding.UTF8.GetString(responseBytes);
// parse the json response
This is a simple example but the same construct would work for any web api query. Just paste this code anywhere in your plugin and it should work. Make sure you specify the UseDefaultCredentials as true to make the web api call under the context of the user the plugin is running.
This code will work even if you are calling the the webapi from a console application. The only difference is in that case you would need to specify your credentials instead of using the default credentials.
client.Credentials = new NetworkCredential(<username>, <password>, <domain>)
CRM Online or IFD
Unfortunately I could not make it work for CRM online when i wrote this blog. To see it working with the latest version of Dynamics online, go for the below link
Now continuing with this post for 2016 version IFD
The above could would not work for CRM online since the WebClient credentials is of type Network credentials whereas you need to pass office 365 credentials to for CRM online.
For calling online WebAPI methods you would need to pass the OAuth token in the header and for that you would need user interaction. Executing the webclient code from above with the credentials would give you unauthorized access. I even tried to use the ADAL library in plugin and get the authentication token but since the plugin is in sandbox mode you would end up with an error like the one below.
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=220.127.116.11, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Unexpected exception from plug-in (Execute): XrmPlugins.TestEntityPostUpdate: System.TypeLoadException: Inheritance security rules violated while overriding member: ‘Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)’. Security accessibility of the overriding method must match the security accessibility of the method being overriden.Detail:
<OrganizationServiceFault xmlns:i=”http://www.w3.org/2001/XMLSchema-instance” xmlns=”http://schemas.microsoft.com/xrm/2011/Contracts”>
<ErrorDetails xmlns:d2p1=”http://schemas.datacontract.org/2004/07/System.Collections.Generic” />
<Message>Unexpected exception from plug-in (Execute): XrmPlugins.TestEntityPostUpdate: System.TypeLoadException: Inheritance security rules violated while overriding member: ‘Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)’. Security accessibility of the overriding method must match the security accessibility of the method being overriden.</Message>
<InnerFault i:nil=”true” />
A pretty ugly error but what this means is that to acquire the token, Active Directory Authentication Library would need to run in full trust mode but plugins registered in sandbox( which is the only option for online) runs only under partial trust.
As of now I am stuck with this. Would definitely like to know if anybody is able to get this working.
Hope this helps!