Wednesday, 23 January 2019

Be careful when you import managed solution and you modify that component

Hi all,

Just a short blog as per current experience.
I know it has been years I never write any post.

So, my current post is just want to explain that should you imported solution as Managed and then something requires you to update.
Does not matter it is just a display name for name, is searchable Advanced Find for a field, a Report Category for a Report, Web Resources modification directly from the Production with Managed solutions.

Please be noted that you are doing wrong thing and there is no way back for CRM Online other than raising ticket which can be rejected as it will make that component becomes 'Unmanaged' and is part of Active or you call it Default Solution.

Well, you can see it is still "Managed" in your Managed solution, but it is actually a Default Solution
It means, your component CANNOT Be DELETED anymore using Holding nor Solution Upgrade or manually you CANNOT Delete. It will remain there.

So, if you have fields you want to delete, dont hide it.
If you have report you want to hide dont hide it.
Dont do that directly in your Managed Solution environment.
Do it in the UNMANAGED Solution and you can use SOLUTION UPGRADE method to delete that component like people posted before.

This what happen the moment you changing something in your report:

The report you modified directly become "Unmanaged" and part of the "Default Solution" as the final layering. You WILL NOT be able to deploy the Managed solution again which has this component.
As there is conflict internally in the database.

So, dont do that.
Always stick in your Development for any modification.
If it is something like Report, sitemap that frequently changing and easy to maintain, it is still the best to keep it Unmanaged so you can modify and delete if you dont like it, all manually but possible.
Well, like entities, changing directly in PROD is not recommended.

Or, you can prevent the customizable

Hope this is useful.

Wednesday, 15 February 2017

Error: "Unable to Login to Dynamics CRMOrganizationWebProxyClient is nullOrganizationWebProxyClient is nullOrganizationServiceProxy is nullOrganizationServiceProxy is null" during connecting to CRM Online using Xrm.Tooling.Connector

It’s been long time I have not written any post.
So, now I just want to share my experience when I have error once trying to connect to the CRM Online using Xrm.Tooling.Connector

Here is there error:

"Unable to Login to Dynamics CRMOrganizationWebProxyClient is nullOrganizationWebProxyClient is nullOrganizationServiceProxy is nullOrganizationServiceProxy is null"

Here is my connection string:

It does seem okay since I am following the example given by SDK:

But I receive that error as it makes me cannot connect to the CRM.

Then, how to solve it?

It is easy, just fix the URL and ensure that’s you have correct Username, password and also AuthType parameter

So, the mistake here is just the URL, change this to your unique organization, not the friendly/display name

*I know it can be misleading because the example is using the display name as same as you use to type your URL when you are trying to access through your browser.

*Change to:

To find the Unique name, please to the Customizations –> Developer Resource and find the unique name of your organization

Hope this helps!
Thank you

Tuesday, 6 September 2016

Utilize Custom Action to Help Filtering The Lookup View in CRM Form


Sometimes in our project, we have requirement to filter lookup based on some conditions and it can be achieved using addCustomView or addCustomFilter function.

And sometimes it is just not too easy to do it in Javascript or the complex fetch xml, so in my blog I just want to share another method to get the filtered result same as you wanted, that is using Javascript + Custom Action!


Following my previous post:

So, considering you have this filter:

To get the result as per expected, you can use Custom Action.


1. You need to create a custom action that give you output, either STRING or ENTITYCOLLECTION

2. Inside the custom action code, if you want to return string, you can use comma delimited concept, or using | as delimiter, or you can just return the Final XML Filter already.

If you use EntityCollection, you might need to parse it again.

3. Then create a javascript that can call the Custom Action, you can use this method for easy way:

4. Then you get the result as parameter, you can just set it to the filter = “the Result” (if you use Final XML Filter as the Output) or you parse the GUID if you use the comma or | delimited concept, or if you use EntityCollection then you need to parse it back.

5. See the result

Basically, you just need to get this result:


Either you just easily using String as output or other method it is up to u.

But the point here is we can use Custom Action for solving complex filtering and remember that we can use impersonation also to get the data you want if it is related to the other entities as well, imagine if we also need to have multiple entities involved then it might be easier if we use Custom Action as we just replace the DLL if there is any other changes using Plugin Registration Tool.

