Why the Data structure HashSet can be Saviour at times?

Hi Folks,

Thank you for vising my blog today…I believe many of the Consultants or Power Platform professionals out there didn’t know about the HashSet available in .Net since version 3.5.

By the way, what is HashSet..here is a brief about it?

HashSet is a data structure which we mightn’t have come across, neither me until implementing one of my requirements. It offers several benefits compared to other data structures for specific use cases. HashSet is preferred and advantageous, here is a use case where HashSet can be useful than other Data Structures available…followed by Advantages and disadvantages.

Scenario: I have a requirement where I need to send an email to the owners of the record using Custom workflow when record is updated, I see many numbers of records are having same owner and hence same email addresses are being added to the To activity party which I want to prevent, it is then, I searched and found of this HashSet.

using System.Collections.Generic;
HashSet<Guid> uniqueGuids = new HashSet<Guid>();
Guid guidToAdd = Guid.Empty;
guidToAdd = ecellorsdemo.GetAttributeValue<EntityReference>("ecellors_ownerid").Id;
if (!uniqueGuids.Contains(guidToAdd))
{
uniqueGuids.Add(guidToAdd);
ToParty["partyid"] = new EntityReference(EntityConstants.SystemUser, guidToAdd); // Set the partyid
ToPartyCol.Entities.Add(ToParty);
}
view raw HashSetDemo.cs hosted with ❤ by GitHub

In this way, you can get the owner of the record and add to the HashSet as shown above in the diagram. Also Hash Set can help prevent adding duplicate records making it an ideal way to deal in certain scenarios.

Advantages:

  1. Fast Lookup: It is efficient for tasks that involve frequent lookups, such as membership checks.
  2. Uniqueness: All elements are unique. It automatically handles duplicates and maintains a collection of distinct values. This is useful when you need to eliminate duplicates from a collection.
  3. No Order: It does not maintain any specific order of elements. If the order of elements doesn’t matter for your use case, using a HashSet can be more efficient than other data structures like lists or arrays, which need to maintain a specific order.
  4. Set Operations: It supports set operations like union, intersection, and difference efficiently and beneficial when you need to compare or combine sets of data, as it can help avoid nested loops and improve performance.
  5. Hashing: It relies on hashing to store and retrieve elements. Hashing allows for quick data access and is suitable for applications where fast data retrieval is crucial.
  6. Scalability: It typically scales well with a large number of elements, as long as the hash function is well-distributed, and collisions are minimal.

Limitations include:

  1. Lack of order: It you need to maintain the order of elements, then this is a good candidate for your implementation.
  2. Space usage: It is memory intensive and is not recommended when memory optimization is being considered.
  3. Limited Metadata: It primarily stores keys (or elements), which means you have limited access to associated metadata or values. If you need to associate additional data with keys, you might consider other data structures like HashMap or custom classes.

I hope this gives an overview on using HashSet…however you can’t use Hash Set in all scenarios, it actually depends on your use case, please check the disadvantages too before using it… if you have any questions, don’t hesitate to ask…

Thank you and keep rocking…

Cheers,

PMDY

Plugin Error – Security accessibility of the overriding method must match the security accessibility of the method being overridden – Quick Fix

Hi Folks,

I recently came across the above error for one of my Dynamics 365 Plugins…this blog talks about applying a quick fix.

While debugging our Plugin logic line by line to understand why it’s not working, observed this error for messages like RetrieveMultiple, Retrieve when I use any Organization Service call.

This was a .Net version downgrade issue caused by ILMerge as I downgraded one of the DLL to 4.6.2 version from 4.7.1. If you see this issue even without downgrading your DLL, you can use this fix.

After some research I came across this article and applied the same to my assembly which fixed the issue. Added these lines to my AssemblyInfo.cs class file..

[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityRules(SecurityRuleSet.Level1)]

Hope this helps someone who is facing the same issue down the line in their Plugin Development, Debugging…

Thank you for reading…

Cheers,

PMDY

Granting Access to a Business unit Team via C#

Hi Folks,

I hope there isn’t any one who doesn’t know about security roles and access privileges being in Dynamics space. Most of the people should be aware of doing this via application, in this post, sharing one simple way to grant access to the records using C# code. Please use the below code to achieve the same.

