Refresh Security Token for Microsoft Dynamics CRM Connection

In my previous blog post I used singleton pattern to keep the connection open to Dynamics CRM organization service. The only caveat of this method is that you need to monitor your token expiry depending on your implementation method and renew it before expiry.

From MSDN best practices:

Monitor your WCF security token (Token) and refresh it before it expires so that you do not lose the token and have to start over with authentication. To check the token, create a custom class that inherits from the OrganizationServiceProxy or DiscoveryServiceProxy class and that implements the business logic to check the token. Or wrap the proxy classes in a new class. Another technique is to explicitly check the token before each call to the web service. Example code that demonstrates these techniques can be found in the ManagedTokenDiscoveryServiceProxy, ManagedTokenOrganizationServiceProxy, and AutoRefreshSecurityToken classes in the Helper code: ServerConnection class topic.

See the code on GitHub

This piece of code demonstrate how to do monitor the token and refresh it before it expires:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;

namespace CRMConnectionHelper
    public sealed class ManagedTokenOrganizationServiceProxy : OrganizationServiceProxy
        private AutoRefreshSecurityToken<OrganizationServiceProxy, IOrganizationService> _proxyManager;

        public ManagedTokenOrganizationServiceProxy(Uri serviceUri, ClientCredentials userCredentials)
            : base(serviceUri, null, userCredentials, null)
            this._proxyManager = new AutoRefreshSecurityToken<OrganizationServiceProxy, IOrganizationService>(this);

        public ManagedTokenOrganizationServiceProxy(IServiceManagement<IOrganizationService> serviceManagement,
            SecurityTokenResponse securityTokenRes)
            : base(serviceManagement, securityTokenRes)
            this._proxyManager = new AutoRefreshSecurityToken<OrganizationServiceProxy, IOrganizationService>(this);

        public ManagedTokenOrganizationServiceProxy(IServiceManagement<IOrganizationService> serviceManagement,
            ClientCredentials userCredentials)
            : base(serviceManagement, userCredentials)
            this._proxyManager = new AutoRefreshSecurityToken<OrganizationServiceProxy, IOrganizationService>(this);

        protected override void AuthenticateCore()

        protected override void ValidateAuthentication()

    /// Class that wraps acquiring the security token for a service
    /// </summary>

    public sealed class AutoRefreshSecurityToken<TProxy, TService>
        where TProxy : ServiceProxy<TService>
        where TService : class
        private TProxy _proxy;

        /// Instantiates an instance of the proxy class
        /// </summary>

        /// <param name="proxy">Proxy that will be used to authenticate the user</param>
        public AutoRefreshSecurityToken(TProxy proxy)
            if (null == proxy)
                throw new ArgumentNullException("proxy");

            this._proxy = proxy;

        /// Prepares authentication before authenticated
        /// </summary>

        public void PrepareCredentials()
            if (null == this._proxy.ClientCredentials)

            switch (this._proxy.ServiceConfiguration.AuthenticationType)
                case AuthenticationProviderType.ActiveDirectory:
                    this._proxy.ClientCredentials.UserName.UserName = null;
                    this._proxy.ClientCredentials.UserName.Password = null;
                case AuthenticationProviderType.Federation:
                case AuthenticationProviderType.LiveId:
                    this._proxy.ClientCredentials.Windows.ClientCredential = null;

        /// Renews the token (if it is near expiration or has expired)
        /// </summary>

        public void RenewTokenIfRequired()
            if (null != this._proxy.SecurityTokenResponse &&
            DateTime.UtcNow.AddMinutes(15) >= this._proxy.SecurityTokenResponse.Response.Lifetime.Expires)
                catch (CommunicationException)
                    if (null == this._proxy.SecurityTokenResponse ||
                        DateTime.UtcNow >= this._proxy.SecurityTokenResponse.Response.Lifetime.Expires)

                    // Ignore the exception 

now create an instance of ManagedTokenOrganizationServiceProxy instead of OrganizationServiceProxy :

//get the OrganizationService
//OrganizationServiceProxy _serviceproxy = new OrganizationServiceProxy(new Uri(config.XrmOrgServiceProxy), null, clientcred, null);
 ManagedTokenOrganizationServiceProxy _serviceproxy = new ManagedTokenOrganizationServiceProxy(new Uri(config.XrmOrgServiceProxy), clientcred);

Improving Dynamics CRM connection performance with Singleton pattern

Calling Dynamics CRM services is slow process.The authentication process adds the most overhead in establishing a connection to CRM. The call needs to go through multiple steps in order to be authenticated and authorized to access the data in Dynamics CRM.

