D365 JavaScript Web Resource Library Usage

It’s fairly straight forward to find which Forms use a Web Resource with the ‘Show Dependencies’ option, but that will list Forms where the JavaScript library has been added to the form in the Form Libraries. This doesn’t give you any indication whether the functions in the JavaScript file have actually been used in the form.

Obviously, you can scroll through each Tab and Field in the Event Handlers to look for occurrences of an event, but if you are doing maintenance on a form you didn’t originally develop then it could take a while to scroll though all the possible events. The Event Libraries and Event Handlers are stored in the formjson column of the systemform entity so with a simple FetchXML query you can get a list of Forms that actually use functions from a particular library. The example below will return all Forms where the msdyn_/Utils/head.js Web Resource has been used.The key part is the Filter Condition that is looking for a LibraryName that matches our JavaScript library. The formjson content contains an array of EventHandlers that define the EventName, FunctionName and LibraryName.

<fetch>
  <entity name='systemform' >
    <attribute name='name' />
    <attribute name='formjson' />
    <attribute name='formactivationstate' />
    <attribute name='type' />
    <attribute name='objecttypecode' />
    <filter>
      <condition attribute='formjson' operator='like' 
         value='%&quot;LibraryName&quot;:&quot;msdyn_/Utils/head.js%' />
    </filter>
  </entity>
</fetch>

The next step is to figure out which EventHandlers, if any, use that library in those forms. To do that I created a simple LINQPad script to return a list of the functions in each form.

void Main()
{
	string url = "https://myorgname.crm6.dynamics.com"; 
	string username = "my.user@myorgname.onmicrosoft.com";
	string password = Util.GetPassword("d365-admin");
	
	CrmServiceClient conn = new CrmServiceClient($"Url={url};Username={username};Password={password}; AuthType=Office365");

	conn.OrganizationServiceProxy.Timeout = new System.TimeSpan(0, 3, 0);
	
	conn.OrganizationServiceProxy.EnableProxyTypes();
	
	IOrganizationService orgService = conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;

	string pagingCookie = null;
	
	EntityCollection formsCol = null;
	
	List<Entity> forms = new List<Microsoft.Xrm.Sdk.Entity>();
	
	do
	{
		string fetchXML = $@"<fetch>
		  <entity name='systemform' >
		    <attribute name='name' />
		    <attribute name='formjson' />
		    <attribute name='formactivationstate' />
		    <attribute name='type' />
		    <attribute name='objecttypecode' />
		    <filter>
		      <condition attribute='formjson' operator='like' value='%&quot;LibraryName&quot;:&quot;msdyn_/Utils/head.js%' />
		    </filter>
		  </entity>
		</fetch>";

		formsCol = orgService.RetrieveMultiple(new FetchExpression(fetchXML));
		
		if (formsCol.Entities.Count > 0)
		{
			forms.AddRange(formsCol.Entities);	
		}
		pagingCookie = formsCol.PagingCookie;
	}
	while (formsCol.MoreRecords);

	forms.Select(e => new
	{
		Name = e.GetAttributeValue<string>("name"),
		FormJSON = e.GetAttributeValue<string>("formjson"),
		Functions = System.Text.RegularExpressions.Regex.Matches(e.GetAttributeValue<string>("formjson"), "(\"EventName\":(.*?)},)", RegexOptions.None).Cast<Match>().Select(m => m.Value).ToList()
	}).Dump();
}

Since the formjson content is just a string, I used a Regex pattern to find multiple occurrences of the Event Handlers for each form. The result is a list of the EventNames, FunctionNames and LibraryNames for each form that utilises the JavaScript library in the FetchXML statement.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s