Get Sql ConnectionString from CRM server code

Sometime, your business logic need access direct SQL Server, and you want to know the ConnectionString of CRM Database.

This code will help you get Sql ConnectionString from CRM Plugin/Custom Action/Custom Workflow (before that I saved the ConnectionString to the custom Options entity)

public void Execute(IServiceProvider serviceProvider)
{
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    var platformContext = context.GetType().InvokeMember("PlatformContext", BindingFlags.GetProperty, null, context, null);
    var transaction = (SqlTransaction)platformContext.GetType().InvokeMember("SqlTransaction", BindingFlags.GetProperty, null, platformContext, null);
    throw new InvalidPluginExecutionException(transaction.Connection.ConnectionString);
}
  • Remember to add reference System.Data.dll to your project

Limitation

  • CRM On-Premises only
  • Plugin/Custom Action/Custom Workflow when register the option Isolation Mode should selected None
  • Access SQL code should out side the Plugin/Custom Action/Custom Workflow pipe line transaction. (E.g: use at Pre-Validation)

Actual project experience

  • Requirement: End user want change exchange rate at the end of month after a lot of records created/locked on this month with current temporary exchange rate.
  • Analysis: You cannot use the SDK code because a lot of records locked by CRM
  • Solution:
    • Create a custom action, get SQL ConnectionString, and then use the ConnectionString to update records
    • Create a custom ribbon button, then call custom action to update data.

Hide Next Stage, Set Active, Back Button in the Business Process Flows

I have a requirement in my current project that hide Next Stage, Set Active and Back button in the Business Process Flows

To do that, I used an UnSupported code code below

function hideBPFButton() {
    hideBPFButtons();
    window.addEventListener("resize", hideBPFButtons);
    Xrm.Page.data.process.addOnStageSelected(hideBPFButtons);
}

function hideBPFButtons() {
    var dom = (Xrm == undefined || Xrm.Internal == undefined || Xrm.Internal.isTurboForm() == undefined || Xrm.Internal.isTurboForm() == false) ? document : parent.document;
    $("#stageSetActiveActionContainer", dom).remove();
    $("#stageBackActionContainer", dom).remove();
    $("#stageNavigateActionContainer", dom).remove();
    setTimeout(function () { $("#processStagesContainer", dom).width(1894); }, 50);
}

In the form OnLoad, call function

hideBPFButton();

Before apply code

Before apply code

After apply code

After apply code

How to code: change stage, set active

  • Client side: check Xrm.Page.data.process and Xrm.Page.ui.process
  • Server side: reference 3 fields: processid, stageid and traversedpath: in the entity record

The following code query processid by Process Name in the entity workflow

[Read More]

Add more buttons on the form subgrid

Sometime, your business requirement need add some buttons in the form sub-grid like picture below (Account form, sub-grid Contacts). Add more buttons

How I can do that

1. Prepare 2 web-resource png image 16x16 file.

  • 1 for normal button
  • 1 for hover button

2. Copy function below to your main js web-resource file.

function createButton(grid, buttonName, buttonTooltip, buttonImage, buttonImageHover, callback) {
    if (grid == null || grid.length == 0) return;
    if (buttonName == null || buttonName.length == 0) return;
    if (buttonImage == null || buttonImage.length == 0) return;
    var dom = (Xrm == undefined || Xrm.Internal == undefined || Xrm.Internal.isTurboForm() == undefined || Xrm.Internal.isTurboForm() == false) ? document : parent.document;
    var button = dom.getElementById(grid + "_addImageButton");
    if (button == null || button.parentNode == null || button.parentNode.parentNode == null) return;
    var tooltip = "";
    if (buttonTooltip != null && buttonTooltip.length > 0)
        tooltip = " title='" + buttonTooltip + "' alt='" + buttonTooltip + "' ";
    var div = dom.createElement("div");
    div.className = "ms-crm-contextButton";
    div.innerHTML = "<a href='#' id='" + buttonName +"' style='display:block;cursor:pointer;'" + tooltip + "><img id='"+ buttonName +"Image' src='" + buttonImage + "'" + tooltip + "></a>";
    button.parentNode.parentNode.appendChild(div);
    if (buttonImageHover != null) {
        dom.getElementById(buttonName).onmouseover = function () {
            dom.getElementById(buttonName + "Image").src = buttonImageHover;
        }
        dom.getElementById(buttonName).onmouseout = function () {
            dom.getElementById(buttonName + "Image").src = buttonImage;
        }
    }
    dom.getElementById(buttonName).onclick = callback;
}

3. On the on-load form, add the following code to add button to form sub-grid.

[Read More]