Friday, November 9, 2018

Quick Tricks

Merge multiple solutions into one
Steps:
-Create the solution which should contain the merged set of components.
-Considering and example - where i have "solution1", "solution2" and "solution3" as the schema names of the solutions to merge into one destination solution - "solutionfinal"
-Export "solution2", unzip,open the Solution Xml and update the UniqueName property from "solution2" to "solution1".
Zip the updated solution xml with rest of the export file components.
Import the above file back to CRM.
This would merge the components of the solution2 into solution1.
The Display name of solution1 would have now changed to that of solution2, update it back as needed.

Export "solution3", unzip,open the Solution Xml and update the UniqueName property from "solution3" to "solution1".
Zip the updated solution xml with rest of the export file components.
Import the above file back to CRM.
This would merge the components of the solution3 into solution1.
The Display name of solution1 would have now changed to that of solution3, update it back as needed.

You'are done!

The approach leverages the fact that the solution Components are additive upon Import.




 

Thursday, May 10, 2018

Use the View data in the Chart- html Javascript for further processing

 function getParametersFromQuery(query) {

            var parametersDictionary = new Array();

            var parameters = query.split('&');

            for (var i = 0; i < parameters.length; i++) {

                var keyAndValue = parameters[i].split('=');

                parametersDictionary[unescape(keyAndValue[0])] = unescape(keyAndValue[1]);

            }

            return parametersDictionary;

        }
 function loadChartFromCrm(callback) {
           
            var parameters = getParametersFromQuery(window.location.search.substring(1));
            entityName = parameters["typename"];
            parameters = getParametersFromQuery(parameters["data"]);

            var id = parameters["visid"].substr(1, 36);
            var viewId = parameters["viewid"].substr(1, 36);
            var type = parameters["vistype"];
        }
The above retrieved View Id  can be used to retrieve the FetchXml of the view- field Name- "FetchXml" to retrieve the View fetchXml, which in turn can be directly used as the fetch query to retrieve the data corresponding to the View, which can be used for further processing in scenarios like placing Push pins on Bing Map for All the Accounts in NYC / Highlighting the locations where Contacts exist etc.

Sample RemoveFromQueueRequest - Dynamics 365


public void removeRecordFromQueue(Guid entId, IOrganizationService service)
{

    string queueItemQuery = @"<fetch distinct='false' mapping='logical' output-format='xml-platform' version='1.0'>
                        <entity name='queueitem'>
                            <attribute name='queueitemid' />
                            <filter type='and'>
                                   <condition attribute='objectid' value='{0}' operator='eq'/>
                            </filter>
                          </entity>
                        </fetch>";

    queueItemQuery = string.Format(queueItemQuery, entId.ToString());

    EntityCollection returnEntityCollection = service.RetrieveMultiple(new FetchExpression(queueItemQuery));

    foreach (var returnEntity in returnEntityCollection.Entities)
    {       
        RemoveFromQueueRequest removeFromQueueRequest = new RemoveFromQueueRequest
        {
            QueueItemId = returnEntity.Id
        };
        service.Execute(removeFromQueueRequest);
    }
}

Sample Dynamics 365 CRM- Web API Call

 In the below example, "abc_vehicles" is the Plural name of the Entity data being retrieved, scs_name (Filter has been applied on this)and scs_value(This is the field being retrieved) are fields on this entity.

function sampleWebAPIRetrieve{
var vehName = "Honda";
    var vehValue = "";
   var  orCriteria += "scs_name eq '" + vehName + "'";
    var req = new XMLHttpRequest();
    //Added for single service call start
    var reqString = Xrm.Page.context.getClientUrl() + "/api/data/v8.0/abc_vehicles?$select=scs_values&$filter=" + orCriteria;
    req.open("GET", reqString, false);
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.setRequestHeader("Prefer", "odata.include-annotations=\"OData.Community.Display.V1.FormattedValue\"");

    req.send();

    var results = JSON.parse(req.response);

    if (results.value.length > 0) {

        for (var i = 0; i < results.value.length; i++) {
            vehValue += results.value[i]["scs_values"] + ";";
        }
    }
}

The query can be easily built using CRM Rest Builder.

Using the $expand, the Fields(except lookup field) can be retrieved from the record referred in the Lookup field.

Tuesday, May 8, 2018

Troubleshooting the Issues in CRM

Plugin Action not returning any Output Parameter
One of the causes for this issue is - Registration of the Plugin action in PreValidation stage.

BPF Fields Read-Only, without Lock symbol
BPF Fields are disabled by programmatically through JS Code/ through Business Rules,
but in some cases, we have seen that fields wouldn't be editable, though no Script/BR applied.

One such scenarios is - In a Multi- Entity BPF, the specific fields of a stage corresponding to an Entity could be disabled, One of the Reasons is:
If the Field Schema names for multiple entities used in any stage in the BPF are same,
then the stage which appears later would have the fields disabled.
Solution would be - to re-create those fields of any one entity of those, so that the schema names are different from teh other entity.


Error during solution Export-Query Build Error: The specified field does not exist in Microsoft Dynamics 365
Issue Can be resolved by removing the Invalid Component from the solution.
run the below code in using the Code Now in XrmToolBox.

