Friday, 6 October 2017

WCF service

CRM connector code
to get CRM service
 public IOrganizationService GetOrgInstance()

        {

            ClientCredentials cre = new ClientCredentials();

              cre.UserName.UserName = "username";
             cre.UserName.Password = "pwd";


            Uri serviceUri = new Uri("organization service");

            Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy proxy = new Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy(serviceUri, null, cre, null);

            proxy.EnableProxyTypes();

            Microsoft.Xrm.Sdk.IOrganizationService service = (Microsoft.Xrm.Sdk.IOrganizationService)proxy;


            return service;

        }


discovery service code

 public void Run(ServerConnection.Configuration serverConfig, bool promptforDelete)
        {
            try
            {
                // Connect to the Discovery service. 
                // The using statement assures that the service proxy will be properly disposed.
                using (_serviceProxy = new DiscoveryServiceProxy(serverConfig.DiscoveryUri,
                                                                    serverConfig.HomeRealmUri,
                                                                    serverConfig.Credentials,
                                                                    serverConfig.DeviceCredentials))
                {
                    // You can choose to use the interface instead of the proxy.
                    IDiscoveryService service = _serviceProxy;

                    #region RetrieveOrganizations Message

                    // Retrieve details about all organizations discoverable via the
                    // Discovery service.
                    RetrieveOrganizationsRequest orgsRequest =
                        new RetrieveOrganizationsRequest()
                        {
                            AccessType = EndpointAccessType.Default,
                            Release = OrganizationRelease.Current
                        };
                    RetrieveOrganizationsResponse organizations =
                        (RetrieveOrganizationsResponse)service.Execute(orgsRequest);

                    // Print each organization's friendly name, unique name and URLs
                    // for each of its endpoints.
                    Console.WriteLine();
                    Console.WriteLine("Retrieving details of each organization:");
                    foreach (OrganizationDetail organization in organizations.Details)
                    {
                        Console.WriteLine("Organization Name: {0}", organization.FriendlyName);
                        Console.WriteLine("Unique Name: {0}", organization.UniqueName);
                        Console.WriteLine("Endpoints:");
                        foreach (var endpoint in organization.Endpoints)
                        {
                            Console.WriteLine("  Name: {0}", endpoint.Key);
                            Console.WriteLine("  URL: {0}", endpoint.Value);
                        }
                    }
                    Console.WriteLine("End of listing");
                    Console.WriteLine();

                    #endregion RetrieveOrganizations Message

                    #region RetrieveOrganization Message

                    // Retrieve details about a single organization discoverable via the Discovery service.
                    //
                    RetrieveOrganizationRequest orgRequest =
                        new RetrieveOrganizationRequest()
                        {
                            UniqueName = organizations.Details[organizations.Details.Count -1].UniqueName,
                            AccessType = EndpointAccessType.Default,
                            Release = OrganizationRelease.Current
                        };
                    RetrieveOrganizationResponse org =
                        (RetrieveOrganizationResponse)service.Execute(orgRequest);

                    // Print the organization's friendly name, unique name and URLs
                    // for each of its endpoints.
                    Console.WriteLine();
                    Console.WriteLine("Retrieving details of specific organization:");
                    Console.WriteLine("Organization Name: {0}", org.Detail.FriendlyName);
                    Console.WriteLine("Unique Name: {0}", org.Detail.UniqueName);
                    Console.WriteLine("Endpoints:");
                    foreach (KeyValuePair<EndpointType, string> endpoint in org.Detail.Endpoints)
                    {
                        Console.WriteLine("  Name: {0}", endpoint.Key);
                        Console.WriteLine("  URL: {0}", endpoint.Value);
                    }
                    Console.WriteLine("End of listing");
                    Console.WriteLine();

                    #endregion RetrieveOrganization Message

                }
            }

            // Catch any service fault exceptions that Microsoft Dynamics CRM throws.
            catch (FaultException<Microsoft.Xrm.Sdk.DiscoveryServiceFault>)
            {
                // You can handle an exception here or pass it back to the calling method.
                throw;
            }
        }

Thursday, 5 October 2017

Code for secure/unsecured configuration

Unsecured Configuration
  • is viewable by any CRM user
  • will automatically move between environments with your CRM solutions.
  • Available when Plugin is Registered for Outlook Offline Mode

Secured Configuration
  • is only viewable by CRM Administrators
XML code for configuration block:
    <Settings>
          <setting name="TracingEnabled">
            <value>true</value>
          </setting>
    </Settings>