Hope this helps!


Modify the Delete (Dustbin icon) Button in the CRM Subgrid


Sometimes we need to modify the Delete button in the CRM Subgrid, example:

1. For preventing users to perform the delete button (but you dont want to just disable it)

2. Call another function or call custom function that needs client site programming (We can do plugin onDelete or onAssociate, but in case you want to show it in the client site)

3. To do impersonation

The Code

function modifyRibbon() {
    modifySubgridDeleteButtonEventHandler("subgrid_name_in_the_form", deleteSubgridRecord, true);

function deleteSubgridRecord() {

function modifySubgridDeleteButtonEventHandler(subgridName, functionToCall, passGridControl) {
    try {
        //to store the original function ones
        var originalFunctionDeleteRecordSubgrid = Mscrm.GridCommandActions.deleteRecords;
        //add new standard subgrid
        Mscrm.GridCommandActions.deleteRecords = function (selectedControl, selectedControlSelectedItemReferences, selectedEntityTypeCode) {
            //if (typeof (gridControl.get_id).toString().toLowerCase() == "undefined") {} //no need since I replaced by the previous line
            if (selectedControl.get_id() != subgridName) {
                originalFunctionDeleteRecordSubgrid(selectedControl, selectedControlSelectedItemReferences, selectedEntityTypeCode);
            else {
                if (passGridControl) {
                else {
    catch (e) {



*After clicking the ‘Delete’ button


Note: This method is overwriting the CRM functions and it works for CRM 2013, for CRM 2015/2016, this function [Mscrm.GridCommandActions.deleteRecords] might have been changed, so need to find out the current function name based on your CRM Version. And again, it means it is unsupported Smile


Wednesday, 17 August 2016

Insert Label After the Field in CRM Form using Javascript

Hi all,
Long time I did not blog any post due to workload.
And this is my first post in this month (I know it is end of the month already)
This post basically a quick one because I have the requirement.

So, the users just want to have guidance when they entering inputs in the system.

Which we can have these solutions:

1. Tooltip (using CRM Field description)

See my post here:

2. Using HTML Web Resource

This is a supported way and very useful as well. But it will make the form slower because will load the web resource and how many web resource you should create and insert. Well, you can create 1 common .html then pass the label text as the parameter

3. Using other way

So, unfortunately if those 2 solutions still not the best choice, we could go to another way using the help of CSS and Javascript.

*This is unsupported way…

And here is the Code

The Code

function insertLabelToField(fieldname, text, objSpan) {
    var elemDiv = document.getElementById(fieldname + "_c");
    //var tbl = document.createElement('table');     //elemDiv.parentNode.insertBefore(tbl, elemDiv.nextSibling);
    //var tr = tbl.insertRow();     //var td1 = tr.insertCell();     //td1.appendChild(elemDiv);     var td1 = elemDiv;     // = "2px solid #c1c7c4"; = "5.5px";
    var spanPref = null;
    if (!objSpan) {         spanPref = document.createElement('span');                 //you can change the color condition here         if (attr(fieldname).getRequiredLevel() == "required") {    = '#e31a1a';         }         else {    = '#4b4c54';         } = '10.51px'; = 'italic';     }     else {         spanPref = objSpan;     } = 'spanPref_' + fieldname;         td1.appendChild(spanPref);     document.getElementById('spanPref_' + fieldname).innerText = text; }

How to Call

insertLabelToField(“fieldname”, "(Please describe me)");

And here is the Result


Hope this helps.


Wednesday, 10 August 2016

Modify Subgrid Ribbon Behaviour Using Form Script


A Quick post, just want to post how to Modify Subgrid button behaviour to always “Create New child record”, instead of “Add Existing record”.

This will use the similar method like described in the previous post before, but it does not call the custom funtion, it just will “redirect” the function to your “Create new record”.

Note: This is an unsupported way, for the supported way you can do two things:

1. Make the parent lookup field name to ‘Required’
2. Modify the Ribbon of the subgrid and Hide the ‘Add Existing’ button
*For your reference – > Nice post by Gareth:

But, those will apply to the subgrid regardless the Condition, probably for the second method, you could apply some Enable/Display Rule on the subgrid ribbon.

But, if you want to do it only for specific entity and based on Parent Form condition (can be based on parent fields or even other entity values), then there is another way to do this that I will put the code in this post.

The Code

Ok, so back to the code.

Here is the code:
//function to insist create new record form instead of Add Existing
function openNewRecordFormFromSubgridButton(subgridName, passGridControl) {
    try {
        //to store the original function ones
        var originalFunctionAddNewStandard = Mscrm.GridRibbonActions.addNewFromSubGridStandard;
        var originalFunctionAddExistingStandard = Mscrm.GridRibbonActions.addExistingFromSubGridStandard;
        var originalFunctionAssociated = Mscrm.GridRibbonActions.addExistingFromSubGridAssociated;

        var primaryControl = document.getElementById('crmForm');
        var parentEntityId =;
        var parentEntityTypeCode =;

        //add existing standard subgrid
        Mscrm.GridRibbonActions.addExistingFromSubGridStandard = function (gridTypeCode, gridControl) {
            if (gridControl.get_id() != subgridName) {
                originalFunctionAddExistingStandard(gridTypeCode, gridControl);
            else {
                var primaryControl = document.getElementById('crmForm');
                originalFunctionAddNewStandard(gridTypeCode, parentEntityTypeCode, parentEntityId, null, gridControl);
        //and even possible for the N:N (but this is a rare scenario)
        //add associate subgrid (N:N)
        Mscrm.GridRibbonActions.addExistingFromSubGridAssociated = function (gridTypeCode, gridControl) {
            if (gridControl.get_id() != subgridName) {
                originalFunctionAssociated(gridTypeCode, gridControl);
            else {
                var primaryControl = document.getElementById('crmForm');
                originalFunctionAddNewStandard(gridTypeCode, parentEntityTypeCode, parentEntityId, null, gridControl);
    catch (e) {


How to call:

openNewRecordFormFromSubgridButton("mysubgrid_name", true);


As we can see it opens lookup to look to the Existing record, it is 1:N, the record is almost possible already linked to another record, so it will make the users confused when they open this lookup.

*And I never set any Required field to the parent lookup value, because this field is NOT always mandatory field, so it is conditional only.

Note: Use this method if you want to control the subgrid plus button based on some conditions and using the Form on Load script (easier), and it only works for the subgrid inside the form that load the function, other subgrid from another parent entity that does not have this function will not be affected, that is the advantage of using this method, to only affect subgrid of the child based on some parent entities and the function will be placed in the Parent Entity Form OnLoad and this is unsupported way.

“This is for dynamically control the subgrid behaviour through parent form onload functions based on some conditions logic, especially for 1:N relationship that usually already linked to another parent record, so that it is supposed to insist to open new Form, instead of asking the user to choose another existing record.

Hope this helps!


Tuesday, 31 May 2016

Modify CRM View Query or Filter Criteria on Demand Dynamically using Plugin Retrieve

Hi guys,

Just want to share how we can modify the View Filter Criteria/Condition dynamically.


Recently I have requirement that I need to create a View in CRM that there is no way to construct it from Advanced Find and make it dynamic.

For example,
I need to have query that:
1. The Date parameter is must be changed accodingly based on the today date and
2. Another parameter must get the value from a Configuration Entity
Ok, for number 1, we can force the users to always go to the View and change the date accordingly, but how about number 2?

So, my use case:

Show me the list of Customers that due date is in the next 21 days?
Meanwhile, 21 here is must be dynamically obtained from another Configuration entity.

So, this is nearly impossible, because even we use Advanced Find there is no way to use variable as parameter in the filter criteria that we need to query from another entity that is NOT related at all!
As we know that Advanced Find Query, only has limited operator and also it cannot Query from another entity, only limited to the related entities.

Use Case

So, to go to the code, I need to tell the scenario first, and to make it simpler, I just use this use Case:
I want to get all Active Customers that birthday is this Month.

This month is May for example.
So, I have a custom field = Birthday Month

Which I have auto-populated this field before with the Date Birth component (in another plugin).
So, now I need to always update the View to always Query to the:

Status = Active and Birthday Month = 5

And for the Next Month (June) should be:
Status = Active and Birthday Month = 6

Which last Month for April
Status = Active and Birthday Month = 4

Those number 5, 6, and 4 are supposed to be generated dynamically.

And I can’t use the This-Month operator because I dont have May 2016 Data, since I save the DOB, not updating every customer BOD every year plus 1 year.

You can also add another requirement, such as must be a Member Customer with Annual Income more than X, which X is you taken from Configuration entity.

What you need is just a new fetch XML or Query Expression that you can just convert use this request!

QueryExpressionToFetchXmlRequest req = new QueryExpressionToFetchXmlRequest();
req.Query = qenew;
QueryExpressionToFetchXmlResponse resp = (QueryExpressionToFetchXmlResponse)service.Execute(req);

But, for this use case, my point is jut to point out to you how to modify the Query just as per you wish (sorry as per Users’ whish Smile)

The Current View


So, for the post here, I just need to replace the Query from the Existing View (in your case, you might need to create a new View)


Then I got the savedqueryid from this view

The Code

public void Execute(IServiceProvider serviceProvider)

            #region must have

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            // Create service with context of current user
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            //create tracing service
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));


            if (context.OutputParameters.Contains("BusinessEntity"))
                var retrievedResult = (Entity)context.OutputParameters["BusinessEntity"];
                Entity entity = retrievedResult;
                string fetch = string.Empty;

                //the below GUID, you can do advance query to make this as non-hardcoded one, you can find by name as well, for example
                //just for my use case here, I post here as final GUID of the 'Active Customer' view GUID
                //in ACTUAL case, do not use harcoded one because it will change in different environment unless for Out of The Box Entities View
                if ((Guid)entity["savedqueryid"] == new Guid("00000000-0000-0000-00AA-000010001004")) 
                    QueryExpression qenew = new QueryExpression("contact");

                    ConditionExpression activeCon = new ConditionExpression()
                        AttributeName = "statecode",
                        Operator = ConditionOperator.Equal,
                        Values = { 1 }

                    int currentMonth = DateTime.Now.Month; //this is the variable that dynamically you need to insert in

                    ConditionExpression birthdayCon = new ConditionExpression()
                        AttributeName = "ags_birthdaymonth",
                        Operator = ConditionOperator.Equal,
                        Values = { currentMonth }


                    //for easy fetch XML I use the Query Expression then convert to FetchXML
                    //but you can always use the directly generated fetchXML and also can get from Advanced Find as well
                    QueryExpressionToFetchXmlRequest req = new QueryExpressionToFetchXmlRequest();
                    req.Query = qenew;
                    QueryExpressionToFetchXmlResponse resp = (QueryExpressionToFetchXmlResponse)service.Execute(req);

                    //work with newly formed fetch string
                    string myfetch = resp.FetchXml;

                    //change the existing
                    entity["name"] = "Active Customer Birthday this Month"; 
                    entity["fetchxml"] = myfetch;

Code Explanation

*For the GUID of savedqueryid section, I got the ID and I implement in my code


*In your case, you need to do query, do not hardcode, please see my comment in the code as well.
For the Query Expresison, this is the place for you to change the logic as per your current requirement


Then for the Fetch XML


As the title mentioned, Then you need to register as POST event for RETRIEVE message, entity = savedquery.
Refresh the Advanced Find or View to see the result.


As we can see that now, the Active Customer View (The View that we just now changed the fetchXML dynamically), now has this Query


You can also try to tweak your code, by just add additional conditional over the existing view by retrieving the fetch xml

string baseFetchXML = enSavedQuery["fetchxml"].ToString();

Then use this request to convert to Query Expression easily


Example of what I Did:

Remember, you can also add another Parameters.

So use this method for Querying:
1. Query that different from the static query from the View
2. Query that requires dynamic Date/Datetime variables
3. Query that needs condition obtained from another non-related entity
4. Query with variable from another Entity, let’s say Configuration Entity
5. Another Impossible Query using standard static Advanced Find
6. Also can do query that involving Current User, Security Role, or Team Query
7. Query requires Operator like “Does-Not-Equal Today” then you can utilize the “ON-OR-BEFORE” or “ON-ON-AFTER”
8. Query for “NOT IN”, then this one you can utilize the “DOES NOT EQUAL” function

But remember, you still need to use  FetchXML in the End.

Hope this helps!