If you have an application that needs to perform CRUD operation outside of CRM you can leave the connection open to Dynamics CRM with Singleton pattern.

Singleton pattern:

public class XrmConnectionProvider
        private static IOrganizationService instance;
        private static object _lockObject = new object();

		private static IConfigurationService _configurationService;
		private XrmConnectionProvider() { }
        public static IOrganizationService CRMService
                    lock (_lockObject)
                        if (instance == null)
							var container = IoC.Initialize();
							_configurationService = container.GetInstance<IConfigurationService>();

                            instance = Connect();
                        return instance;
                catch (Exception ex)
					throw new Exception("Unable to connect to CRM", ex);

        private static IOrganizationService Connect()
		     //user name and password stored in a config file
			var config = _configurationService.Get<XrmClientConfiguration>();

			Uri dInfo = new Uri(config.XrmUri);
			ClientCredentials clientcred = new ClientCredentials();
			clientcred.UserName.UserName = config.XrmClientCredUserName;
			clientcred.UserName.Password = config.XrmClientCredPassword;

			#region on-premise/online

			DiscoveryServiceProxy dsp = new DiscoveryServiceProxy(dInfo, null, clientcred, null);
            RetrieveOrganizationsRequest rosreq = new Microsoft.Xrm.Sdk.Discovery.RetrieveOrganizationsRequest();
            RetrieveOrganizationsResponse r = (RetrieveOrganizationsResponse)dsp.Execute(rosreq);

            //get the OrganizationService
            OrganizationServiceProxy _serviceproxy = new OrganizationServiceProxy(new Uri(config.XrmOrgServiceProxy), null, clientcred, null);
            //In order to use the generated types when dealing with the organization service, you have to add the ProxyTypesBehavior to the endpoint Behaviors collection. This instructs the OrganizationServiceProxy to look in the assembly for classes with certain attributes to use. The generated classes are already attributed with these attributes. Simply, this makes all interactions with the organization service to be done using the generated typed classes for each entity instead of the generic Entity class we used earlier.
            _serviceproxy.ServiceConfiguration.CurrentServiceEndpoint.EndpointBehaviors.Add(new ProxyTypesBehavior());
            //Do not forget to include _serviceproxy.EnableProxyTypes();. Without this line,you will be unable to use early binding.
            IOrganizationService service = (IOrganizationService)_serviceproxy;

            return service;

Now in your code you can call below class and it will only generate one instance instead of calling it for each request :

 var CRMService= XrmConnectionProvider.Connect();

Here is the result of URL based test on Visual studio online after applying above approach :

The test ran for duration of 120 seconds with 25 users load hitting my Web API application (hosted on azure) retrieving Dynamics CRM contacts.






The only caveat to this method is that you need to monitor your token expiry depending on your implementation method and renew it before expiry.
You can read about it on this blog post.
But before that you need to increase the life time of token if you’ve configured your CRM for IFD.  By default the ADFS token last for 60 minutes. By using Windows PowerShell, you can change the TokenLifetime property for the relying party objects that you created from 60 minutes to a longer period, such as 480 minutes (8 hours).

From MSDN best practices:

Monitor your WCF security token (Token) and refresh it before it expires so that you do not lose the token and have to start over with authentication. To check the token, create a custom class that inherits from the OrganizationServiceProxy or DiscoveryServiceProxy class and that implements the business logic to check the token. Or wrap the proxy classes in a new class. Another technique is to explicitly check the token before each call to the web service. Example code that demonstrates these techniques can be found in the ManagedTokenDiscoveryServiceProxy, ManagedTokenOrganizationServiceProxy, and AutoRefreshSecurityToken classes in the Helper code: ServerConnection class topic.

Get and set user timezone in cookies with jQuery


  1. Find the user timezone from it’s browser default time and then get the confirmation from the user about it’s timezone.
  2. User should be able to select different time zone
  3. Store the timezone in a cookie
  4. Perform the above procedure only if the user is logged in ( identity)


  • Using jQuery check if user is authenticated ( identity)
  • If authenticated check if the timezone cookie is already set
  • If the cookie is not set yet, get confirmation from user about it’s timezone using bootstrap modal and store it in a cookie


