Once you have set up the App Permissions for Azure AD to access Dynamics CRM Online you can use the Application ID to authenticate with Online Management API and work with Various Operations.

 

Follow the given steps to understand how to set up Console Application to work with Online Management API:

  • Open Visual Studio and Create a new “Console Application”
  • Create a New Class file called “Helper.cs” and copy the helper code (from SDK) to the file.

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace Dynamics.OnlineManagement.FirstSample
{

        /// <summary>
        /// Manages authentication to the Online Management API service.
        /// Uses Microsoft Azure Active Directory Authentication Library (ADAL) 
        /// to handle the OAuth 2.0 protocol. 
        /// </summary>
        public class Authentication
        {
            private HttpMessageHandler _clientHandler = null;
            private AuthenticationContext _authContext = null;
            private string _authority = null;
            private string _serviceUrl = null;

            // Static variable to hold the Resource. This will be discovered
            // and then used later for acquiring access token
            private static string _resource = null;

            // TODO: Substitute your app registration values here.
            // These values are obtained on registering your application with the 
            // Azure Active Directory.
            private static string _clientId = "189fd489-4791-4486-a301-f884f923f14d";     //e.g. "e5cf0024-a66a-4f16-85ce-99ba97a24bb2"
            private static string _redirectUrl = "http://localhost/";  //e.g. "http://localhost/SdkSample"

            #region Constructors
            /// <summary>
            /// Base constructor.
            /// </summary>
            public Authentication() { }

            /// <summary>
            /// Custom constructor that allows adding an authority determined asynchronously before 
            /// instantiating the Authentication class.
            /// </summary>                
            /// <param name="authority">The URL of the authority.</param>
            public Authentication(string authority)
                : base()
            {
                Authority = authority;
                SetClientHandler();
            }
            #endregion Constructors

            #region Properties
            /// <summary>
            /// The authentication context.
            /// </summary>
            public AuthenticationContext Context
            {
                get
                { return _authContext; }

                set
                { _authContext = value; }
            }

            /// <summary>
            /// The HTTP client message handler.
            /// </summary>
            public HttpMessageHandler ClientHandler
            {
                get
                { return _clientHandler; }

                set
                { _clientHandler = value; }
            }


            /// <summary>
            /// The URL of the authority to be used for authentication.
            /// </summary>
            public string Authority
            {
                get
                {
                    if (_authority == null)
                    {
                        var authority = DiscoverAuthority(_serviceUrl.ToString());
                        _authority = authority.Result.ToString();
                    }


                    return _authority;
                }

                set { _authority = value; }
            }
            #endregion Properties

            #region Methods
            /// <summary>
            /// Discover the authentication authority asynchronously.
            /// </summary>
            /// <param name="serviceUrl">The specified endpoint address</param>
            /// <returns>The URL of the authentication authority on the specified endpoint address, or an empty string
            /// if the authority cannot be discovered.</returns>
            public static async Task<string> DiscoverAuthority(string _serviceUrl)
            {
                try
                {
                    AuthenticationParameters ap = await AuthenticationParameters.CreateFromResourceUrlAsync(
                        new Uri(_serviceUrl + "/api/aad/challenge"));
                    _resource = ap.Resource;
                    return ap.Authority;
                }
                catch (HttpRequestException e)
                {
                    throw new Exception("An HTTP request exception occurred during authority discovery.", e);
                }
                catch (Exception e)
                {
                    throw e;
                }
            }

            /// <summary>
            /// Returns the authentication result for the configured authentication context.
            /// </summary>
            /// <returns>The refreshed access token.</returns>
            /// <remarks>Refresh the access token before every service call to avoid having to manage token expiration.</remarks>
            public AuthenticationResult AcquireToken()
            {
                return _authContext.AcquireToken(_resource, _clientId, new Uri(_redirectUrl),
                    PromptBehavior.Always);
            }

            /// <summary>
            /// Sets the client message handler.
            /// </summary>
            private void SetClientHandler()
            {
                _clientHandler = new OAuthMessageHandler(this, new HttpClientHandler());
                _authContext = new AuthenticationContext(Authority, false);
            }

            #endregion Methods

            /// <summary>
            /// Custom HTTP client handler that adds the Authorization header to message requests.
            /// </summary>
            class OAuthMessageHandler : DelegatingHandler
            {
                Authentication _auth = null;

                public OAuthMessageHandler(Authentication auth, HttpMessageHandler innerHandler)
                    : base(innerHandler)
                {
                    _auth = auth;
                }

                protected override Task<HttpResponseMessage> SendAsync(
                    HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
                {
                    // It is a best practice to refresh the access token before every message request is sent. Doing so
                    // avoids having to check the expiration date/time of the token. This operation is quick.
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _auth.AcquireToken().AccessToken);

                    return base.SendAsync(request, cancellationToken);
                }
            }
        }
 
}

 

  • In Helper code update client id to your Application ID while you registered CRM Online App with Azure AD. Set URL to “http://localhost/” 
  • Add Reference to “Microsoft.IdentityModel.Clients.ActiveDirectory”. If you don’t have it installed you can install it through NuGet Package
    • Right click the References -> Click Manage NuGet Packages.
  •  
    • Search for “Microsoft.IdentityModel.Clients.ActiveDirectory” and select version “2.x.x” as version “3.x.x” will not work.  Click Install.
  •  
  • Replace Program class with following code (taken from SDK Sample) and add missing references.

