Connecting to CRM 2013 Online SOAP and OData endpoint through External Client Application (Windows Forms Application)
With CRM 2013, external client application can now authenticate with the Microsoft Dynamics CRM OData and SOAP web service end points.
Steps:
- Create a new windows application project in Visual Studio.
- Right click the project in solution explorer and select Manage NuGet Packages.
- Search Online and Install Active Directory Authentication Library.
The following Assemblies will be added to the project
- Next step is to register the app.
- Sign in to Graph Explorer using the system account used to access Microsoft Dynamics CRM Online.
- https://graphexplorer.cloudapp.net/
- Select Add Application Permission option there
- Specify Microsoft.CRM in the service already has been registered drop down box.
- Specify Client App Url as ms-app://test
- Copy App Url and Client ID value from the Application Permission Creation Summary Page. We will use those values in our windows application.
The sample code (uses the code found in SDK)
namespace Crm2013WindowsApp
{
public partial class MyApp : Form
{
public MyApp ()
{
InitializeComponent ();
}
private const string _clientID = "0a57c0ce-6624-42c7-9178-7cb0e44249c0" ;
public const string CrmServiceUrl = "https://x.crm5.dynamics.com/" ;
private void Form1_Load (object sender , EventArgs e )
{
try
{
string redirectUri = "ms-app://test" ;
var authenticationContext = new AuthenticationContext ( "https://login.windows.net/common/wsfed" );
var authenticationResult = authenticationContext . AcquireToken ( "Microsoft.CRM" , "0a57c0ce-6624-42c7-9178-7cb0e44249c0" , new System . Uri ( redirectUri ));
var token = authenticationResult . AccessToken ;
//Call Soap
RetrieveMultipleSoap ( token , new string [] { "firstname" , "lastname" }, "contact" );
// Call OData
Retrieve ( token , new string [] { "FirstName" , "LastName" }, "Contact" );
}
catch( Exception ex )
{
MessageBox . Show ( "Error occured " + ex . Message );
}
}
public static async Task < string > RetrieveMultipleSoap ( string accessToken , string [] Columns , string entity )
{
// Build a list of entity attributes to retrieve as a string.
string columnsSet = string . Empty ;
foreach ( string Column in Columns )
{
columnsSet += "<b:string>" + Column + "</b:string>" ;
}
// Default SOAP envelope string. This XML code was obtained using the SOAPLogger tool.
string xmlSOAP =
@"<s:Envelope xmlns:s='https://schemas.xmlsoap.org/soap/envelope/'>
<s:Body>
<RetrieveMultiple xmlns='https://schemas.microsoft.com/xrm/2011/Contracts/Services' xmlns:i='https://www.w3.org/2001/XMLSchema-instance'>
<query i:type='a:QueryExpression' xmlns:a='https://schemas.microsoft.com/xrm/2011/Contracts'><a:ColumnSet>
<a:AllColumns>false</a:AllColumns><a:Columns xmlns:b='https://schemas.microsoft.com/2003/10/Serialization/Arrays'>" + columnsSet +
@"</a:Columns></a:ColumnSet><a:Criteria><a:Conditions /><a:FilterOperator>And</a:FilterOperator><a:Filters /></a:Criteria>
<a:Distinct>false</a:Distinct><a:EntityName>" + entity + @"</a:EntityName><a:LinkEntities /><a:Orders />
<a:PageInfo><a:Count>0</a:Count><a:PageNumber>0</a:PageNumber><a:PagingCookie i:nil='true' />
<a:ReturnTotalRecordCount>false</a:ReturnTotalRecordCount>
</a:PageInfo><a:NoLock>false</a:NoLock></query>
</RetrieveMultiple>
</s:Body>
</s:Envelope>" ;
// The URL for the SOAP endpoint of the organization web service.
string url = "https://x.crm5.dynamics.com/XRMServices/2011/Organization.svc/web" ;
// Use the RetrieveMultiple CRM message as the SOAP action.
string SOAPAction = "https://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/RetrieveMultiple" ;
// Create a new HTTP request.
HttpClient httpClient = new HttpClient ();
// Set the HTTP authorization header using the access token.
httpClient . DefaultRequestHeaders . Authorization = new AuthenticationHeaderValue ( "Bearer" , accessToken );
// Finish setting up the HTTP request.
HttpRequestMessage req = new HttpRequestMessage ( HttpMethod . Post , url );
req . Headers . Add ( "SOAPAction" , SOAPAction );
req . Method = HttpMethod . Post ;
req . Content = new StringContent ( xmlSOAP );
req . Content . Headers . ContentType = MediaTypeHeaderValue . Parse ( "text/xml; charset=utf-8" );
// Send the request asychronously and wait for the response.
HttpResponseMessage response ;
response = await httpClient . SendAsync ( req );
var responseBodyAsText = await response . Content . ReadAsStringAsync ();
return responseBodyAsText ;
}
public static async Task < string > Retrieve ( string accessToken , string [] Columns , string entity )
{
// Build a list of entity attributes to retrieve as a string.
string columnsSet = "" ;
foreach ( string Column in Columns )
{
columnsSet += "," + Column ;
}
// The URL for the OData organization web service.
string url = "https://x.crm5.dynamics.com/XRMServices/2011/OrganizationData.svc/" + entity + "Set?$select=" + columnsSet . Remove ( 0 , 1 ) + "" ;
// Build and send the HTTP request.
HttpClient httpClient = new HttpClient ();
httpClient . DefaultRequestHeaders . Authorization = new AuthenticationHeaderValue ( "Bearer" , accessToken );
HttpRequestMessage req = new HttpRequestMessage ( HttpMethod . Get , url );
req . Method = HttpMethod . Get ;
// Wait for the web service response.
HttpResponseMessage response ;
response = await httpClient . SendAsync ( req );
var responseBodyAsText = await response . Content . ReadAsStringAsync ();
return responseBodyAsText ;
}
}
}
Cheers !
Shraddha
Comments
Anonymous
November 28, 2013
nice articleAnonymous
December 05, 2013
We've got CRM Dynamics 2013 Online 6.0.0.1018, but signing into Graph Explorer with system account failed complaining of wrong user id or password. I take it we don't need to create an Active Directory on Azure and link it somehow? Also is there code samples for non-dotnet languages making the authentication requests without the library? And can this work without requiring the user to sign-in? We have a public website running on Linux and want a form that visitors can fill out and then on the server save it in our Dynamics system automatically. So storing credentials in our web app and calling the Dynamics REST service with those credentials is exactly what we want.Anonymous
December 06, 2013
The comment has been removedAnonymous
December 20, 2013
Shraddha, thanks I've been reading that Microsoft are in the middle of migrating Dynamics from Windows Live authentication to Office365 authentication, could that be the cause of failing to sign in to Graph Explorer if we haven't migrated yet?Anonymous
March 17, 2014
Hi, I am trying to create application permission as well and followed all the steps but I noticed that the client dropdown (below the Company textbox) is empty for me. Note: I'm using Dynamics CRM 2013 Online trial version. Thanks,Anonymous
April 26, 2014
Hi Shraddha, We are trying to use a third party user fillable application that we want CRM 2013 to house. Also, need our Account Entity to hold the link to web service. Our Live Forms will push out data for a flow submission using a multipart HTTP POST. This contains XML, attached PDFs, etc. Appreciate the help. Kindly, MikeAnonymous
August 19, 2014
The comment has been removedAnonymous
December 12, 2015
hi is it also possible to do the same using javascript API? i need to use odata on a hybrid application which uses OData REST URIs to do CRUD operations. The problem is with the authentication... how can it be possible right now?