Code to extract value from XML document
     class PluginConfiguration
    {
        private static string GetValueNode(XmlDocument doc, string key)
        {
            XmlNode node = doc.SelectSingleNode(String.Format("Settings/setting[@name='{0}']", key));

            if (node != null)
            {
                return node.SelectSingleNode("value").InnerText;
            }
            return string.Empty;
        }

        public static Guid GetConfigDataGuid(XmlDocument doc, string label)
        {
            string tempString = GetValueNode(doc, label);

            if (tempString != string.Empty)
            {
                return new Guid(tempString);
            }
            return Guid.Empty;
        }

        public static bool GetConfigDataBool(XmlDocument doc, string label)
        {
            bool retVar;

            if (bool.TryParse(GetValueNode(doc, label), out retVar))
            {
                return retVar;
            }
            else
            {
                return false;
            }
        }

        public static int GetConfigDataInt(XmlDocument doc, string label)
        {
            int retVar;

            if (int.TryParse(GetValueNode(doc, label), out retVar))
            {
                return retVar;
            }
            else
            {
                return -1;
            }
        }

        public static string GetConfigDataString(XmlDocument doc, string label)
        {
            return GetValueNode(doc, label);
        }
    }

Plugin code to retrieve config data
    public TracingPluginSimple(string unsecureString, string secureString)
        {
            if (!String.IsNullOrWhiteSpace(unsecureString))
            {
                try
                {
                    _unsecureString = unsecureString;
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(_unsecureString);

                    bool TracingEnabled = PluginConfiguration.GetConfigDataBool(doc, "TracingEnabled");

                    _unsecureString = unsecureString;
                    //_secureString = secureString;
                    _tracingEnabled = TracingEnabled;
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("Unsecure or secure strings are required by the TracingPluginSimple Plug-in, but not provided.");
                }
            }
            if (!String.IsNullOrWhiteSpace(secureString))
            {
                try
                {
                    _secureString = secureString;
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(unsecureString);

                    bool TracingEnabled = PluginConfiguration.GetConfigDataBool(doc, "TracingEnabled");

                    //_unsecureString = unsecureString;
                    _secureString = secureString;
                    _tracingEnabled = TracingEnabled;
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("Unsecure or secure strings are required by the TracingPluginSimple Plug-in, but not provided.");
                }
            }
         
        public void Execute(IServiceProvider serviceProvider)
        {
            if (_tracingEnabled)
            {
                //Implement functionality
             }
      }

Shared Variable code

The message pipeline model for Microsoft Dynamics 365 defines a parameter collection of custom data values in the execution context that is passed through the pipeline and shared among registered plug-ins, even from different 3rd party developers. This collection of data can be used by different plug-ins to communicate information between plug-ins and enable chain processing where data processed by one plug-in can be processed by the next plug-in in the sequence and so on. This feature is especially useful in pricing engine scenarios where multiple pricing plug-ins pass data between one another to calculate the total price for a sales order or invoice. Another potential use for this feature is to communicate information between a plug-in registered for a pre-event and a plug-in registered for a post-event.
The name of the parameter that is used for passing information between plug-ins is SharedVariables. This is
 a collection of key\value pairs. At run time, plug-ins can add, read, or modify properties in the SharedVariables
 collection. This provides a method of information communication among plug-ins
 public class PreEventPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the execution context from the service provider.
            Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

            // Create or retrieve some data that will be needed by the post event
            // plug-in. You could run a query, create an entity, or perform a calculation.
            //In this sample, the data to be passed to the post plug-in is
            // represented by a GUID.
            Guid contact = new Guid("{74882D5C-381A-4863-A5B9-B8604615C2D0}");

            // Pass the data to the post event plug-in in an execution context shared
            // variable named PrimaryContact.
            context.SharedVariables.Add("PrimaryContact", (Object)contact.ToString());
        }
    }

    public class PostEventPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the execution context from the service provider.
            Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

            // Obtain the contact from the execution context shared variables.
            if (context.SharedVariables.Contains("PrimaryContact"))
            {
                Guid contact =
                    new Guid((string)context.SharedVariables["PrimaryContact"]);

                // Do something with the contact.
            }
        }
    }

form scripts to disable the auto-save behaviors on a form level

function preventAutoSave(econtext) {
    var eventArgs = econtext.getEventArgs();
    if (eventArgs.getSaveMode() == 70) {
        eventArgs.preventDefault();
    }
}

Have you ever faced an issue where you need to import some record without changing GUID of the record? For example if we need to migr...