private void ShareRecordtoBUTeamofRequestorUser(Guid Targetid, Guid TargetShare, IOrganizationService orgService)
        {
            try
            {
                if (Targetid != null && TargetShare != null)
                {
                    GrantAccessRequest grant = new GrantAccessRequest();
                    grant.Target = new EntityReference(MetadataHelper.VolunteerList.EntityLogicalName, Targetid);

                    PrincipalAccess principal = new PrincipalAccess();
                    principal.Principal = new EntityReference(MetadataHelper.Team.EntityLogicalName, TargetShare);
                    principal.AccessMask = AccessRights.ReadAccess;
                    grant.PrincipalAccess = principal;

                    try
                    {
                        //GrantAccessResponse grant_response = (GrantAccessResponse)orgService.Execute(grant);
                        orgService.Execute(grant);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

I have commented below lines in try block above and avoid using them because you will get an error for the same…

GrantAccessResponse grant_response = (GrantAccessResponse)orgService.Execute(grant);

An unhandled exception has occurred during execution of the plugin.
An error occured while getting default Team of Requestor BusinessUnit[A]Microsoft.Crm.Sdk.Messages.GrantAccessResponse cannot be cast to
[B]Microsoft.Crm.Sdk.Messages.GrantAccessResponse. Type A originates from ‘Microsoft.Crm.Sdk.Proxy, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ in the context ‘Default’ at location ‘C:\Microsoft.Crm.Sdk.Proxy.dll’. Type B originates from ‘Hisol.SCS.CRM.Plugins, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bb2727b96c9cb15e’ in the context ‘LoadNeither’ in a byte array.

Thank you.

Cheers,

PMDY

Are you still using WS-Trust Auth and OrganizationServiceProxy…then it is time to change …

Hi Folks,

Microsoft had recently announced on docs.microsoft.com that using WS-Trust authentication security protocol to connect to your Common Data Service had been deprecated.

So what does this mean??

Firstly you need to note that this only applies to client applications that connect to CDS.

It does not impact your custom plug-ins, workflow activities, or on-premises/IFD service connections.

Below are the places where you need to replace them…

If your code uses Username & Password for authenticating with Common Data Service or an application, you are likely using the WS-Trust security protocol.

  • If you are using the OrganizationServiceProxy  class at all in your code, you are using WS-Trust.
  • If you are using CrmServiceClient.OrganizationServiceProxy  in your code, you are using WS-Trust.

Check the following:

  1. If your client applications using Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy:

         Action Required:

        Replace all occurrences of the type OrganizationServiceProxy with  the IOrganizationService interface

      2.                            using CrmServiceClient with the “Office365” authentication type:

          Action Required:

          Switch over to using an OAuth based connection string, Note that LoginPrompt can be set to “never” to simulate the way that the Office 365 behavior worked. Please note that the App ID and Redirect URI should be created in AAD in your tenant.

Few points to note before we conclude:

  • An update to Microsoft.CrmSdk.XrmTooling.CoreAssembly is available for download through NuGet package that includes auto redirect support. This library will redirect an authentication type of Office365 to OAuth.
  • If you were not able to login even using OAuth, check if MultiFactor Authentication/conditional access is enabled, if so consider registering application user (Service Principal) in Azure Active Directory.

 

References:

CDS/CRM SDK – WS-Trust auth and OrganizationServiceProxy Deprecated

Use of Office365 authentication with the WS-Trust security protocol

 

If you still have issue, don’t hesitate to comment here…or reach to community using this link…

Cheers,

PMDY

 

 

 

Fix : Could not load file or assembly ‘Microsoft.IdentityModel.Clients.ActiveDirectory..The system cannot find the file specified.”:”Microsoft.IdentityModel.Clients.ActiveDirectory..

Hi Folks,

Recently I came across this problem with one my console applications while working with ADAL library. After debugging for a while, came to know that this DLL referenced had been updated and I strangely note that error popping up.

Then I came to know that there was an assembly binding defined with a different version from the DLL present in the bin folder. So I tried to understand a bit about assembly binding and what assembly binding redirect is all about.

Why are binding redirects needed at all?

Suppose you have application A that references library B, and also library C of version 1.1.2.5. Library B in turn also references library C, but of version 1.1.1.0. Now we have a conflict, because you cannot load different versions of the same assembly at runtime. To resolve this conflict you might use binding redirect, usually to the new version (but can be to the old too). You can do that by adding the following to app.config file of application A, under configuration>runtime>assemblyBinding section (see here for an example of full config file):

<dependentAssembly>
    <assemblyIdentity name="C"  
                      publicKeyToken="32ab4ba45e0a69a1"  
                      culture="en-us" />  
    <bindingRedirect oldVersion="1.1.1.0" newVersion="1.1.2.5" />  
</dependentAssembly>

You can also specify a range of versions to map:

<bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.2.5" />  

Now library B, which was compiled with reference to C of version 1.1.1.0 will use C of version 1.1.2.5 at runtime. Of course, you better ensure that library C is backwards compatible or this might lead to unexpected results.

You can redirect any versions of libraries, not just major ones.

If you want to know more about assembly binding, redirects. Please refer to below post.

https://www.codeproject.com/Articles/12215/Assemblies-locating-binding-and-deploying

Finally I was able to resolve this issue by commenting this section in App.config. The fix seem to be easy.

Hope this helps.

Cheers,

PMDY

 

Visual Studio Cache Cleanup – Tip to Step into your DLL Code

Hi Folks,

Have you ever had a situation where you had to debug a DLL code referred from your existing .Net Assembly…?

Possibly you might have added a reference…but still not able to step into your respective DLL even after adding project references and placing PDB in bin folder, then this tip of Visual Studio is for you…

First of all, here’s how to clear the Component Cache…

1. Close Visual Studio (ensure devenv.exe is not present in the Task Manager)
2. Delete the %USERPROFILE%\AppData\Local\Microsoft\VisualStudio\14.0\ComponentModelCache directory
3. Restart Visual Studio.

You could also need to cleanup your user’s temp folder. It is usually located under  %USERPROFILE%\AppData\Local\Temp.

Now try to debug and verify…possibly you need to try the user profile temp data clearing also.

If the above fails, you can go with approach…but be careful before proceeding…

%USERPROFILE%\AppData\Local\Microsoft\Team Foundation
%USERPROFILE%\AppData\Local\Microsoft\VisualStudio
%USERPROFILE%\AppData\Local\Microsoft\VSCommon

Then, open the Visual Studio IDE folder in command prompt and Run devenv /resetuserdata from the Visual Studio IDE folder.
Typical location for 64 bit: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE
Typical location for 32 bit: C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE

Reference:

https://www.matteopozzani.com/visual-studio-cache-cleanup/

Hope this helps in troubleshooting..

Cheers,

PMDY

Enable logging in CE without any third party tools

Hi,

Have you ever had an issue where you need logging mechanism to troubleshoot…

Out there we have some 3rd party software which can help with this…but we can use Notes entity in CE so that we can enable logging to our .Net Assembly code with out any other 3rd party additions.

Add the below part to your code..

Entity _annotation = new Entity(“annotation”);
_annotation.Attributes[“mimetype”] = @”text/plain”;
_annotation.Attributes[“notetext”] = message;
service.Create(_annotation);

And use the method above to create log wherever needed like below..no other DLL additions required..you fill find the logs under Notes entity.

createlog(service, “Your String to be logged”);

Hope this helps while troubleshooting…

Cheers,

PMDY

Understand differences between System.Collections.Generic.List.Add() & System.Collections.Generic.List.AddRange()

Hi,

For now we will jump back to our C# Collections to gain some understanding…

Firstly whenever we would like to add just one element to the collection we use List.Add as below

List<OrganizationRequest> RequestCollection = new List<OrganizationRequest>();

OrganizationRequest class is provided in Microsoft.Xrm.Sdk namespace.

For this list of organization request collection…if we want to add an element..we can do like this where CreateRequest  is part of OrganizationRequest

CreateRequest transCreate = new CreateRequest { Target = orderTransaction };
RequestCollection.Add(transCreate);//Adding a create request

Suppose if we want to add multiple elements…we can use as below..

RequestCollection.AddRange(orderStarValue,totalRewardStars,salesOrder,orderDate);

Hope this helps..

 

No lock and distinct conditions in query expression

Hi Folks,

Whenever i tried using query expression for retrieve multiple operations, came to know some interesting facts which exists and hence would like to share with you all.

As you already know Query expression was used when dealing with a little complex query, lets see this in action

Basic Query Expression Example


// Query using ConditionExpression and FilterExpression
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "lastname";
condition1.Operator = ConditionOperator.Equal;
condition1.Values.Add("Brown");
FilterExpression filter1 = new FilterExpression();
filter1.Conditions.Add(condition1);
QueryExpression query = new QueryExpression("contact");
query.ColumnSet.AddColumns("firstname", "lastname");
query.Criteria.AddFilter(filter1); query.NoLock = true;//Condition to prevent occurrence of deadlocks, distinct was used to retrieve unique columnsets in the query
EntityCollection result1 = _serviceProxy.RetrieveMultiple(query);

The benefit of setting NoLock to true is that it allows you to keep the system from issuing locks against the entities in your queries; this increases concurrency and performance because the database engine does not have to maintain the shared locks involved. The downside is that, because no locks are issued against the records being read, some “dirty” or uncommitted data could potentially be read. A “dirty” read is one in which the data being read is involved in a transaction from another connection. If that transaction rolls back its work, the data read from the query using NoLock will have read uncommitted data. This type of read makes processing inconsistent and can lead to problems. The risk of having “dirty” data is something to consider, especially in high database transaction environments.

Reference: https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.query.queryexpression.aspx 

https://mscrmmindfire.wordpress.com/2013/11/26/avoiding-deadlock-in-plugins/

http://www.resultondemand.nl/support/sdk/f5d2195b-8cae-49d6-a493-6f8b92e7f54e.htm

Hope this helps some one…

Cheers,

PMDY

Open source tools, Solutions available for Developers and Admins

So today, I would like to give you a list of most useful tools available till now for Dynamics CRM which increases the developer productivity and helps Admins.

Some great tools you should check out to see if they could work in your organization.
  1. Fiddler – web debugging proxy
  2. Task Workflow Tools – custom workflow steps to extend your workflows
  3. Mobile Task Flows – walk users through tasks in the mobile or phone app
  4. Ribbon Workbench – visually edit the ribbon
  5. CRM Bookmarklets – JavaScript saved as bookmarks to “hack” your CRM (edit read only fields, show hidden fields, etc.)
  6. XRM Toolbox – It was shipped with 20 84  plugins as of April 2018 to handle several administration, customization or configuration tasks. Wiki
    • Access Checker
    • Assembly Recovery Tool
    • Attribute Bulk Updater
    • Audit Center
    • FetchXml Tester
    • Bulk Form Attribute Manager
    • FLS Bulk Updater
    • Form Libraries Manager
    • Form Parameter Manager
    • Import/Export NN relationships
    • Iconator
    • Metadata Browser
    • Metadata Document Generator
    • Privileges Discovery
    • Role Updater
    • Script Finder
    • SiteMap Editor
    • Solution Components Mover
    • Solution Import
    • Solution Transfer Tool
    • Sync Filter Manager
    • Synchronous events execution order editor
    • Easy Translator
    • User Roles Manager
    • User Settings Utility
    • View Layout Replicator
    • View Transfer Tool
    • Web Resources Manager
  7. Metablast – visual utility for exporting metadata
  8. CRM Snoop – Plugin Troubleshooting tool
  9. LinqPad – Easily run .NET code
  10. CRM DevTools – Chrome extension visible in the F12 developer area with lots of helpful functions for admins. It is worth it just to remember the debug and diagnostic links
  11. KingswaySoft – SSIS Integration toolkit
  12. Developer tool kit – New developer tool kit which was officially released
  13. Microsoft Fakes framework to unit test your CRM Code  – Test your undeveloped CRM Custom code using Microsoft Fakes framework
  14. CRM JavaScript Web API Service Utility – Used to write the latest javascript code using Web API
  15. Link Buddy –  It’s useful for converting logging/tracing details from CRM plug-ins, custom apps, etc. into click-able links that open the CRM record for which the GUID represents.
  16. MS CRM Security Roles to Excel Export – A Tool to export CRM Security roles into a Excel workbook.
  17. FetchXML Tester Online – Allows you to test FetchXML queries online without importing any solution or downloading any separate application.
  18. ILMerge – a .NET tool/utility which merges a number of dll’s into one dll, which is useful for creating plugins for online CRM.
  19. Tool to track performance – Check the CRM latency and bandwidth at https://CRMUrl.com/tools/diagnostics/diag.aspx (make sure to replace CRMUrl.com with the actual CRM URL).
  20. Convert FetchXML to SQL query – people find difficulties in converting the fetch xml query created from advanced find to a SQL query to retrieve records from Backend, use this tool to help the same
  21. Convert SQL query to Fetch XML – Two way round, use this to convert your backend queries to fetch XML to use them in your Code to retrieve data and metadata.
  22. Diagnostics Tool for On premise – Helps CRM developers and administrators to enable trace and devErrors on CRM server. Whereas its name only mentions CRM 2011, it is compatible with CRM 2013 and 2015 too (OnPremise only)
  23. Fetch XML Formatter 1, Fetch XML Formatter 2– Two similar tools for the same functionality, use according to your convenience. These were lightweight windows application that tool will be help you when you are extensively working with FetchXML in Javascript / C# code to get desired result. Takes fetchXML from Advance Find as an input and convert that into desired format, which can be used into Javascript / C# for further coding.
  24. Local option set to Global optionset converter – It’s purpose is to automate the task of converting a Local Option Set (an option set that is defined by and specific to a single entity. e.g. a CRM 4.0 Picklist), into a Global Option Set.
  25. Win Merge – A great tool to compare customizations.xml files taken from solutions
  26. CRM Rest Builder – A tool for CRM 2011/2013/2015/2016 Online & On Premise to generate JavaScript code using the 2011 & Web API REST endpoints.
  27. CRM Visual Studio Code JS Snippets – JavaScript code snippets for Dynamics 365/CRM 2011 – 2016 (5.0 – 8.2)
  28. TableTools2 – Add on for only Mozilla firefox to improve the CRM Grids. You can use the addon in grids that don’t display a filter or just in general with any page that displays a table like structure.
  29. CRM Theme Generator – Use this tool to generate the feature and create themes in CRM, supporting latest versions
  30. Advanced Query outer Join – Plugin to enable outer join queries from Advanced Find. This plugin enabled you to do that. The plugin runs on pre-RetrieveMultiple and alter the query that gets sent to the pipeline, with the correct outer join conditions
  31. Easy VS Code in Action – Use this to work with JavaScript file types from your desktop itself and without opening visual studio
  32. Custom code validation tool – Between CRM 2015 and CRM 2016 there are no differences for the checking of unsupported customizations of Js code, so if you get results to fix with the 2015 custom code validation tool means that you need to fix as well for 2016
  33. CRM DevTools – from Sonoma Partners is a Chrome extension which quickly provides CRM record and environment information and makes troubleshooting and testing so much easier. Once it’s installed, you can access the features by going to the Chrome DevTools (F12 key) and clicking the CRM DevTools tab.
  34. Solution to Create “Does Not Have” Queries using Advanced Find – This solution allows you to create “does not have” or “does not exist” queries using the standard Advanced Find interface.
  35. Dynamics 365 developer extensions(tool kit) – Tool to search for CRM related MSDN content, and tooling to assist with managing and deploying web resources, plug-ins, and reports
  36. Network Visualisation tool – Visualize the relationships between accounts, contacts and activities in a network graph, refer to this video to get insights
  37. Level up for dynamics CRM – Works with Edge and Chrome only. Gives form helpers and Navigation helpers, an amazing tool
  38. Personal view to System view – use this to convert created personal view to system view
  39. Beautify your JS, JSON code – improve the readability of your JS code, even minify your code
  40. Ribbon workbench 2016 – Most user friendly and universally accepted tool to customize ribbon, note that this version don’t need Silverlight within your browser
  41. ilspy – Used to decompile your source code from your .NET DLL, helpful to find your source code from plugin DLL’s
  42. Autonumbering solution – free autonumbering solution used to generate a Unique Reference Number for new records so they can easily be tracked, and is also useful for integrations.
  43. ReSharper – on the fly code analysis, identifies problems and provides quick fixes, best addin to visual studio
  44. Integrate Microsoft Dynamics CRM – Find the ETL tools and other key useful integration tools supported from MSDN.
  45. Call workflows and actions using Javascript – Use this tool to call workflows and actions using JavaScript without much hassles without too much taking care of code.
  46. Scribe Insights – Good data migration platform to move data between two systems and create new records in MS CRM. Reasonably the best in terms of performance with such a kind of UI and easy to learn. Comes with one month free trial.
  47. SOAP UI – Most widely used tool for testing web services and other API’s without much hassles.
  48. DLL Extractor – Extract your plugin DLL’s located on your CRM Database, this applies only for On premise applications. Login to your Client network and specify the server and database name with Integrated security or SQL Authentication. Click on List Plugins which shows the assemblies registered and download the                    required ones.
  49. Portal Checker – Troubleshoot your Dynamics 365 portals
  50. Autonumber No Code solution – Autonumbering generation solution.
  51. Commander – is a pre-configured software package that provides you with an awesome terminal emulator, and best shell you’ll ever have on Windows
  52. GuidGen – GuidGen is Microsoft recommended tool which programmatically generates GUID’s.

Hope you found some tool which had increased your productivity developing CRM…

Cheers,

PMDY