Add a bootstrap modal form to your page with timezone drop-down list:

 <div class='modal fade' id='modalTimeZoneApprove' tabindex='-1' role='dialog' aria-labelledby='myModalLabel'>
 <div class='modal-dialog' role='document'>
 <div class='modal-content'>
 <div class='modal-header'>
 <button type='button' class='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>&times;</span></button>
 <h4 class='modal-title'>Approve Your TimeZone</h4>
 <div class='modal-body'>
 <p>Your default time zone is : <span id="spanTimeZone"></span></p>
 <br />
 <p>You can change your timezone: </p>
 <select class="form-control" id="zoneList">
 <option value="-13">--Select--</option>
 <option value="-12">(GMT-12:00) International Date Line West</option>
 <option value="-11">(GMT-11:00) Midway Island, Samoa</option>
 <option value="-10">(GMT-10:00) Hawaii</option>
 <option value="-9">(GMT-09:00) Alaska</option>
 <option value="-8">(GMT-08:00) Pacific Time (US & Canada)</option>
 <option value="-8">(GMT-08:00) Tijuana, Baja California</option>
 <option value="-7">(GMT-07:00) Arizona</option>
 <option value="-7">(GMT-07:00) Chihuahua, La Paz, Mazatlan</option>
 <option value="-7">(GMT-07:00) Mountain Time (US & Canada)</option>
 <option value="-6">(GMT-06:00) Central America</option>
 <option value="-6">(GMT-06:00) Central Time (US & Canada)</option>
 <option value="-6">(GMT-06:00) Guadalajara, Mexico City, Monterrey</option>
 <option value="-6">(GMT-06:00) Saskatchewan</option>
 <option value="-5">(GMT-05:00) Bogota, Lima, Quito, Rio Branco</option>
 <option value="-5">(GMT-05:00) Eastern Time (US & Canada)</option>
 <option value="-5">(GMT-05:00) Indiana (East)</option>
 <option value="-4">(GMT-04:00) Atlantic Time (Canada)</option>
 <option value="-4">(GMT-04:00) Caracas, La Paz</option>
 <option value="-4">(GMT-04:00) Manaus</option>
 <option value="-4">(GMT-04:00) Santiago</option>
 <option value="-3.5">(GMT-03:30) Newfoundland</option>
 <option value="-3">(GMT-03:00) Brasilia</option>
 <option value="-3">(GMT-03:00) Buenos Aires, Georgetown</option>
 <option value="-3">(GMT-03:00) Greenland</option>
 <option value="-3">(GMT-03:00) Montevideo</option>
 <option value="-2">(GMT-02:00) Mid-Atlantic</option>
 <option value="-1">(GMT-01:00) Cape Verde Is.</option>
 <option value="-1">(GMT-01:00) Azores</option>
 <option value="0">(GMT+00:00) Casablanca, Monrovia, Reykjavik</option>
 <option value="0">(GMT+00:00) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London</option>
 <option value="1">(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna</option>
 <option value="1">(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague</option>
 <option value="1">(GMT+01:00) Brussels, Copenhagen, Madrid, Paris</option>
 <option value="1">(GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb</option>
 <option value="1">(GMT+01:00) West Central Africa</option>
 <option value="2">(GMT+02:00) Amman</option>
 <option value="2">(GMT+02:00) Athens, Bucharest, Istanbul</option>
 <option value="2">(GMT+02:00) Beirut</option>
 <option value="2">(GMT+02:00) Cairo</option>
 <option value="2">(GMT+02:00) Harare, Pretoria</option>
 <option value="2">(GMT+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius</option>
 <option value="2">(GMT+02:00) Jerusalem</option>
 <option value="2">(GMT+02:00) Minsk</option>
 <option value="2">(GMT+02:00) Windhoek</option>
 <option value="3">(GMT+03:00) Kuwait, Riyadh, Baghdad</option>
 <option value="3">(GMT+03:00) Moscow, St. Petersburg, Volgograd</option>
 <option value="3">(GMT+03:00) Nairobi</option>
 <option value="3">(GMT+03:00) Tbilisi</option>
 <option value="3.5">(GMT+03:30) Tehran</option>
 <option value="4">(GMT+04:00) Abu Dhabi, Muscat</option>
 <option value="4">(GMT+04:00) Baku</option>
 <option value="4">(GMT+04:00) Yerevan</option>
 <option value="4.5">(GMT+04:30) Kabul</option>
 <option value="5">(GMT+05:00) Yekaterinburg</option>
 <option value="5">(GMT+05:00) Islamabad, Karachi, Tashkent</option>
 <option value="5.5">(GMT+05:30) Sri Jayawardenapura</option>
 <option value="5.5">(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi</option>
 <option value="5.75">(GMT+05:45) Kathmandu</option>
 <option value="6">(GMT+06:00) Almaty, Novosibirsk</option>
 <option value="6">(GMT+06:00) Astana, Dhaka</option>
 <option value="6.5">(GMT+06:30) Yangon (Rangoon)</option>
 <option value="7">(GMT+07:00) Bangkok, Hanoi, Jakarta</option>
 <option value="7">(GMT+07:00) Krasnoyarsk</option>
 <option value="8">(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi</option>
 <option value="8">(GMT+08:00) Kuala Lumpur, Singapore</option>
 <option value="8">(GMT+08:00) Irkutsk, Ulaan Bataar</option>
 <option value="8">(GMT+08:00) Perth</option>
 <option value="8">(GMT+08:00) Taipei</option>
 <option value="9">(GMT+09:00) Osaka, Sapporo, Tokyo</option>
 <option value="9">(GMT+09:00) Seoul</option>
 <option value="9">(GMT+09:00) Yakutsk</option>
 <option value="9.5">(GMT+09:30) Adelaide</option>
 <option value="9.5">(GMT+09:30) Darwin</option>
 <option value="10">(GMT+10:00) Brisbane</option>
 <option value="10">(GMT+10:00) Canberra, Melbourne, Sydney</option>
 <option value="10">(GMT+10:00) Hobart</option>
 <option value="10">(GMT+10:00) Guam, Port Moresby</option>
 <option value="10">(GMT+10:00) Vladivostok</option>
 <option value="11">(GMT+11:00) Magadan, Solomon Is., New Caledonia</option>
 <option value="12">(GMT+12:00) Auckland, Wellington</option>
 <option value="12">(GMT+12:00) Fiji, Kamchatka, Marshall Is.</option>
 <option value="13">(GMT+13:00) Nuku'alofa</option>
 <div class='modal-footer'>
 <button type='button' class='btn btn-primary' id='confirmModalTimeZone'>Confrim</button>
 <button type='button' class='btn btn-default' data-dismiss='modal' id='closeModalApprove'>Cancel</button>

the modal will looks like this:

Now add JavaScript/jQuery methods to set the cookies if the users is authenticated (using Identity)

 function getCookie(cname) {
            var name = cname + "=";
            var decodedCookie = decodeURIComponent(document.cookie);
            var ca = decodedCookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) == ' ') {
                    c = c.substring(1);
                if (c.indexOf(name) == 0) {
                    return c.substring(name.length, c.length);
            return "";

 function setCookie(cname, cvalue, exdays) {
            var d = new Date();
            d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
            var expires = "expires=" + d.toUTCString();
            document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";

 function checkCookie(cname) {
            var cookieName = getCookie(cname);
            if (cookieName != "") {
                alert("Welcome again " + cookieName);
            else {
                cookieName = "GMT  " + get_time_zone_offset();
                if (cookieName != "" && cookieName != null) {
                    setCookie(cname, cookieName, 365); MediaQueryList

  function get_time_zone_offset() {
            var current_date = new Date();
            return -current_date.getTimezoneOffset() / 60;

 $(document).ready(function () {
            var isAuthenticated = '<%=HttpContext.Current.User.Identity.IsAuthenticated %>';
            if (isAuthenticated=="True") {

                var cookieName = getCookie("AccountTimeZone");
                if (cookieName != "") {
                    //do nothing!
                else {
                    cookieName = "GMT  " + get_time_zone_offset();

                $('#zoneList').on('change', function () {
                    $("#spanTimeZone").text($("#zoneList option:selected").text());

                $("#confirmModalTimeZone").click(function () {
                    var zone = $("#spanTimeZone").text();
                    if (zone != "" && zone != null) {
                        setCookie("AccountTimeZone", zone, 365);

Dynamics CRM processes to attach with remote debugger

For debugging plugins and custom workflow activities, attach to these Dynamics CRM processes in visual studio :

  • Online: W3WP.exe
  • Offline: Microsoft.Crm.Application.Hoster.exe
  • Asynchronous registered plug-ins (post operation): CrmAsyncService.exe
  • Custom workflow assemblies: CrmAsyncService.exe
  • Sandbox (isolation mode): Microsoft.Crm.Sandbox.WorkerProcess.exe


Adding a Dynamics CRM Status Reason with custom values

The default status reasons for Dynamics CRM custom entities are 1 for active and 2 for inactive.


It’s not possible to add Status Reason (statuscode) with values less than 551,870,000 through MS Dynamics CRM user interface and added new values are read only and incremental. If the default status reason is somehow deleted or you want to create a status reason with specific values, you can add it using CRM API’s.

Here is an example of adding an active status reason in CRM with value of 1:

(in my case the default active status reason was deleted)

         var response= ((InsertStatusValueResponse)ServiceContext.Execute
                new InsertStatusValueRequest
                     AttributeLogicalName = "statuscode",
                     EntityLogicalName = YourEntity.EntityLogicalName,
                     Label = new Microsoft.Xrm.Sdk.Label("Active", 1033),
                     StateCode = 0, //Status: 0 active & 1 inactive 
                     Value = 1