D365 – System Views – Does Not Contain Data

The Advanced Find functionality within D365 v9 allows us to search for records that have no data in a related entity – a NOT IN query. For example, provide a list of Contacts that are not the Primary Contact for an Account.

advanced-find-NOT-IN

However, if we try to create the same using a System View there is currently no option to do a NOT IN query.

system-view-filter

To create a System View which contains a NOT IN query I had to complete the following steps.

  1. Create a basic System View with the required column layout and Publish the View.
  2. Using XrmToolBox and the View Designer Plugin I opened the System View and edited the query (using FetchXML Builder)
  3. Finally, save and publish the changes to the System View.

NOT-IN-FetchXML

A few things I have found when creating NOT IN System Views.

    1. The System View does get created in the list of System Views for the entity and displays the correct content.

system-view-1

    1. When you open the Advanced Find from the System View, the filters for the System View are displayed correctly but the name of the System View we created is not listed.

system-view-2

    1. When you re-open the System View in the D365 solution after you have made the NOT IN modification, the option to Edit the filter criteria is no longer available. Any additional changes to the System View would need to be made using the XrmToolBox View Designer Plugin.

system-view-3

Advertisements

D365 Portals, Liquid Templates and FetchXML

My challenge today was to create a Web Template for a D365 Portal that returned a JSON object from a FetchXML query. There are a few blog posts around on how to achieve this, including this one from my colleague Nadeeja.

The complication for me was the FetchXML contains an ‘in’ operator which would contain a dynamic number of values.
fetchXML
The solution requires the creation of a Liquid array which can then be used in the construction of the FetchXML. To create the array I pass a comma separated list of values of GUIDs I need included in the query. Using the Liquid Assign variable tag i can create the array.
{% assign groupIds = request.params['groupIds'] | split: ',' %}
Within the Web Template I can iterate through the array as part of the construction of the FetchXML query.
fetchXML-2
To test the response I created a POST within Postman to the URL and supplied the named parameter, groupIds, as a comma separated list of values. The POST request is made using form-data and returns the relevant number of items based on the number of items in the groupIds array.
postman

Visual Studio 2017 – NETFramework Versions

If Visual Studio 2017 is not displaying the relevant Target Frameworks for your machine then it may be that the targeting packs are not installed on your machine.

Run the Visual Studio Installer (from within Visual Studio, select Tools | Get Tools And Features) and select the necessary targeting packs.

When you restart Visual Studio you will find the Target Frameworks have been added to the list.

Useful links…

Troubleshoot blocked .NET Framework installations and uninstallations

How to: Determine Which .NET Framework Versions Are Installed

Snipping Tool – Save As not working

If your Save option in the Windows Snipping Tool is not working have a look at the Registry Setting for My Pictures under Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

If it is pointing to an invalid location, for example you have previously modified a drive letter, you may need to update this to the correct location. Just make sure you restart the Snipping Tool when you have made the Registry Correction. Please note, any modifications you make to the Windows Registry are made at your own risk.

Using PowerShell to get a D365 record count

The Microsoft.Xrm.Data.PowerShell module provides a number of very useful functions for getting information from Microsoft CRM/D365 using PowerShell. The Get-CrmEntityRecordCount is just one of those functions but it only returns a count of all records for an entity. What if I need a record count for a filtered view? Fortunately, this is where the Get-CrmRecordsByFetch function can be combined with FetchXml aggregation.

# Create my connection to D365
$conn = Connect-CrmOnlineDiscovery -InteractiveMode

# Create my FetchXML with the relevant filter to return an aggregate (Count)
$count = Get-CrmRecordsByFetch -conn $conn -Fetch @"
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" aggregate="true">
    <entity name="msdyn_workorder">
        <attribute name="msdyn_name" alias="msdyn_name_count" aggregate="count" />
        <filter type="and">
            <condition attribute="createdon" operator="on-or-before" value="2018-02-01" />
        </filter>
    </entity>
</fetch>
"@ 

# Get the actual number of records from the AliasedValue
$count.CrmRecords[0].msdyn_name_count

HTTP Actions and 202 Responses

When calling a Function App that returns a 202 (Accepted) Status Code I found my HTTP action in my Logic App was returning a status code of 405 with the a message of “The HTTP ‘GET’ method is not supported by the ‘GenericJsonWebHookReceiver’ WebHook receiver.”.

This seemed a bit odd because I had tested my Function App using the exact same request using Postman and it was returning a valid 202 response. After reading a bit more about HTTP Actions (https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-workflow-actions-triggers#http-action) the section on Asynchronous Patterns gave me the answer. To disable the asynchronous behavior previously described, set operationOptions to DisableAsyncPattern in the action inputs. In this case, the action’s output is based on the initial 202 response from the server.

Having made this change to the Logic App the server response was accepted and considered a success.

Azure Web App – Read local XML file

I needed a way to get read access to a local XML file in the Azure Web App that is not a .config file. Using the standard naming format for the root folder I can read the XML data file into a DataSet.

DataSet dataSet = new DataSet();
var wscXML = string.Concat(Environment.GetEnvironmentVariable("HOME", EnvironmentVariableTarget.Process), @"\site\wwwroot\wsc.xml");
dataSet.ReadXml(wscXML);