using System;
using System.Net.Http;
using System.Threading.Tasks;


namespace Dynamics.OnlineManagement.FirstSample
{

    /// <summary>
    /// This sample retrieves Customer Engagement instances
    /// in your Office 365 tenant.
    /// </summary>    

    class Program
    {
        private HttpClient httpClient;

        //TODO: Change this value if your Office 365 tenant is in a different region than North America
        private static string _serviceUrl = "https://admin.services.crm5.dynamics.com";

        private void ConnectToAPI()
        {
            Console.WriteLine("Connecting to the Online Management API service...");

            // Discover authority for the Online Management API service
            var authority = Authentication.DiscoverAuthority(_serviceUrl);

            // Authenticate to the Online Management API service by 
            // passing in the discovered authority 
            Authentication auth = new Authentication(authority.Result.ToString());

            // Use an HttpClient object to connect to Online Management API service.           
            httpClient = new HttpClient(auth.ClientHandler, true);

            // Specify the API service base address and the max period of execution time 
            httpClient.BaseAddress = new Uri(_serviceUrl);
            httpClient.Timeout = new TimeSpan(0, 2, 0);
        }

        public async Task RetrieveInstancesAsync()
        {
            HttpRequestMessage myRequest = new HttpRequestMessage(HttpMethod.Get, "/api/v1/instances");
            HttpResponseMessage myResponse = await httpClient.SendAsync(myRequest);

            if (myResponse.IsSuccessStatusCode)
            {
                var result = myResponse.Content.ReadAsStringAsync().Result;
                Console.WriteLine("Your instances retrieved from Office 365 tenant: \n{0}", result);
            }
            else
            {
                Console.WriteLine("The request failed with a status of '{0}'",
                       myResponse.ReasonPhrase);
            }
        }

        static public void Main(string[] args)
        {
            Program app = new Program();
            try
            {
                // Connect to the Online Management API. 
                app.ConnectToAPI();

                // Run your request
                Task.WaitAll(Task.Run(async () => await app.RetrieveInstancesAsync()));
            }
            catch (System.Exception ex) { DisplayException(ex); }
            finally
            {
                if (app.httpClient != null)
                { app.httpClient.Dispose(); }
                Console.WriteLine("Press <Enter> to exit the program.");
                Console.ReadLine();
            }
        }

        /// <summary> Helper method to display exceptions </summary> 
        private static void DisplayException(Exception ex)
        {
            Console.WriteLine("The application terminated with an error.");
            Console.WriteLine(ex.Message);
            while (ex.InnerException != null)
            {
                Console.WriteLine("\t* {0}", ex.InnerException.Message);
                ex = ex.InnerException;
            }
        }
    }

}

 

  • Update the Service URL based on your region.
  • Run the Application, it will ask for Online Authentication and approval to give permissions to app.
  • Once executed you will get instance information.

For Sample Highlighted above you can refer to First Sample solution in following Git Repo.

https://github.com/BuggyBrain/Dynamics.OnlineManagement   

The post Online Management API: Using Console Application appeared first on Abhinav Ranjan.