/********************
Include below namespaces in the <Using> section of Code Now
using System;
using System.Xml;
using System.Text;
using System.IO;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Crm.Sdk.Messages;
********************/       
 public static void CodeNow()
        {
            string SOLUTION_NAME = "PUT_YOUR_SOLUTION_NAME_HERE";
            
            LogMessage("------------- Start -----------------");
            LogMessage("Solution " + SOLUTION_NAME);

            var solutionComponentQuery = new QueryExpression("solutioncomponent");
            solutionComponentQuery.Distinct = true;
            solutionComponentQuery.ColumnSet.AddColumns("objectid", "componenttype", "solutioncomponentid");
            var solutioncomponentSolutionLink = solutionComponentQuery.AddLink("solution", "solutionid", "solutionid");
            solutioncomponentSolutionLink.EntityAlias = "aa";
            solutioncomponentSolutionLink.LinkCriteria.AddCondition("uniquename", ConditionOperator.Equal, SOLUTION_NAME);

            var results = Service.RetrieveMultiple(solutionComponentQuery);
            foreach (var item in results.Entities)
            {
                
                var componentType = item.GetAttributeValue<OptionSetValue>("componenttype").Value;
                //LogMessage("Checking Component " + componentType);
                if (componentType == 2)
                {
                    //LogMessage("Checking Attribute");
                    var attributeRequest = new RetrieveAttributeRequest
                    {
                        MetadataId = item.GetAttributeValue<Guid>("objectid")
                    };

                    try
                    {
                        var result = (RetrieveAttributeResponse)Service.Execute(attributeRequest);
                        LogMessage("Attribute " + result.AttributeMetadata.LogicalName + " is valid");
                    }
                    catch
                    {
                        // //attribute is missing, remove it from solution
                        LogMessage("Attribute {" + attributeRequest.MetadataId + "} is missing. Removing from the solution.");
                        
                        var removeRequest = new RemoveSolutionComponentRequest
                        {
                            SolutionUniqueName = SOLUTION_NAME,
                            ComponentId = attributeRequest.MetadataId,
                            ComponentType = componentType
                        };
                        Service.Execute(removeRequest);
                    }
                }
            }
            LogMessage("----------------------DONE-------------------");
        }
References:https://community.dynamics.com/crm/f/117/t/236469

Unable to debug and ILMerged Plugin
Though there doesn't seem to be any possible way to debug an ILMerged plugin solution through Plugin Profiler, We can get the the Plugin trace log after every execution, by
-First Turning the Plugin Tracing for teh organinzation
-Then starting Profiler, with "Persist to Entity" option.

After having done this, every execution of the plugin would generate a log, available for us to view  in the Plugin Trace Logs view.
By adding appropriate tracing statements in our Plugin code, we will be able to get the information needed.

Error with Plugins: Assembly couldn’t be loaded  / SecurityException: Assembly does not allow partially trusted callers.
 Solution: Use ILMerge- install MSBuildILMerge on Solution , check true for Copy as Local against all assemblies that need to  be loaded and others false, then build and deploy the assembly.



Error in the Plugin Registration Tool: Plugin Doesn’t contain required types
Solution- some of the registered Class would be missing in the solution used to updated the Assembly. Add, rebuild and then update the Assembly.

Issue editing Workflows :Fields in Workflow editor are disabled while trying to update/ create a record.
Solution-The Workflow step (Update/Create)fields edit-ability is based on the Last Opened form for the entity for which Workflow is built, hence open a record of the entity and switch to a form in which these fields are editable, then open the Workflow editor.

Issue with Report: Redundant Spaces , Report not displayed properly.
Solution-The Report width property should not exceed the Report Body width, also taking into consideration- the Margins.

Complex requirement in Report: Lookup function based on multiple fields
Solution-Use Calculated Field in Data set which would be concatenation of the fiels to be mapped in the Lookup function.
Considering an example Report where there are 2 Data sets- DS1(Parent with Fields: PGuid,
Role, Duty) and DS2(Child  with Fields: PGuid, Role, Subduties), and we need to get the rows from DS2 where the 2 fields PGuid and Role match those of DS1, We can include a calculated field- say CF in DS1 an DS2 (The Field name should be same in the Parent and the child/Source and destination)which is a concatenation of PGuid and Role, and use this field for Lookup.

Error in Report :If Else calculated together, as a result Error occurring
Solution- In the If Else, make sure the erring part is outside iif.
Example:
Consider the expression - =IIF(IsNothing(Fields!ReIdValue.Value.ToString()),&Fields!strNo.Value.ToString(),Fields!ReIdValue.Value.ToString()&Fields!strNo.Value.ToString())
The inclusion of strNo within the IIF resulted in error when ever it had no Value, hence modifying it as below resolved the issue
=IIF(IsNothing(Fields!ReIdValue.Value),"NA",Fields!ReIdValue.Value).ToString()&Fields!strNo.Value.ToString()

Report not getting uploaded- VS 2015
Solution-Open the Report Project, Property--> Configuration. Change the Target Server Version to SQL Server 2008 R2,2012 or 2014.
Reference http://dynamicscrmcoe.com/report-upload-issue-visual-studio-2015/

Portal  Error- Internal Service Error
(One of)Solution - Check the Data which the Page is trying to display. It could be that multiple levels of hierarchical data loading would be making the load slow, as it multiple steps -
Load CRM Data an filter-> Apply Portal Filters->Check for the web roles of Logged in User->Check Permissions associated with the Web Role -> Display the data along with any hierarchical data to show, probably resulting in Time Out causing the issue.Hence data needs to be limited using filters to avoid this issue


Solution update issues-Dependency issues, for the field removed from the customization xml through manual editing of exported solution file.
Solution - Open Solution xml,
Search for "Missing dependencies" node, remove corresponding dependency  xml component, then import the solution