<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C# on The CRM Chap</title><link>/tags/c%23/</link><description>Recent content in C# on The CRM Chap</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 06 Mar 2022 00:00:00 +0000</lastBuildDate><atom:link href="/tags/c%23/index.xml" rel="self" type="application/rss+xml"/><item><title>Getting Started with Microsoft Dataverse Plug-in Logging in Application Insights</title><link>/getting-started-with-microsoft-dataverse-plug-in-logging-in-application-insights/</link><pubDate>Sun, 06 Mar 2022 00:00:00 +0000</pubDate><guid>/getting-started-with-microsoft-dataverse-plug-in-logging-in-application-insights/</guid><description>&lt;img src="/images/PowerApps-FI.png" alt="Featured image of post Getting Started with Microsoft Dataverse Plug-in Logging in Application Insights" /&gt;&lt;p&gt;In today&amp;rsquo;s post, we will be taking a lot at some new functionality that I had the fortunate opportunity to play around with a short time ago. If you&amp;rsquo;re looking to enhance the way you store and manage log information relating to your &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/plug-ins?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Microsoft Dataverse plug-ins&lt;/a&gt;, then be sure to read on. 😀&lt;/p&gt;
&lt;h2 id="so-whats-the-deal"&gt;So What&amp;rsquo;s the Deal?
&lt;/h2&gt;&lt;p&gt;In the past, developers of plug-ins have been limited to storing telemetry information directly within Microsoft Dataverse via the capabilities on offer as part of &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/logging-tracing?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;trace logging&lt;/a&gt;. While this offers us the ability to debug and detect potential problems arising from any custom code we’ve written, attempting to work with this information outside of Dataverse has typically been challenging, if not impossible. To help address this need, it is now possible for developers to output detailed logging and telemetry information into &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview?WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;Application Insights&lt;/a&gt; as well. This offers several distinct benefits, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The ability to easily extract and view this information via tools such as Power BI.&lt;/li&gt;
&lt;li&gt;Support for &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/tutorial-alert?WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;generating alert rules&lt;/a&gt; and custom actions, such as triggering a Logic App or Azure Function.&lt;/li&gt;
&lt;li&gt;No degradation in the quality of the outputted information; developers can expect to receive and work with the exact details currently available as part of trace logging.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Combined together, this capability affords new opportunities for organisations to more closely integrate their Power Platform solution with any existing monitoring capabilities that may already exist within their Microsoft Azure environment.&lt;/p&gt;
&lt;p&gt;Now, it&amp;rsquo;s worth noting that all of this stuff is still currently in public preview, having been initially released in this manner in July last year &lt;a class="link" href="https://docs.microsoft.com/en-us/power-platform-release-plan/2021wave1/data-platform/plug-in-telemetry-application-insights-integration?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;as part of the Wave 1 2021 updates&lt;/a&gt;. Therefore, it’s recommended not to use this yet for any production scenarios; however, it represents an excellent opportunity for developers to &lt;em&gt;review&lt;/em&gt; what&amp;rsquo;s on offer and take steps to consider using it in the future.&lt;/p&gt;
&lt;h2 id="getting-started"&gt;Getting Started
&lt;/h2&gt;&lt;p&gt;First, make sure you have an Application Insights resource stood up on Microsoft Azure, ideally within the same region as your Dataverse environment. From there, you will then need to navigate into &lt;a class="link" href="https://aka.ms/ppac" target="_blank" rel="noopener"
&gt;the Power Platform Admin Center&lt;/a&gt; and navigate into the &lt;strong&gt;Data Export (preview)&lt;/strong&gt; area:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/PowerPlatform-AdminCenter-DataExportArea.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Then, select &lt;strong&gt;New Data export&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/PowerPlatform-AdminCenter-DataExportAppInsights.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;On the &lt;strong&gt;New data export&lt;/strong&gt; pane, select the &lt;strong&gt;CDS diagnostics and performance option&lt;/strong&gt; and choose the environment you want to configure the integration for:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/PowerPlatform-AdminCenter-NewDataExport.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Then, on the final screen, select the Application Insights resource you created earlier and select &lt;strong&gt;Create&lt;/strong&gt; - provided you have the relevant access, all possible Azure subscriptions/resource groups/resources will appear in the appropriate dropdowns:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/PowerPlatform-AdminCenter-NewDataExportAppInsightsDetails.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;(It&amp;rsquo;s worth noting here that there is a strict 1:1 binding for Environment and Application Insights resource. Therefore, you may need to set up additional Application Insights resources to accommodate this restriction.)&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s everything setup successfully, which we can confirm by navigating to the &lt;strong&gt;App Insights&lt;/strong&gt; tab:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/PowerPlatform-AdminCenter-DataExportAppInsightsList.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Pretty straightforward, I&amp;rsquo;m sure you&amp;rsquo;ll agree - provided you know where to find it, of course. 😉&lt;/p&gt;
&lt;p&gt;Next, we need to implement a plug-in that uses the &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger?view=dotnet-plat-ext-6.0&amp;amp;WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;ILogger Interface&lt;/a&gt;. This is included as part of the &lt;strong&gt;System.Net.Http&lt;/strong&gt; assembly, which should be added automatically as part of any new class assembly project; otherwise, &lt;a class="link" href="https://www.nuget.org/packages/System.Net.Http/4.3.4?_src=template" target="_blank" rel="noopener"
&gt;add it in from NuGet&lt;/a&gt;. From there, we can start to think about using this in our code. Let&amp;rsquo;s assume our plug-in project is called &lt;strong&gt;JJG.Plugins.AppInsightsSample&lt;/strong&gt;. First, create a folder in the project called &lt;strong&gt;Helper&lt;/strong&gt; and then add in the following custom class:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.PluginTelemetry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;JJG.Plugins.AppInsightsSample.Helper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// Class used to consolidate all Tracing / Logger calls into a single action.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// Logs information out to the Trace Log and Application Insights resource for the current environment.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;param name=&amp;#34;log&amp;#34;&amp;gt;The actual message to log out.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// Logs an error out to the Trace Log and Application Insights resource for the current environment.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;param name=&amp;#34;log&amp;#34;&amp;gt;The actual message to log out.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;param name=&amp;#34;log&amp;#34;&amp;gt;Exception details to log out into Application Insights.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The class acts as a means of simplifying any calls out to the Logger and the plug-in trace log, as and when we need to. I would advise always writing out to both destinations so that any relevant information from a debugging standpoint is also available within Dynamics 365.&lt;/p&gt;
&lt;p&gt;Next, we&amp;rsquo;ll need to add in a plug-in that performs some action. In this case, we have a plug-in that goes off and creates a couple of Task rows on a Case, provided that the source of the Case does not equal &lt;strong&gt;Facebook&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.ServiceModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;JJG.Plugins.AppInsightsSample.Helper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;JJG.Plugins.AppInsightsSample&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Case_OnUpdate_PushAppInsightsSample&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;facebookCaseOrigin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2483&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Obtain the execution context from the service provider.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Check for EntityType and Message supported by your Plug-In&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageName&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Update&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrimaryEntityName&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;incident&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Plug-In {this.GetType()} is not supported for message &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;$&amp;#34;{context.MessageName} of {context.PrimaryEntityName}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Initialize Tracing / Logger for Application Insights - custom class used to simplify the calls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Logger&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tracing / Logging implemented successfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//For the sample, just create a couple of Tasks on the Case and output details to logging.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Also simulate an error scenario, based on the Case Origin value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;incident&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;postIncident&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PostEntityImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;PostImage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Case ID: {incident.Id}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;OptionSetValue&lt;/span&gt; &lt;span class="n"&gt;incidentOrigin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;postIncident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OptionSetValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;caseorigincode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Origin (Value): {incidentOrigin.Value}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;incidentOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;facebookCaseOrigin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;Invalid Case Origin specified. Facebook Origin&amp;#39;s are not allowed.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Creating Tasks for Case ID {incident.Id}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Get a reference to the Organization service.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateOrganizationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;taskNumbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;taskNumbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Processing Task # {number}...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;task&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;Case Task # {number}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;scheduledend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;regardingobjectid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;incident&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;taskID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Task ID {taskID} created successfully.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Plugin {this.GetType()} execution successfully completed!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt; &lt;span class="n"&gt;pex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FaultException&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrganizationServiceFault&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;finalMessage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;An error occurred in the {this.GetType().FullName}:{Environment.NewLine}{message}{Environment.NewLine}{fex}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;finalMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;finalMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;finalMessage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;An error occurred in the {this.GetType().FullName}:{Environment.NewLine}{ex}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;finalMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;finalMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This plug-in requires a post-operation step that should be registered on Update of any column on the Case table (it doesn&amp;rsquo;t matter which one). The plug-in step will also require a Post Image configuring, as indicated below:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolPostImageAppInsights.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="reviewing-the-logs"&gt;Reviewing the Logs
&lt;/h2&gt;&lt;p&gt;With logging enabled at the environment level, what we will find is that our Application Insights logs start filling up with execution details for &lt;em&gt;every&lt;/em&gt; plug-in within the environment, alongside additional information relating to user requests, API calls and other related telemetry. We, therefore, need to write particular sets of queries to retrieve the information we want. The appropriate object types available to us include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;dependencies&lt;/strong&gt;: Stores details of all backend SDK operations executed in the environment, such as RetrieveMultiple, Update etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;exceptions&lt;/strong&gt;: All custom / unhandled errors will be logged into here&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pageViews&lt;/strong&gt;: Unrelated to our current purposes, we can use this object to see all actions carried out within a model-driven app by each user(s).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;requests&lt;/strong&gt;: This object will log all Web API and Organisation Service Requests made against the environment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;traces&lt;/strong&gt;: Within here, every single message logged out using the &lt;strong&gt;LogInformation&lt;/strong&gt; method will appear - one row for every single &amp;ldquo;trace&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To help get you started, I&amp;rsquo;ve provided a couple of examples below, alongside an indication of the results we can expect to receive. To execute these, make sure we are in the &lt;strong&gt;Logs&lt;/strong&gt; area of our Application Insights resource:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/MicrosoftAzure-ApplicationInsights-LogAnalytics.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h3 id="return-all-errors-for-specific-plug-in"&gt;Return All Errors for Specific Plug-in
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;exceptions
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| order by timestamp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| project timestamp, cloud_RoleInstance, customDimensions[&amp;#34;FormattedMessage&amp;#34;], problemId, [&amp;#39;type&amp;#39;], assembly, method, outerType, outerMessage, outerAssembly, outerMethod
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| where cloud_RoleInstance contains &amp;#34;SandboxRoleInstance&amp;#34; and method == &amp;#34;JJG.Plugins.AppInsightsSample.Case_OnUpdate_PushAppInsightsSample&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="/images/MicrosoftAzure-ApplicationInsights-DataversePluginLogExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h3 id="get-all-traces-for-specific-plug-in-execution"&gt;Get All Traces for Specific Plug-in Execution
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traces
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| project timestamp, message, itemType, customDimensions, operation_Id, session_Id
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| where operation_Id == &amp;#34;918c491a-ffd6-4820-a432-3c332ed21248_9d7f35ed-376f-49a7-afa5-05bdc3d88ffe&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="/images/MicrosoftAzure-ApplicationInsights-DataversePluginTracingExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h3 id="get-all-traces-for-all-failed-plug-in-executions"&gt;Get All Traces for All Failed Plug-in Executions
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dependencies
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| where type == &amp;#34;Plugin&amp;#34; and name == &amp;#34;JJG.Plugins.AppInsightsSample.Case_OnUpdate_PushAppInsightsSample&amp;#34; and success == false
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| project operation_Id, timestamp, target
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| join (traces
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; | project operation_Id, message
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ) on $left.operation_Id == $right.operation_Id
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| order by timestamp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="/images/MicrosoftAzure-ApplicationInsights-DataversePluginTracingForErrorsExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="further-resources"&gt;Further Resources
&lt;/h2&gt;&lt;p&gt;Below are some links to the official Microsoft Docs on this subject - well worth a read, and I&amp;rsquo;m grateful to these posts in helping to put together this blog post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/application-insights-ilogger?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Write Telemetry to your Application Insights resource using ILogger (Preview)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/power-platform/admin/analyze-telemetry?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Preview: Analyze model-driven apps and Microsoft Dataverse telemetry with Application Insights&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/power-platform/admin/set-up-export-application-insights?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Preview: Set up exporting to Application Insights&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What do you think of this new functionality? Beneficial or too much hassle to work with? Let me know your thoughts in the comments below!&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>What's The Deal with Schedule API? (Dynamics 365 Project Operations)</title><link>/whats-the-deal-with-schedule-api-dynamics-365-project-operations/</link><pubDate>Sun, 05 Dec 2021 00:00:00 +0000</pubDate><guid>/whats-the-deal-with-schedule-api-dynamics-365-project-operations/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post What's The Deal with Schedule API? (Dynamics 365 Project Operations)" /&gt;&lt;p&gt;I had a great time recently getting involved as part of the &lt;a class="link" href="https://www.meetup.com/microsoft-dynamics-erp-meetup-uk/" target="_blank" rel="noopener"
&gt;Microsoft Dynamics ERP User Group&lt;/a&gt;, where I presented a session asking (channelling my inner Seinfeld in the process) &amp;ldquo;What&amp;rsquo;s the Deal with Schedule API in Dynamics 365 Project Operations?&amp;rdquo;. Off the back of this session, I wanted to do an accompanying blog post that helps to cover off some of the main topics from my talk and as a resource for anyone interested in diving into this subject again or for the very first time. So without much further ado, let&amp;rsquo;s jump in to try and answer this question as best as possible.&lt;/p&gt;
&lt;h2 id="schedule-api-overview"&gt;Schedule API Overview
&lt;/h2&gt;&lt;p&gt;Schedule API provides developers working with &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/project-operations?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Dynamics 365 Project Operations&lt;/a&gt; the &lt;strong&gt;only&lt;/strong&gt; mechanism to automate actions targeting the platform and ensure operations are replicated correctly between &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/data-platform/data-platform-intro?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Microsoft Dataverse&lt;/a&gt; and &lt;a class="link" href="https://support.microsoft.com/en-gb/office/what-is-project-for-the-web-c19b2421-3c9d-4037-97c6-f66b6e1d2eb5" target="_blank" rel="noopener"
&gt;Project for the web&lt;/a&gt;. Rather than using standard Create, Update or Delete actions targeting the core set of Scheduling Tables within Project Operations, developers must instead leverage the Schedule API to carry out these actions. Indeed, this is, in fact, the only supported way we can do this. When we talk about &amp;ldquo;Scheduling Tables&amp;rdquo;, we mean any of the following Project Operations table types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Project Task (msdyn_projecttask)&lt;/li&gt;
&lt;li&gt;Project Task Dependency (msdyn_projecttaskdependency)&lt;/li&gt;
&lt;li&gt;Resource Assignment (msdyn_resourceassignment)&lt;/li&gt;
&lt;li&gt;Project Bucket (msdyn_projectbucket)&lt;/li&gt;
&lt;li&gt;Project Team Member (msdyn_projectteam)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Schedule API’s are built using native capabilities that have been available within Microsoft Dataverse for many years, meaning we can call any of the Schedule API’s in the same way we would for any &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/workflow-custom-actions?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom Action&lt;/a&gt; or &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/custom-api?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom API&lt;/a&gt;. With the Schedule API&amp;rsquo;s, we can carry out the desired automation and programmatic actions we want against Project Operations, using familiar tools and without the need to write a complex integration ourselves that will persist data out into Project for the web.&lt;/p&gt;
&lt;h2 id="how-it-all-works"&gt;How It All Works
&lt;/h2&gt;&lt;p&gt;Because the actions we carry out within Project Operations / Microsoft Dataverse need to be replicated to Project for the web (and vice-versa), Microsoft provides a shared backend service used to process all actions. The following diagram from Microsoft offers an excellent overview of how this backend service works as we target actions against the Schedule API:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-ProjectOperations-ScheduleAPIArchitecture.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;As part of this, developers don’t need to handle complex technical logic; instead, we can let the Schedule API do all the heavy lifting for us. 😀&lt;/p&gt;
&lt;h2 id="supported-apis"&gt;Supported API&amp;rsquo;s
&lt;/h2&gt;&lt;p&gt;At the time of writing this post, the Schedule API supports the following actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creation of new Projects synchronously (via the &lt;strong&gt;msdyn_CreateProjectV1&lt;/strong&gt; action)&lt;/li&gt;
&lt;li&gt;Creation of new Team Members synchronously (via the &lt;strong&gt;msdyn_CreateTeamMemberV1&lt;/strong&gt; action)&lt;/li&gt;
&lt;li&gt;Asynchronous Create, Update or Delete actions targeting any of the Scheduling Tables, using the following actions:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;msdyn_PSSCreateV1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;msdyn_PSSUpdateV1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;msdyn_PSSDeleteV1&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="operationsets-overview"&gt;OperationSets Overview
&lt;/h2&gt;&lt;p&gt;As the Schedule API&amp;rsquo;s rely on the backend services mentioned earlier, a mechanism is needed to ensure we can submit these requests and have complete atomicity as part of our transactions. This is provided for as part of &lt;strong&gt;OperationSets&lt;/strong&gt;, a concept worthy of further discussion. In layman’s terms, these provide a wrapper to bundle all our Schedule API requests together. This request is then passed off to the Schedule API to execute the operations we&amp;rsquo;ve indicated. As such, &lt;strong&gt;every&lt;/strong&gt; request we make to the Schedule API &lt;strong&gt;must&lt;/strong&gt; be included as part of an OperationSet, and we must also link all OperationSets to a Project. We achieve all of this via a two-step process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Initialise the OperationSet (via a &lt;strong&gt;msdyn_CreateOperationSetV1&lt;/strong&gt; request)&lt;/li&gt;
&lt;li&gt;Execute the OperationSet (via a &lt;strong&gt;msdyn_ExecuteOperationSetV1&lt;/strong&gt; request)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once we execute our OperationSets, this is then processed asynchronously by the backend Schedule API service; therefore, there can sometimes be a slight delay in processing substantial requests.&lt;/p&gt;
&lt;p&gt;We can view the list of OperationSets created within Project Operations by navigating to the appropriate area within the sitemap:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-ProjectOperations-OperationSetsSitemap.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;For each row, we can then view details regarding its status, the Project associated with the OperationSet and each request added into the OperationSet:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-ProjectOperations-OperationSetRowExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-ProjectOperations-OperationSetDetailsExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;All of this can be incredibly useful from a debugging and diagnosis standpoint.&lt;/p&gt;
&lt;h2 id="schedule-api-usage-scenarios"&gt;Schedule API Usage Scenarios
&lt;/h2&gt;&lt;p&gt;In a nutshell, any scenario requiring you to automate critical operations targeting Project Operations and, specifically, any scheduling tables will be a good candidate for the Schedule API. This will include situations where, for example, you need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Batch Processing scenarios from external systems into Project Operations.&lt;/li&gt;
&lt;li&gt;Automating the creation of new Projects based on existing template structures.&lt;/li&gt;
&lt;li&gt;Handling complex Work Breakdown Structure’s (WBS’s) that are not easy to define manually in Project Operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="working-with-the-schedule-api"&gt;Working with the Schedule API
&lt;/h2&gt;&lt;p&gt;Because the Schedule API leverages Dataverse actions, we can work with it in a variety of ways, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Any .NET application, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/developer-tools#net-sdk-assemblies?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;using the official SDK assemblies from Microsoft&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/plug-ins?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;.NET Dataverse Plug-ins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;JavaScript / TypeScript, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/webapi/overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;via the Dataverse Web API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/power-automate/overview-cloud?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Power Automate Cloud Flows&lt;/a&gt; &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/commondataserviceforapps/#perform-an-unbound-action?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;via the &lt;strong&gt;Perform unbound action&lt;/strong&gt; action step.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can also use tools, such as &lt;a class="link" href="https://www.postman.com/" target="_blank" rel="noopener"
&gt;Postman&lt;/a&gt; to test operations targeting the Schedule API. &lt;a class="link" href="/exam-pl-400-revision-notes-working-with-the-microsoft-dataverse-web-api-and-processing-workloads" &gt;Check out my post from my PL-400 blog series, all about working with the Dataverse Web API to understand how we can do this.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To help better understand and work through some of the common ways we can work with the Schedule API, both via C# and Power Automate, &lt;a class="link" href="https://github.com/JJGriffin/talk-assets/tree/master/ScheduleAPI/D365.ScheduleAPIDemos" target="_blank" rel="noopener"
&gt;check out the demo project on my GitHub repository&lt;/a&gt;, which you can download and experiment further with. I&amp;rsquo;ve included outline instructions on how to work with each sample provided - let me know in the comments below or on GitHub if you have any problems working with either of them.&lt;/p&gt;
&lt;h2 id="gotchas--limitations"&gt;Gotchas &amp;amp; Limitations
&lt;/h2&gt;&lt;p&gt;Helpful that the Schedule API may be, there are a couple of things to keep in mind while you are working with it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All operations must execute as a fully licensed Project Operations user. This means that using a dedicated Application User account is not supported, as it&amp;rsquo;s impossible to assign a license to accounts of this type. My recommendation would be to set up a full user account, which you can then utilise as a service account that all automation targeting the Schedule API&amp;rsquo;s can then run as. Keep in mind that there will be a cost implication for taking the additional license. 😉&lt;/li&gt;
&lt;li&gt;Microsoft restricts certain actions targeting specific columns on each of the scheduling tables. For example, we can&amp;rsquo;t write any information to a Project Task Actual Start or Actual End columns. &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/project-operations/project-management/schedule-api-preview#restricted-fields?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Be sure to consult the complete list of unsupported columns&lt;/a&gt; to avoid getting caught out during your development work.&lt;/li&gt;
&lt;li&gt;Any operation you execute using the Schedule API will be subject to any platform-level limitations that Project Operations enforces, such as the limit on the number of tasks and resources on a project. &lt;a class="link" href="https://docs.microsoft.com/en-us/project-for-the-web/project-for-the-web-limits-and-boundaries?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Again, ensure you&amp;rsquo;ve consulted the relevant Microsoft documentation to avoid any unwelcome surprises.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To full the view list of limitations, &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/project-operations/project-management/schedule-api-preview#limitations-and-known-issues?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;you can consult the dedicated Microsoft Docs article section devoted to this subject.&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="troubleshooting-schedule-api-issues"&gt;Troubleshooting Schedule API Issues
&lt;/h2&gt;&lt;p&gt;Things can, invariably, go wrong when working the Schedule API. The API&amp;rsquo;s do a pretty good job of identifying and throwing back any issues in your Operation Set Details as you submit them to the platform (e.g. if you provide a column that&amp;rsquo;s not supported with the API&amp;rsquo;s). Still, things can occasionally go wrong as the OperationSets are processed behind the scenes. For when problems occur, we can consult the &lt;strong&gt;PSS Error Log&lt;/strong&gt; (msdyn_psserrorlog) table, which will log any errors that arise alongside the appropriate error code. The information exposed here can be somewhat limited currently, so you may need to escalate each error, along with its CorrelationId, to Microsoft for further investigation.&lt;/p&gt;
&lt;h2 id="additional-resources"&gt;Additional Resources
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://www.linkedin.com/in/antti-pajunen-1a6b9420/" target="_blank" rel="noopener"
&gt;Antti Pajunen&lt;/a&gt; remains, as always, my go-to person whenever it comes to anything Project Service Automation or Project Operations, and the following posts are particularly recommended. I&amp;rsquo;m indebted to the first of these in helping to put together the demos in my GitHub repository:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://daytodaydynamics365.com/dynamics-365-project-operations-using-schedule-apis-with-power-automate-and-custom-project-templates" target="_blank" rel="noopener"
&gt;Dynamics 365 Project Operations: Using Schedule APIs with Power Automate and custom project templates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://daytodaydynamics365.com/d365-project-operations-project-for-the-web-calling-schedule-apis-from-power-automate-without-custom-connectors" target="_blank" rel="noopener"
&gt;D365 Project Operations, Project for the web: Calling Schedule APIs from Power Automate without custom connectors&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another good resource you can turn to, which helps evaluate and understand the expected performance of Schedule API, is the &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/project-operations/project-management/project-schedule-api-performance?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Project Schedule API Performance Benchmarks article&lt;/a&gt;, which provides some example execution times for a variety of different request types.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I hope this post has helped remove any doubts or queries you may have had relating to the Schedule API in Dynamics 365 Project Operations. Let me know in the comments below if you have any questions&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Blocking Duplicate Quotes in Dynamics 365 Sales Professional / Enterprise (C#)</title><link>/blocking-duplicate-quotes-in-dynamics-365-sales-professional-enterprise-c-sharp/</link><pubDate>Sun, 14 Nov 2021 00:00:00 +0000</pubDate><guid>/blocking-duplicate-quotes-in-dynamics-365-sales-professional-enterprise-c-sharp/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Blocking Duplicate Quotes in Dynamics 365 Sales Professional / Enterprise (C#)" /&gt;&lt;p&gt;&lt;a class="link" href="/reopening-won-quotes-dynamics-365-sales-professional-enterprise-c-sharp" &gt;As you might be able to tell from other recent blog posts&lt;/a&gt;, I&amp;rsquo;ve been doing lots of work lately with &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/sales?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Dynamics 365 Sales&lt;/a&gt; and, specifically, the &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/sales-professional/sales-professional-overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Professional variant of the application&lt;/a&gt;. Sales Professional can be best thought of as a &amp;ldquo;lite&amp;rdquo; CRM system, with much of the same type of functionality as we&amp;rsquo;d expect from the full-blown Enterprise application. &lt;a class="link" href="/wheres-the-create-order-button-on-my-active-quote-records-dynamics-365-sales-professional" &gt;I&amp;rsquo;ve blogged previously on the subject of differences between the two versions&lt;/a&gt;. The only major thing you lose with the Professional application is access to things like &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/sales/create-edit-competitor-record-sales?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Competitors&lt;/a&gt; and restrictions on the number of custom tables that you can include as part of your solution. It&amp;rsquo;s worth consulting the &lt;a class="link" href="https://go.microsoft.com/fwlink/p/?LinkId=866544" target="_blank" rel="noopener"
&gt;licensing guide&lt;/a&gt; to break down the differences in detail before making a decision. Still, if you are in the market for your very first CRM system, you can&amp;rsquo;t go far wrong with considering Dynamics 365 Sales Professional.&lt;/p&gt;
&lt;p&gt;As was the case with last week&amp;rsquo;s jolly jaunt into Dynamics 365 Sales, I was dealing yet again with another unusual requirement. In this case, the organisation in question wanted to have it so that only a single Draft Quote could ever exist for an Opportunity in the system. As part of the solution, some additional automation and reporting requirements relied upon information present within the most current Quote issued to Customers and salespeople in the organisation were, very often, creating multiple Quotes without realising. So we needed an approach that would prevent the duplicates from ever getting made. &lt;a class="link" href="https://docs.microsoft.com/en-us/power-platform/admin/set-up-duplicate-detection-rules-keep-data-clean?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Duplicate Detection Rules&lt;/a&gt; provide a mechanism to &lt;em&gt;discourage&lt;/em&gt; users from creating duplicate rows, but users could still override this if they felt mischievous. Therefore, we decided that a server-side solution and, specifically, a C# plug-in would be required to prevent duplicates from being created altogether. As far as I know, this is the only way we can meet such a requirement; answers on a postcard, though, if you think there&amp;rsquo;s a better way. 😉 With all of this in mind then, below is the code that was implemented to achieve the requirement:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;JJG.MyPlugins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.Query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// Blocks the Create or Update action for a Quote, if it&amp;#39;s detected that another Draft Quote exists linked to the same Opportunity.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cs"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlockDuplicateQuoteForOpportunity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Check for EntityType and Message supported by your Plug-In&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Create&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Update&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrimaryEntityName&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Plug-In {this.GetType()} is not supported for message {context.MessageName} of {context.PrimaryEntityName}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Starting execution of {nameof(BlockDuplicateQuoteForOpportunity)}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Get the newly create Quote (Create) or the Post Image for the Quote (Update), and the Opportunity lookup value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt; &lt;span class="n"&gt;opportunity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;opportunityid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opportunity&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;No Opportunity is present for Quote ID {quote.Id}. Cancelling plug-in execution&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Attempt to retrieve other Draft Quotes that are linked to the same Opportunity ID we have here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Attempting to retrieve other Quote rows linked to Opportunity ID {opportunity.Id}...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt; &lt;span class="n"&gt;serviceFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateOrganizationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt; &lt;span class="n"&gt;qe&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EntityName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Criteria&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Conditions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConditionExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;opportunityid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ConditionOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opportunity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConditionExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ConditionOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConditionExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ConditionOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotEqual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;quotes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetrieveMultiple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Got {quotes.Entities.Count} Quotes!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// If one or more exist, then we throw an error to block the Create / Association&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Multiple Draft Quotes exist for Opportunity ID {opportunity.Id}. Throwing error to cancel operation...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Draft Quote(s) already exist for the selected Opportunity. Only a single Draft Quote is allowed. Please edit or delete the other Draft Quote(s) before proceeding.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;No other Draft Quotes are linked to Opportunity ID {opportunity.Id}. No action required. Cancelling plug-in execution&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When registering this plug-in into the application, ensure that it&amp;rsquo;s aligned to the Post-Operation step on the following messages indicated below:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolDuplicateQuotePluginConfig.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;For the Update step, we also specifically filter on just the &lt;strong&gt;opportunityid&lt;/strong&gt; row, to ensure the plug-in doesn&amp;rsquo;t fire unnecessarily:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolDuplicateQuotePluginConfigFilteringAttributes.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;When the user then attempts to create or associate more than one Quote to a single Opportunity, this will be the error message they will receive:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Sales-BusinessProcessErrorExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Because the plug-in throws the &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.invalidpluginexecutionexception?view=dynamics-general-ce-9&amp;amp;WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;InvalidPluginExecutionException&lt;/strong&gt;&lt;/a&gt; error message, the platform will roll back the entire transaction. We can then inject our own custom message into the dialog that appears.&lt;/p&gt;
&lt;p&gt;As alluded to earlier, having a low/no-code solution to achieve this requirement would be preferred. But, unless I&amp;rsquo;m missing something obvious, doing something similar via a &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/data-platform/overview-realtime-workflows?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;real-time workflow&lt;/a&gt; would be impossible due to the &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.iorganizationservice.retrievemultiple?view=dynamics-general-ce-9&amp;amp;WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;RetrieveMultiple&lt;/strong&gt;&lt;/a&gt; request we have to perform to get other pre-existing Quotes. As much as I make a living out of implementing these types of solutions, we should always be cautious of adopting a code-first mindset if other routes are available to us within Dynamics 365 Sales and the Power Platform. Take care to understand the &amp;ldquo;baggage&amp;rdquo; involved with a solution like this so that you don&amp;rsquo;t get caught out in future as part of an upgrade or when you later incorporate additional functionality into the equation.&lt;/p&gt;</description></item><item><title>Reopening Won Quotes in Dynamics 365 Sales Professional / Enterprise (C#)</title><link>/reopening-won-quotes-dynamics-365-sales-professional-enterprise-c-sharp/</link><pubDate>Sun, 07 Nov 2021 00:00:00 +0000</pubDate><guid>/reopening-won-quotes-dynamics-365-sales-professional-enterprise-c-sharp/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Reopening Won Quotes in Dynamics 365 Sales Professional / Enterprise (C#)" /&gt;&lt;p&gt;After you&amp;rsquo;ve spent any length of time working with the out of the box sales process within &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/sales?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Dynamics 365 Sales Professional / Enterprise&lt;/a&gt;, you get used to some of the behavioural quirks that can commonly cause you challenges during an implementation. A prime candidate for consideration here concerns the various types of tables used by the application. When we consider these in detail, such as the Opportunity, Quote and Order table, many of the assumptions that we make about how things work are instantly proven wrong, as these tables tend to operate by their own set of rules. For example, the ability to easily map across attributes between the different product line table types (Opportunity Product, Quote Product etc.) becomes a challenge; &lt;a class="link" href="/mapping-product-attributes-to-quote-order-invoice-line-items-dynamics-365-customer-engagement" &gt;we must instead revert to using custom code instead to satisfy this requirement&lt;/a&gt;. Little things like this can exasperate both new and long-time users of the application and can often be quite frustrating when explaining to organisations using the software. 😅 Notwithstanding these gripes, I still do genuinely believe the Dynamics 365 Sales platform provides a solid base for organisations to leverage out of the box functionality, with the ability to customise further, as needed. And, when we start to bring into the equation more advanced capabilities, via things such as &lt;a class="link" href="/implementing-a-custom-pricing-engine-within-dynamics-365-customer-engagement" &gt;custom pricing plug-ins&lt;/a&gt;, you begin to move to an entirely new level when it comes to what we can do with this application.&lt;/p&gt;
&lt;p&gt;A particularly annoying behaviour quirk I dealt with recently involved Quotes marked as Won in the system. The organisation I was working with needed to, on occasions, modify details of a Won Quote after the fact. For example, if the salesperson included the wrong item or the customer changed their order after confirming it. As we can observe in the below screenshot, we have no option on the ribbon to reactivate the Quote once Won in the application:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Sales-WonQuoteRibbon.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The only &amp;ldquo;out of the box&amp;rdquo; way of dealing with this was to create and re-input all details into a new Quote; not a viable and time-effective solution. Fortunately, there is a faster way we can achieve the objective by working through the following outline steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, we need to change the Status &amp;amp; Status Reason of the Quote back to &lt;strong&gt;Draft&lt;/strong&gt; &amp;amp; &lt;strong&gt;In Progress&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;After we have made modifications to the Quote, it needs to be set as &lt;strong&gt;Active&lt;/strong&gt; again.&lt;/li&gt;
&lt;li&gt;Once &lt;strong&gt;Active&lt;/strong&gt;, the Quote then must be closed as Won. Microsoft wraps the logic for this within the &lt;a class="link" href="https://docs.microsoft.com/fi-fi/dynamics365/customer-engagement/web-api/winquote?view=dynamics-ce-odata-9&amp;amp;WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;WinQuote&lt;/strong&gt;&lt;/a&gt; action, which we can call via the SDK or against the &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/webapi/overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Microsoft Dataverse Web API&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These steps should be achievable via either a &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/data-platform/overview-realtime-workflows?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;classic workflow&lt;/a&gt; or a &lt;a class="link" href="https://docs.microsoft.com/en-us/power-automate/overview-cloud?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Power Automate cloud flow automation&lt;/a&gt;, which would typically be our first preference for a requirement like this. However, in our case, we wanted to call these steps as part of a &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/custom-api?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom API definition&lt;/a&gt;, which could then be called via a JavaScript action on a Ribbon button, &lt;a class="link" href="/calling-custom-apis-via-javascript-form-ribbon-functions-microsoft-dataverse-power-apps" &gt;similar to how I&amp;rsquo;ve described previously on the blog&lt;/a&gt;. And, most crucially, we needed all steps to be completed synchronously. So, given these requirements, we had to look at a solution leveraging C# instead.&lt;/p&gt;
&lt;p&gt;With all of this in mind, let’s jump into the reason why you’re probably reading this post. 😉 To open a Won Quote using C#, we would need to write and execute the following code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//TODO: Implement code to generate your IOrganizationService reference. For plug-ins, this would look something like this:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//IOrganizationServiceFactory serviceFactory = serviceProvider.GetService&amp;lt;IOrganizationServiceFactory&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;9cc66ad5-2506-4394-854d-f60c35185d96&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OptionSetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Draft&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OptionSetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// In Progress&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, once we&amp;rsquo;re ready to return the Quote to its previous state, we&amp;rsquo;d then run the following code to re-close the Quote. Note in particular, at this stage, we need to execute two separate actions and ensure they are completed successfully:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//TODO: Implement code to generate your IOrganizationService reference. For plug-ins, this would look something like this:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//IOrganizationServiceFactory serviceFactory = serviceProvider.GetService&amp;lt;IOrganizationServiceFactory&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// We execute everything in a transaction, so we can rollback cleanly on failure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ExecuteTransactionRequest&lt;/span&gt; &lt;span class="n"&gt;transactionRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ExecuteTransactionRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Requests&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrganizationRequestCollection&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ReturnResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ExecuteTransactionResponse&lt;/span&gt; &lt;span class="n"&gt;transactionResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;9cc66ad5-2506-4394-854d-f60c35185d96&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// First, we need to Activate the Quote ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OptionSetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Active&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OptionSetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// In Progress&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;UpdateRequest&lt;/span&gt; &lt;span class="n"&gt;updateRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;UpdateRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;transactionRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;updateRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ...with this done, now we can re-close the Quote as Won&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;quoteClose&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteclose&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quoteClose&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Quote Close&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quoteClose&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToEntityReference&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;WinQuoteRequest&lt;/span&gt; &lt;span class="n"&gt;winQuoteRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;WinQuoteRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;QuoteClose&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quoteClose&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OptionSetValue&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;transactionRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;winQuoteRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;transactionResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExecuteTransactionResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transactionRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Quote ID {quoteID} closed as won successfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As stated earlier, if there wasn&amp;rsquo;t a need to execute these actions synchronously, then leveraging Power Automate cloud flows would be something I&amp;rsquo;d actively encourage instead, as both the ability to &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/commondataserviceforapps/#update-a-row?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;update&lt;/a&gt; and &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/commondataserviceforapps/#perform-an-unbound-action?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;call action steps&lt;/a&gt; are supported via this tool. So before you act too gung-ho with the above, validate your approach against the requirements you are working against.&lt;/p&gt;
&lt;p&gt;Regardless of the precise approach you take, it is a minor point of frustration that these types of steps are not natively supported within Dynamics 365 Sales. I understand why the system behaves like this, and there are arguable benefits to having a Quote locked after it&amp;rsquo;s been approved. However, I imagine the ability to make quick edits to a Won Quote is a common requirement across many different organisations, and expecting users to have to go through raising an entirely new Quote is both impractical and ludicrous in equal measure. It&amp;rsquo;s good to know that the underlying platform supports us in building workarounds such as this so that we are not left entirely adrift with a system that must fit around the business instead of the other way around.&lt;/p&gt;</description></item><item><title>Exam PL-400 Revision Notes: Series Roundup</title><link>/exam-pl-400-revision-notes-series-roundup/</link><pubDate>Sun, 27 Jun 2021 00:00:00 +0000</pubDate><guid>/exam-pl-400-revision-notes-series-roundup/</guid><description>&lt;img src="/images/PowerApps-FI.png" alt="Featured image of post Exam PL-400 Revision Notes: Series Roundup" /&gt;&lt;p&gt;Welcome to the final post in my series focused on providing a set of revision notes for the &lt;a class="link" href="https://docs.microsoft.com/en-us/learn/certifications/exams/pl-400?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;PL-400: Microsoft Power Platform Developer exam&lt;/a&gt;. In today&amp;rsquo;s post, I wanted to consolidate all of the content from the series into a single, concise post for ease of access. I&amp;rsquo;ll also provide some general advice and tips that I hope will come in useful for when you sit the exam.&lt;/p&gt;
&lt;p&gt;This series has aimed to provide a broad outline of the core areas to keep in mind when tackling the exam, linked to appropriate resources for more focused study. Ideally, your revision should involve a high degree of hands-on testing and familiarity in working with the platform if you want to do well in this exam.&lt;/p&gt;
&lt;p&gt;Microsoft has split the PL-400 exam into several different areas based on the specification found &lt;a class="link" href="https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE4BeRV" target="_blank" rel="noopener"
&gt;here&lt;/a&gt;. Therefore, I have linked below to the relevant blog/video content from the series for each applicable subject.&lt;/p&gt;
&lt;h3 id="create-a-technical-design-10-15"&gt;Create a technical design (10-15%)
&lt;/h3&gt;&lt;h4 id="validate-requirements-and-design-technical-architecture"&gt;Validate requirements and design technical architecture
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;design and validate the technical architecture for a solution&lt;/li&gt;
&lt;li&gt;design authentication and authorization strategy&lt;/li&gt;
&lt;li&gt;determine whether you can meet requirements with out-of-the-box functionality&lt;/li&gt;
&lt;li&gt;determine when to use Logic Apps versus Power Automate flows&lt;/li&gt;
&lt;li&gt;determine when to use serverless computing, plug-ins, or Power Automate&lt;/li&gt;
&lt;li&gt;determine when to build a virtual entity data source provider and when to use connectors&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="design-solution-components"&gt;Design solution components
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;design a data model&lt;/li&gt;
&lt;li&gt;design Power Apps reusable components&lt;/li&gt;
&lt;li&gt;design custom connectors&lt;/li&gt;
&lt;li&gt;design server-side components&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="describe-microsoft-power-platform-extensibility-points"&gt;Describe Microsoft Power Platform extensibility points
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;describe Power Virtual Agents extensibility points including Bot Framework skills and Power Automate flows&lt;/li&gt;
&lt;li&gt;describe Power BI extensibility points including Power BI APIs, custom visuals, and embedding Power BI apps in websites and other applications&lt;/li&gt;
&lt;li&gt;describe Power Apps portal extensibility points including CRUD APIs and custom styling&lt;/li&gt;
&lt;li&gt;describe Web Resources and their uses&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-designing-a-technical-architecture-for-the-power-platform/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Designing a Technical Architecture for the Power Platform&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-designing-solution-components-within-the-power-platform/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Designing Solution Components within the Power Platform&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-reviewing-power-platform-extensibility-points/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Reviewing Power Platform Extensibility Points&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="configure-microsoft-dataverse-15-20"&gt;Configure Microsoft Dataverse (15-20%)
&lt;/h3&gt;&lt;h4 id="configure-security-to-support-development"&gt;Configure security to support development
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;troubleshoot operational security issues&lt;/li&gt;
&lt;li&gt;create or update security roles and field-level security profiles&lt;/li&gt;
&lt;li&gt;configure business units and teams&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implement-tables-and-columns"&gt;Implement tables and columns
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;configure tables and table options&lt;/li&gt;
&lt;li&gt;configure columns&lt;/li&gt;
&lt;li&gt;configure relationships and types of behaviours&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implement-application-lifecycle-management-alm"&gt;Implement application lifecycle management (ALM)
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;create solutions and manage solution components&lt;/li&gt;
&lt;li&gt;import and export solutions&lt;/li&gt;
&lt;li&gt;manage solution dependencies&lt;/li&gt;
&lt;li&gt;create a package for deployment&lt;/li&gt;
&lt;li&gt;automate deployments&lt;/li&gt;
&lt;li&gt;implement source control for projects including solutions and code assets&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-1"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-using-solutions-to-implement-application-lifecycle-management-alm-capabilities/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Using Solutions to implement Application Lifecycle Management (ALM) Capabilities&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-modelling-data-using-tables-columns-relationships-in-microsoft-dataverse/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Modelling Data using Tables, Columns &amp;amp; Relationships in Microsoft Dataverse&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-implementing-security-within-microsoft-dataverse/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Implementing Security within Microsoft Dataverse&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos"&gt;Videos
&lt;/h4&gt;&lt;h5 id="pl-400-exam-prep-creating-and-deploying-a-managed-solution"&gt;PL-400 Exam Prep: Creating and Deploying a Managed Solution
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/Ke5OgjhC264"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-working-with-the-solution-packager-tool"&gt;PL-400 Exam Prep: Working with the Solution Packager Tool
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/rST0Smks2lQ"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-extracting-and-deploying-solutions-using-azure-devops"&gt;PL-400 Exam Prep: Extracting and Deploying Solutions using Azure DevOps
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/boMCK29dT7Q"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-working-with-tables-columns--relationships-in-microsoft-dataverse"&gt;PL-400 Exam Prep: Working with Tables, Columns &amp;amp; Relationships in Microsoft Dataverse
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/IMW866DrlgE"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-understanding-security-in-microsoft-dataverse"&gt;PL-400 Exam Prep: Understanding Security in Microsoft Dataverse
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/94dCToos_nk"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="create-and-configure-power-apps-15-20"&gt;Create and configure Power Apps (15-20%)
&lt;/h3&gt;&lt;h4 id="create-model-driven-apps"&gt;Create model-driven apps
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;configure a model-driven app&lt;/li&gt;
&lt;li&gt;configure forms&lt;/li&gt;
&lt;li&gt;configure columns&lt;/li&gt;
&lt;li&gt;configure visualizations&lt;/li&gt;
&lt;li&gt;configure commands and buttons&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-canvas-apps"&gt;Create canvas apps
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;create and configure a canvas app&lt;/li&gt;
&lt;li&gt;implement complex formulas to manage control events and properties&lt;/li&gt;
&lt;li&gt;analyze app usage by using App Insights&lt;/li&gt;
&lt;li&gt;build reusable component libraries&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="manage-and-troubleshoot-apps"&gt;Manage and troubleshoot apps
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;troubleshoot app issues by using Monitor and other browser-based debugging tools&lt;/li&gt;
&lt;li&gt;interpret results from App Checker and Solution Checker&lt;/li&gt;
&lt;li&gt;identify and resolve connector and API errors&lt;/li&gt;
&lt;li&gt;optimize app performance including pre-loading data and query delegation&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-2"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-model-driven-power-apps/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Working with Model-Driven Power Apps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-canvas-apps/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Working with Canvas Apps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-managing-and-troubleshooting-a-power-app/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Managing and Troubleshooting a Power App&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-1"&gt;Videos
&lt;/h4&gt;&lt;h5 id="pl-400-exam-prep-creating-a-model-driven-power-app-form-form-view-chart--dashboard"&gt;PL-400 Exam Prep: Creating a Model-Driven Power App Form, Form, View, Chart &amp;amp; Dashboard
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/znDjjnhidrE"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-working-with-canvas-power-apps"&gt;PL-400 Exam Prep: Working with Canvas Power Apps
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/5lpdDl_omWg"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="configure-business-process-automation-5-10"&gt;Configure business process automation (5-10%)
&lt;/h3&gt;&lt;h4 id="configure-power-automate"&gt;Configure Power Automate
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;create and configure a flow&lt;/li&gt;
&lt;li&gt;configure steps to use Dataverse connector actions and triggers&lt;/li&gt;
&lt;li&gt;implement complex expressions in flow steps&lt;/li&gt;
&lt;li&gt;implement error handling&lt;/li&gt;
&lt;li&gt;troubleshoot flows by analyzing JSON responses from connectors&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implement-processes"&gt;Implement processes
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;create and configure business process flows&lt;/li&gt;
&lt;li&gt;create and configure business rules&lt;/li&gt;
&lt;li&gt;create, manage, and interact with business process flows by using server-side and client-side code&lt;/li&gt;
&lt;li&gt;troubleshoot processes&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-3"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-power-automate-flows/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Working with Power Automate Flows&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-implementing-business-process-flows-and-business-rules/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Implementing Business Process Flows and Business Rules&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-2"&gt;Videos
&lt;/h4&gt;&lt;h5 id="pl-400-exam-prep-business-process-automation-using-power-automate-cloud-flows"&gt;PL-400 Exam Prep: Business Process Automation Using Power Automate Cloud Flows
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/x67eOLf-mLA"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-designing-and-interacting-with-a-business-process-flow"&gt;PL-400 Exam Prep: Designing and Interacting with a Business Process Flow
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/ZEbQ69ocvvA"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-working-with-business-rules"&gt;PL-400 Exam Prep: Working with Business Rules
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/Xus4yaDRFVI"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="extend-the-user-experience-10-15"&gt;Extend the user experience (10-15%)
&lt;/h3&gt;&lt;h4 id="apply-business-logic-using-client-scripting"&gt;Apply business logic using client scripting
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;create JavaScript or TypeScript code that targets the Client API object model&lt;/li&gt;
&lt;li&gt;register an event handler&lt;/li&gt;
&lt;li&gt;create client-side scripts that target the Dataverse Web API&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-a-power-apps-component-framework-pcf-component"&gt;Create a Power Apps Component Framework (PCF) component
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;describe the PCF component lifecycle&lt;/li&gt;
&lt;li&gt;initialize a new PCF component&lt;/li&gt;
&lt;li&gt;configure a PCF component manifest&lt;/li&gt;
&lt;li&gt;implement the component interfaces&lt;/li&gt;
&lt;li&gt;package, deploy, and consume the component&lt;/li&gt;
&lt;li&gt;configure and use PCF Device, Utility, and WebAPI features&lt;/li&gt;
&lt;li&gt;test and debug PCF components by using the local test harness&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-a-command-button-function"&gt;Create a command button function
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;create commands&lt;/li&gt;
&lt;li&gt;design command button rules and actions&lt;/li&gt;
&lt;li&gt;edit the command bar by using the Ribbon Workbench&lt;/li&gt;
&lt;li&gt;manage dependencies between JavaScript libraries&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-4"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-implementing-client-side-scripting-on-model-driven-power-apps/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Implementing Client-Side Scripting on Model Driven Power Apps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-creating-a-power-apps-component-framework-pcf-control/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Creating a Power Apps Component Framework (PCF) Control&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-ribbon-command-buttons/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Working with Ribbon Command Buttons&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-3"&gt;Videos
&lt;/h4&gt;&lt;h5 id="pl-400-exam-prep-creating-a-basic-javascript-form-function-for-a-model-driven-power-app-form"&gt;PL-400 Exam Prep: Creating a Basic JavaScript Form Function for a Model Driven Power App Form
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/BOUMjXIE2k0"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-building--deploying-a-power-apps-component-framework-pcf-control"&gt;PL-400 Exam Prep: Building &amp;amp; Deploying a Power Apps Component Framework (PCF) Control
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/fH8sjQyZIQY"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-using-the-ribbon-workbench-to-create-a-simple-command-button"&gt;PL-400 Exam Prep: Using the Ribbon Workbench to Create a Simple Command Button
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/b1ILrxQKHhg"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="extend-the-platform-15-20"&gt;Extend the platform (15-20%)
&lt;/h3&gt;&lt;h4 id="create-a-plug-in"&gt;Create a plug-in
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;describe the plug-in execution pipeline&lt;/li&gt;
&lt;li&gt;design and develop a plug-in&lt;/li&gt;
&lt;li&gt;debug and troubleshoot a plug-in&lt;/li&gt;
&lt;li&gt;implement business logic by using pre-images and post-images&lt;/li&gt;
&lt;li&gt;perform operations on data by using the Organization service API&lt;/li&gt;
&lt;li&gt;optimize plug-in performance&lt;/li&gt;
&lt;li&gt;register custom assemblies by using the Plug-in Registration Tool&lt;/li&gt;
&lt;li&gt;develop a plug-in that targets a custom action message&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-custom-connectors"&gt;Create custom connectors
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;create a definition for the API&lt;/li&gt;
&lt;li&gt;configure API security&lt;/li&gt;
&lt;li&gt;use policy templates to modify connector behavior at runtime&lt;/li&gt;
&lt;li&gt;expose Azure Functions as custom connectors&lt;/li&gt;
&lt;li&gt;create custom connectors for public APIs by using Postman&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="use-platform-apis"&gt;Use platform APIs
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;interact with data and processes by using the Dataverse Web API or the Organization Service&lt;/li&gt;
&lt;li&gt;implement API limit retry policies&lt;/li&gt;
&lt;li&gt;optimize for performance, concurrency, transactions, and batching&lt;/li&gt;
&lt;li&gt;query the Global Discovery service to discover the URL and other information for an organization&lt;/li&gt;
&lt;li&gt;perform entity metadata operations with the Web API&lt;/li&gt;
&lt;li&gt;perform authentication by using OAuth&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="process-workloads"&gt;Process workloads
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;process long-running operations by using Azure Functions&lt;/li&gt;
&lt;li&gt;configure scheduled and event-driven function triggers in Azure Functions&lt;/li&gt;
&lt;li&gt;authenticate to the Microsoft Power Platform by using managed identities&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-5"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-building-deploying-debugging-plug-ins-using-c/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Building, Deploying &amp;amp; Debugging Plug-ins using C#&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-building-a-power-platform-custom-connector/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Building a Power Platform Custom Connector&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-the-microsoft-dataverse-web-api-and-processing-workloads/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Working with the Microsoft Dataverse Web API and Processing Workloads&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-4"&gt;Videos
&lt;/h4&gt;&lt;h5 id="pl-400-exam-prep-creating-a-microsoft-dataverse-plug-in-using-visual-studio-2019--c"&gt;PL-400 Exam Prep: Creating a Microsoft Dataverse Plug-in using Visual Studio 2019 &amp;amp; C#
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/j7jU8VcS8cg"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-deploying-a-microsoft-dataverse-plug-in-using-the-plug-in-registration-tool"&gt;PL-400 Exam Prep: Deploying a Microsoft Dataverse Plug-in using the Plug-in Registration Tool
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/11T7OdYx7UY"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-debugging-a-microsoft-dataverse-plug-in-using-trace-logging"&gt;PL-400 Exam Prep: Debugging a Microsoft Dataverse Plug-in using Trace Logging
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/QzI3NDABbPU"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-debugging-a-microsoft-dataverse-plug-in-using-the-plug-in-registration-tool"&gt;PL-400 Exam Prep: Debugging a Microsoft Dataverse Plug-in Using the Plug-in Registration Tool
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/J6ODPtt6Xd4"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-creating-a-custom-connector-for-an-azure-function"&gt;PL-400 Exam Prep: Creating a Custom Connector for an Azure Function
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/rGVVKuKNfdg"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-authenticating-into-the-microsoft-dataverse-web-api"&gt;PL-400 Exam Prep: Authenticating into the Microsoft Dataverse Web API
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/AmTcp-kGgpY"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-working-with-the-microsoft-dataverse-global-discovery-endpoint"&gt;PL-400 Exam Prep: Working with the Microsoft Dataverse Global Discovery Endpoint
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/1ztU0Ddt7RY"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-performing-common-operations-with-the-microsoft-dataverse-api"&gt;PL-400 Exam Prep: Performing Common Operations with the Microsoft Dataverse API
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/nfzua9P_Lxg"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-performing-batch-operations-using-the-microsoft-dataverse-web-api"&gt;PL-400 Exam Prep: Performing Batch Operations using the Microsoft Dataverse Web API
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/8iSuJQBsQOk"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="develop-integrations-5-10"&gt;Develop Integrations (5-10%)
&lt;/h3&gt;&lt;h4 id="publish-and-consume-events"&gt;Publish and consume events
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;publish an event by using the API&lt;/li&gt;
&lt;li&gt;publish an event by using the Plug-in Registration Tool&lt;/li&gt;
&lt;li&gt;register service endpoints including webhooks, Azure Service Bus, and Azure Event Hub&lt;/li&gt;
&lt;li&gt;implement a Dataverse listener for an Azure solution&lt;/li&gt;
&lt;li&gt;create an Azure Function that interacts with Microsoft Power Platform&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implement-data-synchronization"&gt;Implement data synchronization
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;configure entity change tracking&lt;/li&gt;
&lt;li&gt;read entity change records by using platform APIs&lt;/li&gt;
&lt;li&gt;create and use alternate keys&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-6"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-publishing-and-consuming-events/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Publishing and Consuming Events&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-implementing-data-synchronisation-using-microsoft-dataverse/" target="_blank" rel="noopener"
&gt;Exam PL-400 Revision Notes: Implementing Data Synchronisation using Microsoft Dataverse&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-5"&gt;Videos
&lt;/h4&gt;&lt;h5 id="pl-400-exam-prep-posting-microsoft-dataverse-events-to-azure-service-bus"&gt;PL-400 Exam Prep: Posting Microsoft Dataverse Events to Azure Service Bus
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/qnM39uKKK4c"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-registering--consuming-a-microsoft-dataverse-webhook-from-an-azure-function"&gt;PL-400 Exam Prep: Registering &amp;amp; Consuming a Microsoft Dataverse Webhook from an Azure Function
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/d-aJYR6D8Og"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-working-with-change-tracking-in-the-microsoft-dataverse-web-api"&gt;PL-400 Exam Prep: Working with Change Tracking in the Microsoft Dataverse Web API
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/5-3sDpR0rIM"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="pl-400-exam-prep-working-with-alternate-keys-in-the-microsoft-dataverse-web-api"&gt;PL-400 Exam Prep: Working with Alternate Keys in the Microsoft Dataverse Web API
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/RWgprFTkq0Y"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h4 id="general-exam-preparation-tips"&gt;General Exam Preparation Tips
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Hands-on preparation is &lt;strong&gt;essential&lt;/strong&gt; if you wish to do well in the exam. You should ideally set up a &lt;a class="link" href="https://powerapps.microsoft.com/en-us/developerplan/" target="_blank" rel="noopener"
&gt;Power Apps Developer Plan&lt;/a&gt; environment that you can use to experiment with the core functionality within the Power Platform.&lt;/li&gt;
&lt;li&gt;Keep abreast of the latest Microsoft Docs and &lt;a class="link" href="https://docs.microsoft.com/en-gb/learn/browse/?roles=developer&amp;amp;resource_type=learning%20path&amp;amp;products=power-platform?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Learning Path materials&lt;/a&gt; that are related to this exam, as the platform is continually changing all of the time.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/learn/certifications/exam-duration-question-types?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Familiarise yourself with the general format, length and expected types of questions within a Microsoft exam&lt;/a&gt;. If you want to get a feel for the level and type of questions to expect on the exam, &lt;a class="link" href="https://www.measureup.com/microsoft-practice-test-pl-400-power-platform-developer.html" target="_blank" rel="noopener"
&gt;you can also purchase an official practice test from Measure Up&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Due to the ongoing COVID-19 situation, you will more than likely have to sit your exam using the online proctored experience. &lt;a class="link" href="https://home.pearsonvue.com/Test-takers/OnVUE-online-proctoring.aspx" target="_blank" rel="noopener"
&gt;Take some time to familiarise yourself with the process involved here&lt;/a&gt;, and perform a system test well in advance of your exam date - the last thing you need on the day of the exam is to stress out due to a system or access issue.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;I hope that you&amp;rsquo;ve found this series useful. Good luck when sitting the exam, and let me know how you got on!&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Exam PL-400 Revision Notes: Publishing and Consuming Events</title><link>/exam-pl-400-revision-notes-publishing-and-consuming-events/</link><pubDate>Sun, 13 Jun 2021 00:00:00 +0000</pubDate><guid>/exam-pl-400-revision-notes-publishing-and-consuming-events/</guid><description>&lt;img src="/images/PowerApps-FI.png" alt="Featured image of post Exam PL-400 Revision Notes: Publishing and Consuming Events" /&gt;&lt;p&gt;Welcome to the eighteenth post in my series focused on providing a set of revision notes for the &lt;a class="link" href="https://docs.microsoft.com/en-us/learn/certifications/exams/pl-400?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;PL-400: Microsoft Power Platform Developer exam&lt;/a&gt;. Last time around, &lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-the-microsoft-dataverse-web-api-and-processing-workloads/" target="_blank" rel="noopener"
&gt;we explored some of the capabilities offered by the Microsoft Dataverse Web API&lt;/a&gt;, which can be particularly useful when you are building integrations targeting this platform. This post finished our discussion on the &lt;strong&gt;Extend the platform&lt;/strong&gt; area of the exam, which has a 15-20% total weighting. We now move into the final exam area, &lt;strong&gt;Develop Integrations&lt;/strong&gt; and our first subject area concerning events:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Publish and consume events&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;publish an event by using the API&lt;/li&gt;
&lt;li&gt;publish an event by using the Plug-in Registration Tool&lt;/li&gt;
&lt;li&gt;register service endpoints including webhooks, Azure Service Bus, and Azure Event Hub&lt;/li&gt;
&lt;li&gt;implement a Common Data Service listener for an Azure solution&lt;/li&gt;
&lt;li&gt;create an Azure Function that interacts with Power Platform&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Although this area of the exam has a somewhat low weighting (5-10%) when compared with the other subjects we&amp;rsquo;ve looked at, there is still some essential things to learn here that is not only relevant to the exam itself but also for your daily travels with the platform. Events are just one way in which you can integrate your Microsoft Dataverse environment alongside &lt;a class="link" href="https://azure.microsoft.com/en-gb/overview/?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;Microsoft Azure&lt;/a&gt;. Developing modern cloud applications involving core Microsoft products invariably means you must have a general awareness of the capabilities within Azure, so this topic provides an excellent opportunity to increase your knowledge in this area. Let&amp;rsquo;s dive in now to see what events are all about and how they relate to Azure!&lt;/p&gt;
&lt;p&gt;As with all posts in this series, the aim is to provide a broad outline of the core areas to keep in mind when tackling the exam, linked to appropriate resources for more focused study. Ideally, your revision should involve a high degree of hands-on testing and familiarity in working with the platform if you want to do well in this exam. It would help if you also understand working with plug-ins and the Plug-in Registration Tool, &lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-building-deploying-debugging-plug-ins-using-c/" target="_blank" rel="noopener"
&gt;which we&amp;rsquo;ve already covered in the series&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="what-are-events"&gt;What are Events?
&lt;/h3&gt;&lt;p&gt;You may be worried at this stage that events are a whole new concept that will take considerable time to understand. Fortunately, that&amp;rsquo;s not the case at all and, if you have good familiarity working with the &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/understand-the-data-context?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;IExecutionContext Interface&lt;/a&gt; from within a plug-in, you will find yourself right at home. This is because Events encapsulate all data points that we would typically work within our execution context - whether that be &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.iexecutioncontext.sharedvariables?view=dynamics-general-ce-9&amp;amp;WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;shared variables&lt;/a&gt;, &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.iexecutioncontext.outputparameters?view=dynamics-general-ce-9&amp;amp;WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;output parameters&lt;/a&gt;, &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.iexecutioncontext.businessunitid?view=dynamics-general-ce-9&amp;amp;WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Business Unit ID&lt;/a&gt; or more. An example of how an event can look, when passed out as a JSON object, can be seen below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;BusinessUnitId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;f64c9d1f-d076-ea11-a812-000d3a86a586&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;CorrelationId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dfe79039-5a08-4d0a-b4ee-9534625c8654&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Depth&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;InitiatingUserAzureActiveDirectoryObjectId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;00000000-0000-0000-0000-000000000000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;InitiatingUserId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c164a5aa-765e-4181-8771-537e8b1ebf3b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;InputParameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Entity:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Attributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;territorycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_freighttermscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_shippingmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isprivate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;followemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotbulkemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotsendmm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;emailaddress1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;john@domain.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;jobtitle&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Manager&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;customertypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;John Doe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isautocreate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ownerid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;EntityReference:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c164a5aa-765e-4181-8771-537e8b1ebf3b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isbackofficecustomer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotbulkpostalmail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotpostalmail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_addresstypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotphone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;createdon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/Date(1598771723000)/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;transactioncurrencyid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;EntityReference:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;785af3f0-d976-ea11-a812-000d3a86a586&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;transactioncurrency&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contactid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;haschildrencode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;modifiedby&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;EntityReference:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c164a5aa-765e-4181-8771-537e8b1ebf3b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;leadsourcecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;modifiedonbehalfby&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;preferredcontactmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Doe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;John&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;createdby&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;EntityReference:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c164a5aa-765e-4181-8771-537e8b1ebf3b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;educationcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;yomifullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;John Doe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotfax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;merged&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;customersizecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;marketingonly&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;owningbusinessunit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;EntityReference:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;f64c9d1f-d076-ea11-a812-000d3a86a586&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;businessunit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;shippingmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;creditonhold&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;modifiedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/Date(1598771723000)/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;participatesinworkflow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;preferredappointmenttimecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;exchangerate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;EntityState&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;FormattedValues&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;territorycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_freighttermscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_shippingmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isprivate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;followemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotbulkemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotsendmm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Send&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;customertypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isautocreate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isbackofficecustomer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotbulkpostalmail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotpostalmail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Active&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_addresstypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotphone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;createdon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2020-08-30T07:15:23-00:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;haschildrencode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;leadsourcecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Active&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;preferredcontactmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Any&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;educationcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotfax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;merged&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;customersizecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;marketingonly&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;shippingmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;creditonhold&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;modifiedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2020-08-30T07:15:23-00:00&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;participatesinworkflow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;preferredappointmenttimecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Morning&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RelatedEntities&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;4198516&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;IsExecutingOffline&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;IsInTransaction&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;IsOfflinePlayback&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;IsolationMode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;MessageName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Create&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Mode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OperationCreatedOn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/Date(1598771723000+0000)/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OperationId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;b1b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OrganizationId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9c5d5db0-47c7-4741-aa25-08eb4cdf59a3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OrganizationName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;orgad623a9e&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OutputParameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OwningExtension&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aa45df79-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sdkmessageprocessingstep&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;ParentContext&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;BusinessUnitId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;f64c9d1f-d076-ea11-a812-000d3a86a586&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;CorrelationId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dfe79039-5a08-4d0a-b4ee-9534625c8654&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Depth&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;InitiatingUserAzureActiveDirectoryObjectId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;00000000-0000-0000-0000-000000000000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;InitiatingUserId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c164a5aa-765e-4181-8771-537e8b1ebf3b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;InputParameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Entity:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Attributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;emailaddress1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;john@domain.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;jobtitle&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Manager&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Doe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;John&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;creditonhold&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotpostalmail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotfax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotphone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotbulkemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;followemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;preferredcontactmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotbulkpostalmail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;transactioncurrencyid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;EntityReference:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;785af3f0-d976-ea11-a812-000d3a86a586&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;transactioncurrency&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ownerid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;EntityReference:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c164a5aa-765e-4181-8771-537e8b1ebf3b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;preferredappointmenttimecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;customersizecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_shippingmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_freighttermscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;educationcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isautocreate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;leadsourcecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;shippingmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;participatesinworkflow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;marketingonly&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;territorycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isprivate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;isbackofficecustomer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;merged&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;donotsendmm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;address2_addresstypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;customertypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;haschildrencode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contactid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;EntityState&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;FormattedValues&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RelatedEntities&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SuppressDuplicateDetection&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;IsExecutingOffline&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;IsInTransaction&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;IsOfflinePlayback&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;IsolationMode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;MessageName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Create&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Mode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OperationCreatedOn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/Date(1598771723000+0000)/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OperationId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;b1b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OrganizationId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9c5d5db0-47c7-4741-aa25-08eb4cdf59a3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OrganizationName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;orgad623a9e&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OutputParameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;OwningExtension&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aa45df79-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sdkmessageprocessingstep&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;ParentContext&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;PostEntityImages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;PreEntityImages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;PrimaryEntityId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;PrimaryEntityName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RequestId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;bda24fe5-1f23-4c96-a4ab-34739a2f5628&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;SecondaryEntityName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;none&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;SharedVariables&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;IsAutoTransact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;DefaultsAddedFlag&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ChangedEntityTypes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;__type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;KeyValuePairOfstringstring:#System.Collections.Generic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Update&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Stage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;UserAzureActiveDirectoryObjectId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;00000000-0000-0000-0000-000000000000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;UserId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c164a5aa-765e-4181-8771-537e8b1ebf3b&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;PostEntityImages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;AsynchronousStepPrimaryName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Attributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;John Doe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contactid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;EntityState&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;FormattedValues&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;KeyAttributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LogicalName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RelatedEntities&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RowVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;PreEntityImages&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;PrimaryEntityId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;a2b1d88b-90ea-ea11-a815-000d3a86a3ce&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;PrimaryEntityName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;RequestId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;bda24fe5-1f23-4c96-a4ab-34739a2f5628&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;SecondaryEntityName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;none&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;SharedVariables&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;IsAutoTransact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;DefaultsAddedFlag&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Stage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;UserAzureActiveDirectoryObjectId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;00000000-0000-0000-0000-000000000000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;UserId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c164a5aa-765e-4181-8771-537e8b1ebf3b&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The main difference with events is how we consume them; that is, &lt;em&gt;outside&lt;/em&gt; of the application, as opposed to &lt;em&gt;inside&lt;/em&gt;. There are a variety of reasons why it may be desirable to do this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As we saw when discussing plug-ins, there are some particular limitations that sandbox processing can impose on your custom code - such as the restricted use of third party libraries and the 2-minute maximum execution time. However, by processing these operations external from Microsoft Dataverse, developers can circumvent these restrictions while still benefitting from working with the same type of information typically available as part of a standard plug-in.&lt;/li&gt;
&lt;li&gt;For situations where your environment is processing hundreds or even thousands of record changes each hour, that then need to be processed asynchronously, events provide the most streamlined mechanism for achieving this. Also, it helps to reduce the reliance on the platform and the applications Asynchronous service in performing complex processing of these requests; instead, they can be straightforwardly &amp;ldquo;passed on&amp;rdquo; to a dedicated service responsible for this.&lt;/li&gt;
&lt;li&gt;It may be necessary to immediately trigger an external endpoint or API as soon as a user creates, updates or deletes a table row. By using events alongside Webhooks (more on this shortly), developers have a streamlined mechanism to meet this requirement.&lt;/li&gt;
&lt;li&gt;With the recent changes announced around &lt;a class="link" href="https://docs.microsoft.com/en-us/power-platform/admin/api-request-limits-allocations?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;API request&lt;/a&gt; and &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/api-limits?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;service protection limits&lt;/a&gt; at the platform level, developers may struggle to use the traditional plug-in assembly route to process complex operations. As such, we can realise benefits by moving this processing outside of the application and, as part of this, avoid hitting any nasty error messages resulting from an overage in the number of processed platform requests.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In most cases, you will typically use one of several different Microsoft Azure services when processing events received from the application. However, there are options available to integrate alongside other cloud platforms or systems. For the exam, focusing and having an awareness of the Azure options will be essential.&lt;/p&gt;
&lt;h3 id="understanding-service-endpoints--the-azure-service-bus"&gt;Understanding Service Endpoints &amp;amp; the Azure Service Bus
&lt;/h3&gt;&lt;p&gt;There are two core concepts to understand alongside events - &lt;strong&gt;service endpoints&lt;/strong&gt; and the &lt;strong&gt;Azure Service Bus&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Service Endpoints&lt;/strong&gt;: This defines the &lt;em&gt;location&lt;/em&gt; you wish to write your events out to for further processing. In pretty much all cases, you will want to use the Plug-in Registration Tool to create your service endpoint, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/reference/entities/serviceendpoint?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;but you can also deploy one programmatically via the web API&lt;/a&gt;. You can also use a service endpoint to &lt;em&gt;receive&lt;/em&gt; incoming requests back into Microsoft Dataverse for processing. Once defined, you must then register the appropriate steps that will trigger your endpoint request, much in the same way as defining a plug-in step (e.g. Update on Contact, Delete on Lead, etc.). An advantage with this is that we can include pre/post table images as part of each event payload. However, the critical thing to remember is that we must specify these as asynchronous operations; synchronous calls are not allowed. In most cases, your service endpoint will target an Azure Service Bus queue, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/work-event-data-azure-event-hub-solution?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;but you can also configure an Azure Event Hub endpoint as well&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-gb/azure/service-bus-messaging/service-bus-messaging-overview?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Azure Service Bus&lt;/strong&gt;&lt;/a&gt;: Depending on the type of integration you are attempting to perform, the synchronous (i.e. all at once) processing of information may not be needed or desirable. This could be down to the single fact that the number of potential requests to process will be too high. For when this is relevant, Azure Service Bus comes into the equation by offering a decoupled, asynchronous mechanism to receive, analyse and route multiple requests to an intended destination - whether this is a database, another endpoint or a storage location. The service bus will process all events it receives in order, holding onto each request for as long as is necessary before handing it off. As well as allowing for a predictable flow of information, it can also provide assurances from a failure standpoint; if, for example, the backend endpoint goes offline for whatever reason, messages will remain in the queue and resume processing as soon as the endpoint comes back online. Developers have flexibility over the type of Azure Service Bus listener service to implement, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/write-listener-application-azure-solution?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;which Microsoft outlines in this article&lt;/a&gt;, but the most common scenario is to use a &lt;em&gt;queue&lt;/em&gt;. We can also define the format of events that get written out by the Azure Service Bus listener but, in most cases, outputting this as JSON will be the recommended option.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="demo-posting-microsoft-dataverse-events-to-azure-service-bus"&gt;Demo: Posting Microsoft Dataverse Events to Azure Service Bus
&lt;/h3&gt;&lt;p&gt;In this video, we&amp;rsquo;ll walk through how to deploy out an Azure Service Bus resource and configure a service endpoint to receive requests from Microsoft Dataverse:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/qnM39uKKK4c"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="webhooks-overview"&gt;Webhooks Overview
&lt;/h3&gt;&lt;p&gt;A &lt;a class="link" href="https://en.wikipedia.org/wiki/Webhook" target="_blank" rel="noopener"
&gt;webhook&lt;/a&gt; is a lightweight mechanism for integrating multiple Web API&amp;rsquo;s. It operates on a publish and subscribe model; namely, we &lt;em&gt;publish&lt;/em&gt; an event out, and an external endpoint &lt;em&gt;subscribes&lt;/em&gt; to each event, processing it as it sees fit. As semi-automated, standard HTTP requests in their simplest form, they conform broadly to this pattern and - if they are a new concept - you should experience little difficulty in understanding them if you&amp;rsquo;ve previously worked with RESTful Web API&amp;rsquo;s. Webhooks are commonplace these days, both in the Microsoft world and across other vendors as well. For example, &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/azure-monitor/platform/alerts-log-webhook?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;Azure supports the ability to write out any log alert event as a webhook to an endpoint of your choosing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From a Microsoft Dataverse perspective, developers can register custom webhooks to any endpoint of their choosing. We can handle authentication into these endpoints in one of four ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HttpHeader&lt;/strong&gt;: Here, we must declare the appropriate header key/value pair values that will allow us to authenticate into the endpoint. HttpHeader is the option you will need to go for if you use Basic or OAuth 2.0 authentication via an authorization bearer token.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebhookKey&lt;/strong&gt;: For this option, the platform will append a query string parameter called &lt;strong&gt;code&lt;/strong&gt; onto the URL, whose value then allows you to authenticate into the API. If your endpoint is an &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;Azure Function&lt;/a&gt;, then this is a possible candidate option for you to consider using, as all requests targeting your function will expect this by default.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HttpQueryString&lt;/strong&gt;: Best suited for endpoints that support shared access signature (SAS) authentication, developers specify the appropriate key/value pairs for this, in the same manner as the &lt;strong&gt;HttpHeader&lt;/strong&gt; option. The main difference here is that the platform will instead add these values onto the endpoint URL as query parameters.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anonymous&lt;/strong&gt;: Finally, it is possible to call any endpoint that does not enforce authentication. To do this, ensure you select the &lt;strong&gt;HttpHeader&lt;/strong&gt; authentication type and supply a single key/value pair containing anything you like; otherwise, you may get errors when registering the Webhook.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, similar to working with service endpoints, we define the appropriate steps and Pre/Post images that will trigger the webhook call. The resulting operation will then initiate an HTTP POST request to your endpoint, containing the event data illustrated in the example earlier.&lt;/p&gt;
&lt;p&gt;An important question arises around the usage of Webhooks in comparison to the Azure Service Bus. Certainly, Webhooks are the most attractive option to consider if you are integrating alongside non-Azure based services, your expected volume of API calls are low, or you need your request to execute synchronously. However, they will ultimately only be as reliable as the endpoint that you are contacting. Also, for high volume requests where we can tolerate a delay in processing, Webhooks will likely fall over pretty quickly. When this occurs, the Service Endpoint and Azure Service Bus option represent your optimal choice instead.&lt;/p&gt;
&lt;p&gt;For more information on how to work with Webhooks, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/use-webhooks?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;consult this Microsoft Docs article,&lt;/a&gt; which also provides some examples for you to work through.&lt;/p&gt;
&lt;h3 id="demo-registering--consuming-a-microsoft-dataverse-webhook-from-an-azure-function"&gt;Demo: Registering &amp;amp; Consuming a Microsoft Dataverse Webhook from an Azure Function
&lt;/h3&gt;&lt;p&gt;A common mechanism to work with Webhooks is via an Azure Function. With this in mind, check out the below video, which will show you how to consume webhook events in this manner:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/d-aJYR6D8Og"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;We&amp;rsquo;re on the home stretch now, with only one more topic to look at before we wrap up the series. Next time around, we&amp;rsquo;ll look at how you can enable some specific capabilities on your Microsoft Dataverse to support data synchronisation scenarios.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Exam PL-400 Revision Notes: Building a Power Platform Custom Connector</title><link>/exam-pl-400-revision-notes-building-a-power-platform-custom-connector/</link><pubDate>Sun, 30 May 2021 00:00:00 +0000</pubDate><guid>/exam-pl-400-revision-notes-building-a-power-platform-custom-connector/</guid><description>&lt;img src="/images/PowerApps-FI.png" alt="Featured image of post Exam PL-400 Revision Notes: Building a Power Platform Custom Connector" /&gt;&lt;p&gt;Welcome to the sixteenth post in my series focused on providing a set of revision notes for the &lt;a class="link" href="https://docs.microsoft.com/en-us/learn/certifications/exams/pl-400?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;PL-400: Microsoft Power Platform Developer exam&lt;/a&gt;. In the last post, &lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-building-deploying-debugging-plug-ins-using-c/" target="_blank" rel="noopener"
&gt;we saw how developers could leverage C# code as part of plug-ins to implement complex business logic within Microsoft Dataverse&lt;/a&gt;. We can now examine another extensibility component within the &lt;strong&gt;Extend the platform&lt;/strong&gt; section of the exam as we discuss how to &lt;strong&gt;Create custom connectors.&lt;/strong&gt; For this, Microsoft expects candidates to demonstrate knowledge of the following subjects:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Create custom connectors&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;create a definition for the API&lt;/li&gt;
&lt;li&gt;configure API security&lt;/li&gt;
&lt;li&gt;use policy templates to modify connector behavior at runtime&lt;/li&gt;
&lt;li&gt;expose Azure Functions as custom connectors&lt;/li&gt;
&lt;li&gt;create custom connectors for public APIs by using Postman&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Depending on the type of system you wish to integrate alongside the Power Platform, a custom connector may suit your needs, thereby allowing you to leverage an existing API you have constructed or an entirely new one. What&amp;rsquo;s more, developers can then take these custom connectors and expose them out to other organisations or perhaps even to every other Power Platform user the world over. In short, they are a compelling feature to leverage. So let&amp;rsquo;s take a look at what they are all about and how you can get started with them.&lt;/p&gt;
&lt;p&gt;As with all posts in this series, the aim is to provide a broad outline of the core areas to keep in mind when tackling the exam, linked to appropriate resources for more focused study. Ideally, your revision should involve a high degree of hands-on testing and familiarity with the platform if you want to do well in this exam.&lt;/p&gt;
&lt;h3 id="custom-connectors-overview"&gt;Custom Connectors Overview
&lt;/h3&gt;&lt;p&gt;As we have seen when evaluating both &lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-canvas-apps/" target="_blank" rel="noopener"
&gt;canvas Power Apps&lt;/a&gt; and &lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-power-automate-flows/" target="_blank" rel="noopener"
&gt;Power Automate flows&lt;/a&gt;, developers can use well over 325+ standard connectors, covering various Microsoft and other third-party systems, such as &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/salesforce?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Salesforce&lt;/a&gt;, &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/sap?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;SAP&lt;/a&gt; and &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/oracle?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Oracle Database&lt;/a&gt;. This should give you everything you need to get disparate systems talking to each other within the Power Platform&amp;hellip; in most situations. Custom connectors are there to provide additional headroom for when this is not possible to achieve. Powered by &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/api-management/api-management-key-concepts?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;Azure API Management&lt;/a&gt; underneath the hood, &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom Connectors&lt;/a&gt; provide a guided, visual mechanism of exposing an entirely custom API, alongside its various operations, as an additional connector for the following services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Canvas Power Apps&lt;/li&gt;
&lt;li&gt;Power Automate Flows&lt;/li&gt;
&lt;li&gt;Logic Apps&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Developers can then utilise these in much the same manner as the other connectors discussed previously. For example, you can define trigger actions from your API, pull in entire datasets or perform core operations, such as updating an existing record. The capabilities within your current API ultimately dictate all of this, so, in some situations, developers may need to author a new API themselves and use services such as &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;Azure Functions&lt;/a&gt; or &lt;a class="link" href="https://docs.microsoft.com/en-gb/azure/app-service/overview?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;Azure Web Apps&lt;/a&gt; to host it. Further discussion on how to do this is beyond the scope for this blog post and, indeed, the exam itself; candidates should instead focus their attention on the various supported options for connectors and - most crucially - the outline steps for creating one, which the below diagram summarises well:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/CustomConnectors-ProcessDiagram.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The sections that follow will dive into these steps in further detail&amp;hellip;&lt;/p&gt;
&lt;h3 id="supported-scenarios"&gt;Supported Scenarios
&lt;/h3&gt;&lt;p&gt;&amp;hellip;but first, we should touch upon some of the situations where you may need to consider using a custom connector:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Integrating with On-Premise APIs&lt;/strong&gt;: As custom connectors fully support using the &lt;a class="link" href="https://docs.microsoft.com/en-us/power-automate/gateway-reference?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;on-premises data gateway&lt;/a&gt;, they provide the securest and most streamlined mechanism for making any internal APIs accessible for use within your cloud systems.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incorporating REST / SOAP APIs&lt;/strong&gt;: It is worth noting that custom connectors only support APIs of these particular types. Specifically, canvas Power Apps and Power Automates can only work with HTTP REST APIs; Logic Apps support SOAP APIs too. For situations where your existing API does not meet these requirements, it will be impossible for you to use them with custom connectors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sharing an API within an Organisation&lt;/strong&gt;: For situations where you envision only contacting an API a single time within, let&amp;rsquo;s say, a Power Automate flow, &lt;a class="link" href="https://docs.microsoft.com/en-gb/connectors/webcontents/#invoke-an-http-request?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;using an HTTP action step&lt;/a&gt; may be the most prudent (and fastest) option to consider. Going beyond this, if you think you will need to share out or utilise the same action steps across multiple flows and, also, you wish to provide a simplified means of accessing the same set of actions, a custom connector will fit your needs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ISV Solution Development&lt;/strong&gt;: Many of the custom connectors available today have their origin as internally developed ones, &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/submit-certification?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;which have then been certified by Microsoft and published for general use&lt;/a&gt;. By doing this, ISV developers can help to drive further usage of their existing solutions and even introduce them to an entirely new audience.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="reviewing-custom-connector-creation-options"&gt;Reviewing Custom Connector Creation Options
&lt;/h3&gt;&lt;p&gt;Developers have a few different options available to them when creating a custom connector. But, almost always, you will start from within the &lt;a class="link" href="https://make.powerapps.com/" target="_blank" rel="noopener"
&gt;Power Apps Maker Portal.&lt;/a&gt; Then, by navigating to &lt;strong&gt;Data&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Custom Connectors&lt;/strong&gt;, you can locate the appropriate option to kick off their creation:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/PowerApps-MakerPortal-CustomConnectors.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The best thing about this is that we don&amp;rsquo;t necessarily need to reinvent the wheel, provided we have existing definitions of our API&amp;rsquo;s already built out. At the time of writing this post, developers can utilise the following, if available:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.postman.com/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Postman&lt;/strong&gt;&lt;/a&gt;: If you&amp;rsquo;ve never used this tool before and find yourself regularly poking into numerous API&amp;rsquo;s, then this tool could help you out. In short, the app provides you with a local &amp;ldquo;sandbox&amp;rdquo; to mock-up, execute and inspect the results of various HTTP actions. It has numerous valuable features, such as being able to store requests in collections, handling multiple different types of authentication, and providing online synchronisation capabilities. From a custom connector standpoint, you can use Postman to build out the various action requests that your API exposes out and then import these in as a collection file into the Power Apps Maker Portal. Note as part of this that only V1 Postman collections are supported. &lt;a class="link" href="https://learning.postman.com/docs/sending-requests/intro-to-collections/" target="_blank" rel="noopener"
&gt;There&amp;rsquo;s a great article on the Postman website that shows you how to get started with collections&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://swagger.io/specification/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;OpenAPI&lt;/strong&gt;:&lt;/a&gt; Similar in some respects to a Postman collection, an OpenAPI definition is instead intended as a complete declaration of all the capabilities stored within an API, using an open standard. Developers would typically generate this for their API to provide other developers with a valuable resource when working with the API in question. Thankfully, &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-openapi-definition?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;if you use Azure API Management as the backend for your API, you can quickly generate the appropriate specification using the Azure Portal&lt;/a&gt;. &lt;a class="link" href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?view=aspnetcore-3.1&amp;amp;WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;It is also possible to build this directly into your ASP.NET Core app&lt;/a&gt; if that is what your API is using; I&amp;rsquo;m sure it&amp;rsquo;s possible to do the same for other languages/stacks too, but I&amp;rsquo;ll leave that to you to find out. 😀&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://flow.microsoft.com/en-us/blog/import-a-connector-from-github-as-a-custom-connector" target="_blank" rel="noopener"
&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;: Best for situations where you have built out a connector already or wish to leverage an existing, certified connector, you can very quickly bring it in from a GitHub repository of your choosing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the options listed in the screenshot above, it&amp;rsquo;s worth focusing on each of these in more detail:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create from blank&lt;/strong&gt;: Using this option, you must define each of the individual elements of your API, such as its security, actions and triggers. If you are unsure where to start and don&amp;rsquo;t have an appropriate Postman/OpenAPI definition at your disposal, then this will be the most suitable option to choose.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Import an OpenAPI file&lt;/strong&gt;: With this, you can import the OpenAPI JSON definition file from your local computer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Import an OpenAPI from URL&lt;/strong&gt;: If your definition is instead available as part of a publicly accessible URL, use this option to import it instead.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Import a Postman Collection&lt;/strong&gt;: This choice bears some similarities to the OpenAPI options, as it will let you import a JSON collection file generated from Postman. As mentioned earlier, make sure you export this as a V1 definition from the Postman app.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regardless of which option you select, you can then populate some standard settings for your connector, such as its display name, image and description. At this point, you can also override the URL scheme, the host URL and the Base URL, if required:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/PowerApps-CustomConnectors-GeneralSettings.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h3 id="handling-api-security"&gt;Handling API Security
&lt;/h3&gt;&lt;p&gt;A custom connector can be secured using multiple mechanisms. These authentication profiles do not store sensitive credentials within the connector. Instead, they &lt;em&gt;define&lt;/em&gt; the authentication options that users of the connector must set when using your custom connector for the first time. In this manner, it&amp;rsquo;s possible to connect to multiple instances of your API on the same tenant, using different credentials. A custom connector can support the following four types of authentication methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No Authentication&lt;/strong&gt;: Best for when you are exposing a publically available API that requires no underlying authentication. This option, quite obviously, provides zero security for your API.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Basic Authentication&lt;/strong&gt;: &lt;a class="link" href="https://en.wikipedia.org/wiki/Basic_access_authentication" target="_blank" rel="noopener"
&gt;Utilising the same authentication method as the defined HTTP standard&lt;/a&gt;, here you outline details of the user name and password parameter labels that users must provide for your custom connector. I would typically advise against using Basic Authentication wherever possible, as it doesn&amp;rsquo;t afford the best security for your custom connector or API itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Key&lt;/strong&gt;: Here, you provide the details for an API Key that the custom connector includes as part of either the header or as a query parameter on the URL itself. Many of the Azure Cognitive Services API&amp;rsquo;s use API Key&amp;rsquo;s as their authentication mechanism. API Key&amp;rsquo;s suffer from the same security failings as Basic Authentication and, as such, should be avoided unless necessary.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OAuth 2.0&lt;/strong&gt;: The recommended and most secure option for your custom connector, and also one that integrates neatly alongside Azure Active Directory (AAD) and a variety of other services, such as Google and Facebook. To see an example of how to set this up using an Azure App Registration for an Azure Function, &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/create-custom-connector-aad-protected-azure-functions#create-a-custom-connector-for-your-azure-function?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;you can consult the following Microsoft Docs article.&lt;/a&gt; In short, though, using AAD OAuth 2.0 requires you to set up an &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;app registration&lt;/a&gt; on the appropriate tenant, which then exposes out the details you can use when defining your profile.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="working-with-policy-templates"&gt;Working with Policy Templates
&lt;/h3&gt;&lt;p&gt;If you&amp;rsquo;ve had some experience working with Azure API Management or &lt;a class="link" href="https://crmchap.co.uk/building-resource-manager-templates-for-azure-api-management-logic-apps/" target="_blank" rel="noopener"
&gt;have been following my blog religiously&lt;/a&gt;, this topic might feel somewhat familiar. To fine-tune how your custom connector ultimately interacts with your API, you can perform various manipulation activities as each action/trigger gets fired. These are brought together within a list of re-usable templates that cover common operations that may be necessary and, from an Azure API Management standpoint, &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-policies?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;map back to the various policy definitions that this service supports&lt;/a&gt;. The list below provides an overview of the types of actions policy templates support:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/policy-templates/dynamichosturl/dynamichosturl?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Set host URL&lt;/strong&gt;&lt;/a&gt;: Using this, you can replace the URL for the request with an entirely new one.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/policy-templates/routerequesttoendpoint/routerequesttoendpoint?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Route request&lt;/strong&gt;&lt;/a&gt;: Let&amp;rsquo;s you route the action to a completely different path on the same URL from the one specified.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/policy-templates/setheader/setheader?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Set HTTP header&lt;/strong&gt;&lt;/a&gt;: Allows you to append, skip or replace a Header value as part of the API request. For example, you could supply a &lt;a class="link" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Cache-Control&lt;/strong&gt;&lt;/a&gt; value to help improve performance when the custom connector uses your API.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/policy-templates/setqueryparameter/setqueryparameter?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Set query string parameter&lt;/strong&gt;&lt;/a&gt;: Allows you to append, skip or replace a query parameter value as part of the API request. For example, if your API is an OData endpoint, you might want to append a default &lt;strong&gt;$top&lt;/strong&gt; query parameter to limit the number of returned results each time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the time of writing this post, there are also a couple of additional policy templates available marked as Preview, which allows you to do things such as &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/policy-templates/convertobjecttoarray/convertobjecttoarray?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;converting objects into arrays&lt;/a&gt; and &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/policy-templates/convertarraytoobject/convertarraytoobject?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;vice-versa&lt;/a&gt;. Microsoft will not assess candidates on preview features within exams, so it is unlikely that you will need to know about these as part of your exam prep.&lt;/p&gt;
&lt;h3 id="demo-creating-a-custom-connector-for-an-azure-function"&gt;Demo: Creating a Custom Connector for an Azure Function
&lt;/h3&gt;&lt;p&gt;To help you better understand the process involved in building out a custom connector, check out the video below, where we will build out one that integrates alongside an Azure Function app:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/rGVVKuKNfdg"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;That pretty much wraps it up for the basics on custom connectors, which should be all you need to know for the exam. In the next post, we&amp;rsquo;ll look at how you can leverage the Microsoft Dataverse Web API to perform various operations and manage more complex workloads.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Exam PL-400 Revision Notes: Building, Deploying &amp; Debugging Plug-ins using C#</title><link>/exam-pl-400-revision-notes-building-deploying-debugging-plug-ins-using-c/</link><pubDate>Sun, 23 May 2021 00:00:00 +0000</pubDate><guid>/exam-pl-400-revision-notes-building-deploying-debugging-plug-ins-using-c/</guid><description>&lt;img src="/images/PowerApps-FI.png" alt="Featured image of post Exam PL-400 Revision Notes: Building, Deploying &amp; Debugging Plug-ins using C#" /&gt;&lt;p&gt;Welcome to the fifteenth post in my series focused on providing a set of revision notes for the &lt;a class="link" href="https://docs.microsoft.com/en-us/learn/certifications/exams/pl-400?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;PL-400: Microsoft Power Platform Developer exam&lt;/a&gt;. In the previous post, we finished our discussion of the &lt;strong&gt;Extend the user experience&lt;/strong&gt; exam area by evaluating &lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-ribbon-command-buttons/" target="_blank" rel="noopener"
&gt;command buttons and demonstrating how valuable the Ribbon Workbench tool is&lt;/a&gt; in helping us fine-tune aspects of a &lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-model-driven-power-apps/" target="_blank" rel="noopener"
&gt;model-driven Power App&amp;rsquo;s interface&lt;/a&gt;. This topic rounded off our discussion of the &lt;strong&gt;Extend the user experience&lt;/strong&gt; topic, meaning that we now move into a new section titled &lt;strong&gt;Extend the platform&lt;/strong&gt;. This area has equal weighting (15-20%), and the first topic concerns how we &lt;strong&gt;Create a plug-in&lt;/strong&gt;. Specifically, candidates must demonstrate knowledge of the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Create a plug-in&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;describe the plug-in execution pipeline&lt;/li&gt;
&lt;li&gt;design and develop a plug-in&lt;/li&gt;
&lt;li&gt;debug and troubleshoot a plug-in&lt;/li&gt;
&lt;li&gt;implement business logic by using pre-images and post-images&lt;/li&gt;
&lt;li&gt;perform operations on data by using the Organization service API&lt;/li&gt;
&lt;li&gt;optimize plug-in performance&lt;/li&gt;
&lt;li&gt;register custom assemblies by using the Plug-in Registration Tool&lt;/li&gt;
&lt;li&gt;develop a plug-in that targets a custom action message&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Developers who have previously worked with Dynamics 365 or Dynamics CRM should have very little trouble getting to grips with plug-ins, as they have been a mainstay within these applications for well over a decade now. Notwithstanding this, it&amp;rsquo;s always helpful to get a refresher on even the most familiar of topics 😉. With that in mind, let&amp;rsquo;s dive in!&lt;/p&gt;
&lt;p&gt;As with all posts in this series, the aim is to provide a broad outline of the core areas to keep in mind when tackling the exam, linked to appropriate resources for more focused study. Ideally, your revision should involve a high degree of hands-on testing and familiarity with the platform if you want to do well in this exam. I would also recommend that you have a good general knowledge of working with the &lt;a class="link" href="https://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29" target="_blank" rel="noopener"
&gt;C# programming language&lt;/a&gt; before approaching plug-in development for the first time. &lt;a class="link" href="https://dotnet.microsoft.com/learn/csharp" target="_blank" rel="noopener"
&gt;Microsoft has published a whole range of introductory material to help you learn the language quickly.&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="what-is-a-plug-in"&gt;What is a Plug-in?
&lt;/h3&gt;&lt;p&gt;In the series so far, we&amp;rsquo;ve already touched upon the following functional tools that developers may leverage when dealing with complex business requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-implementing-business-process-flows-and-business-rules/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Business Rules&lt;/strong&gt;&lt;/a&gt;: These provide an excellent mechanism for handling simple logic, targeting both model-driven app forms and platform-level operations.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-working-with-power-automate-flows/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Power Automate&lt;/strong&gt;&lt;/a&gt;: Using flows authored by this tool, you can typically go the extra mile compared with classic workflows, thereby allowing you to integrate multiple systems when processing asynchronous actions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-pl-400-revision-notes-implementing-client-side-scripting-on-model-driven-power-apps/" target="_blank" rel="noopener"
&gt;JavaScript&lt;/a&gt;:&lt;/strong&gt; For situations where Business Rules can&amp;rsquo;t meet your particular requirement, and you need specific logic to trigger as a user is working on a model-driven form, this is the best tool in your arsenal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are great, but there may be situations where they are unsuitable due to the sheer complexity of the business logic you are trying to implement. Also, some of the above tools do not support the ability to carry out synchronous actions (i.e. ones that happen straight away, as the user creates, updates, deletes etc, rows in the application). Finally, it may be that you need to work with some specific elements of the SDK that are not exposed out straightforwardly via alternative routes. In these situations, a custom-authored plug-in is the only solution you can turn to.&lt;/p&gt;
&lt;p&gt;So what are they then? Plug-ins allow developers to write either C# or VB.NET code, which is then registered within the application as a .NET Framework class library (DLL) and executed based on specific conditions you specify within its configuration. For example, when a user creates a Contact, retrieve the details of the parent Account row and update the Contact to match. Developers will use Visual Studio when authoring a plug-in, typically using a class library project template. The &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/developer-tools?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Microsoft Dataverse SDK&lt;/a&gt; provides several modules that expose various operations that a plug-in can support. Some of the other things that plug-ins support include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Both synchronous and asynchronous execution.&lt;/li&gt;
&lt;li&gt;Custom un-secure/secure configuration properties that can modify the behaviour of a plug-in at runtime. For example, by providing credentials to a specific environment to access.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/utilising-prepost-entity-images-in-a-dynamics-crm-plugin/" target="_blank" rel="noopener"
&gt;Pre and Post Table (previously known as Entity) Images&lt;/a&gt;, snapshots of how a record and its related attributes looked before and after a platform level operation occurs.&lt;/li&gt;
&lt;li&gt;For specific operations, such as Update, plug-ins can also support filtering attributes - basically, a list of defined columns that, when modified, will cause the plug-in to trigger.&lt;/li&gt;
&lt;li&gt;Being able to specify the execution order for one or multiple plug-in steps. This capability can be helpful when you need to ensure a set of steps execute in your desired order.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These days, thanks to Business Rules and Power Automate, we see the lessening importance of plug-ins, and, typically, you would want to avoid using them straight out the gate. However, they still have a place and, when used appropriately, become the only mechanism you can resort to when working with complicated business logic.&lt;/p&gt;
&lt;h3 id="understanding-messages-the-execution-pipeline--steps"&gt;Understanding Messages, the Execution Pipeline &amp;amp; Steps
&lt;/h3&gt;&lt;p&gt;Before we start diving into building a plug-in for the first time, it&amp;rsquo;s prudent to provide an overview of the three core concepts that every plug-in developer needs to know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Messages&lt;/strong&gt;: These define a specific, platform level operation that the SDK exposes out. Some of the more commonly used Messages within the application include &lt;strong&gt;Create&lt;/strong&gt;, &lt;strong&gt;Update&lt;/strong&gt; or &lt;strong&gt;Delete&lt;/strong&gt;. Some system tables may have their own set of unique Messages; &lt;strong&gt;CalculatePrice&lt;/strong&gt; is an excellent example of this. From a plug-in perspective, developers essentially &amp;ldquo;piggyback&amp;rdquo; onto these operations as they are performed and inject their custom code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execution Pipeline&lt;/strong&gt;: As a user triggers a particular message, the application processes it using a defined set of stages, known as the execution pipeline. &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/event-framework#event-execution-pipeline?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;These are discussed in detail in this Microsoft Docs article&lt;/a&gt;, but the key ones we need to be aware of are:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PreValidation&lt;/strong&gt;: At this stage, the database transaction has not started. Also, the application has not yet performed any appropriate security checks, potentially meaning that the operation may fail if the user does not have the correct security privileges.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostValidation&lt;/strong&gt;: Here, the database transaction has already started. The platform knows at this stage that no security constraints will prevent the operation from completing, but the transaction may still fail for other reasons.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostOperation&lt;/strong&gt;: Although the database transaction has still not completed at this stage, the core operation of the message (executed within the &lt;strong&gt;MainOperation&lt;/strong&gt; stage) will almost certainly commit successfully, assuming no errors occur via a custom plug-in.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A failure at any of these stages will cause the database transaction to roll back entirely, returning any affected row(s) to their original state. Now, from a plug-in perspective, the execution pipeline is exposed out to developers as stages where your custom code can execute. This can provide developers with a high degree of flexibility and capability when running their custom code. As a general rule of thumb, developers would use each of these stages under the following circumstances:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PreValidation&lt;/strong&gt;: Use this stage to perform checks to cancel the operation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostValidation&lt;/strong&gt;: This stage is handy for modifying any values before they hit the database. Doing this at this stage would also prevent triggering another platform Message.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostOperation&lt;/strong&gt;: Use this stage for when you need to carry out additional logic not related to the current record or potentially provide additional information back to the caller after the platform completes the core operation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Developers will typically need to give some thought towards the execution pipeline and the most appropriate one to select, based on the requirements being worked with.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Steps&lt;/strong&gt;: Simply writing a plug-in class and deploying out the library is not sufficient to trigger your custom logic. Developers must also provide a set of &amp;ldquo;instructions&amp;rdquo;, commonly known as Steps, that &lt;em&gt;tell&lt;/em&gt; the application when and where to execute your custom code. It is here where both the Message and Execution Pipeline come into play, and you would always specify this information when creating a Step. Additional info you can include here includes the execution order, whether the plug-in will execute synchronously or not and the display name of the Step when viewed within the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will see shortly how these topics come into play as part of using the Plug-in Registration Tool.&lt;/p&gt;
&lt;h3 id="building-your-first-plug-in-pre-requisites"&gt;Building Your First Plug-In: Pre-Requisites
&lt;/h3&gt;&lt;p&gt;Before you start thinking about developing a plug-in, you need to make sure that you have a few things installed onto your development machine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://visualstudio.microsoft.com/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Visual Studio&lt;/strong&gt;&lt;/a&gt;: I would recommend using Visual Studio 2019 where possible. If you don&amp;rsquo;t have a Visual Studio/MSDN subscription, we can use the Community Edition instead.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A Microsoft Dataverse Environment&lt;/strong&gt;: Because where else are you going to deploy out and test your plug-in? 😀&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowledge of C#  / VB.NET&lt;/strong&gt;: Attempting to write a plug-in for the first time without at least a &lt;em&gt;basic&lt;/em&gt; grasp of one of these languages will impede your progress.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plug-in Registration Tool&lt;/strong&gt;: To deploy your plug-in out, you will need access to this tool as well. We&amp;rsquo;ll cover this off later in the post.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="demo-creating-a-microsoft-dataverse-plug-in-using-visual-studio-2019--c"&gt;Demo: Creating a Microsoft Dataverse Plug-in using Visual Studio 2019 &amp;amp; C#
&lt;/h3&gt;&lt;p&gt;The best way to learn how to create a plug-in is to see someone build one from scratch. In the YouTube video below, I talk through how to build a straightforward plug-in using Visual Studio 2019 and C#:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/j7jU8VcS8cg"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;For those who would prefer to read a set of instructions, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/tutorial-write-plug-in?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;then this Microsoft Docs article provides a separate tutorial you can follow instead&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="using-the-plug-in-registration-tool"&gt;Using the Plug-in Registration Tool
&lt;/h3&gt;&lt;p&gt;Once you&amp;rsquo;ve written your first plug-in, you then need to consider how to deploy this out. In most cases, you will use the Plug-in Registration Tool to accomplish this. &lt;a class="link" href="https://www.nuget.org/packages/Microsoft.CrmSdk.XrmTooling.PluginRegistrationTool" target="_blank" rel="noopener"
&gt;Available on NuGet&lt;/a&gt;, this lightweight application supports the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Varied access options when working with multiple Dataverse environments.&lt;/li&gt;
&lt;li&gt;The ability to register one or multiple plug-in assemblies.&lt;/li&gt;
&lt;li&gt;The registering of plug-in steps and images, including the various settings, discussed earlier.&lt;/li&gt;
&lt;li&gt;Via the tool, you can install the &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/debug-plug-in#use-plug-in-profiler?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Plug-in Profiler&lt;/a&gt;, an essential tool for remote debugging your plug-ins; more on this capability later.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Plug-In Registration Tool is also necessary for deploying other extensibility components, including &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/walkthrough-register-azure-aware-plug-in-using-plug-in-registration-tool?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Service Endpoints&lt;/a&gt;, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/use-webhooks?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;WebHooks&lt;/a&gt; or &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/virtual-entities/custom-ve-data-providers?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom Data Providers&lt;/a&gt;. We will touch upon some of these later on in the series. For this topic area and the exam, you must have a good general awareness of deploying and updating existing plug-in assemblies.&lt;/p&gt;
&lt;h3 id="demo-deploying-a-microsoft-dataverse-plug-in-using-the-plug-in-registration-tool"&gt;Demo: Deploying a Microsoft Dataverse Plug-in using the Plug-in Registration Tool
&lt;/h3&gt;&lt;p&gt;In this next video, I&amp;rsquo;ll show you how to take the plug-in developed as part of the previous video and deploy it out using the Plug-in Registration Tool:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/11T7OdYx7UY"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/tutorial-write-plug-in#register-plug-in?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;There is also a corresponding Microsoft Docs tutorial that covers these steps too&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="debugging-options-for-plug-ins"&gt;Debugging Options for Plug-ins
&lt;/h3&gt;&lt;p&gt;Plug-ins deployed out into Microsoft Dataverse must always run within sandbox execution mode. As a result, this imposes a couple of limitations (some of which I&amp;rsquo;ll highlight in detail later on), the main one being that it greatly hinders the ability to debug deployed plug-ins &lt;em&gt;easily&lt;/em&gt;. To get around this, Microsoft has provided two mechanisms that developers can leverage:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Plug-in Trace Logging&lt;/strong&gt;: Using this, developers can write out custom log messages into the application at any point in their code. This can be useful in identifying the precise location where a plug-in is not working as expected, as you can output specific values to the log for further inspection. You can also utilise them to provide more accurate error messages for your code that you would not necessarily wish to show users as part of a dialog box. Getting to grips with trace logging is easy - it&amp;rsquo;s just a few lines of code that you need to add to your project - &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/logging-tracing?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;and you can find out more about how to work with it on the Microsoft Docs site&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plug-in Registration Tool &amp;amp; Profiling&lt;/strong&gt;: While trace logging is undoubtedly useful, there will be situations where you need something &lt;em&gt;more&lt;/em&gt;. For example, it may become desirable to breakpoint code, inspect values/properties as they are processed, and determine when your plug-in hits specific conditions or error messages. The Profiler comes into play for these situations by allowing developers to &amp;ldquo;playback&amp;rdquo; their code execution using Visual Studio and the Plug-in Registration Tool. We mentioned the Plug-in Profiler tool earlier, which is a mandatory requirement and must be deployed to your instance first. From there, you can generate a profile file that allows you to rewind execution within Visual Studio.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Developers will typically use both of these debugging methods in tandem to figure out issues with their code. The first option provides a friendly, discreet mechanism of inspecting how a plug-in has got on. The Profiler acts as the &amp;ldquo;nuclear&amp;rdquo; option when we cannot discern the problem easily via trace logging alone. Understanding the benefits/disadvantages of both and how to use them will be essential as part of your exam preparation. With this in mind, check out the two demo videos below that show you how to work with these features in-depth:&lt;/p&gt;
&lt;h3 id="demo-debugging-a-microsoft-dataverse-plug-in-using-trace-logging"&gt;Demo: Debugging a Microsoft Dataverse Plug-in using Trace Logging
&lt;/h3&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/QzI3NDABbPU"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="demo-debugging-a-microsoft-dataverse-plug-in-using-the-plug-in-registration-tool"&gt;Demo: Debugging a Microsoft Dataverse Plug-in Using the Plug-in Registration Tool
&lt;/h3&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/J6ODPtt6Xd4"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="general-performance--optimization-tips"&gt;General Performance / Optimization Tips
&lt;/h3&gt;&lt;p&gt;Anyone can build and deploy a plug-in, but it can take some time before you can do this &lt;em&gt;well&lt;/em&gt;. Here are a few tips that you should always follow to ensure your plug-ins perform well when deployed out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep in mind some of the limitations as part of sandbox execution for your plug-ins, including:
&lt;ul&gt;
&lt;li&gt;The 2 minute limit on execution time.&lt;/li&gt;
&lt;li&gt;The inability to use specific 3rd party DLL&amp;rsquo;s, such as &lt;a class="link" href="https://www.newtonsoft.com/json" target="_blank" rel="noopener"
&gt;Newtonsoft.Json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Various restrictions around accessing operating system level information, such as directories, system state etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For situations where sandbox limitation will cause issues in executing your business logic, you will need to consider moving away from a plug-in and adopting another solution.&lt;/li&gt;
&lt;li&gt;Filtering attributes provide a great way of ensuring your code only executes when you need it to. You should always use these wherever possible.&lt;/li&gt;
&lt;li&gt;Make sure to disable any plug-in profiling and remove the Profiler solution once you are finished. Active profiles can considerably slow down performance, and the Profile solution can also introduce unintended dependencies on core tables, causing difficulties when moving changes as part of a solution file.&lt;/li&gt;
&lt;li&gt;The &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/use-powerapps-checker?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Solution Checker&lt;/a&gt; provides an excellent mechanism for quality checking your code and can give some constructive recommendations on where your plug-in can be improved. Running this at least once before moving your plug-in out into other environments is highly recommended.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/best-practices/business-logic/optimize-assembly-development?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Read through the following Microsoft Docs article&lt;/a&gt; and take care to follow the suggestions it outlines.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dont-forgetcustom-actions--global-discovery-service-endpoint"&gt;Don&amp;rsquo;t Forget&amp;hellip;Custom Actions &amp;amp; Global Discovery Service Endpoint
&lt;/h3&gt;&lt;p&gt;As Microsoft has included them in the exam specification, it&amp;rsquo;s worth talking about these two topics briefly. However, only a general awareness of them should be sufficient, and I wouldn&amp;rsquo;t devote too much of your revision time to them.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve already looked at Messages in-depth and seen how they can act as a &amp;ldquo;gateway&amp;rdquo; for developers to bolt on specific logic when an application-level event occurs. &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/custom-actions?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom Actions&lt;/a&gt; allow you to take this a step further by creating SDK/API exposable, custom Messages. For example, you could combine the Create/Update Messages of the Lead/Opportunity tables into a new message called &lt;strong&gt;SalesProcess&lt;/strong&gt;. Plug-ins or operations targeting the Web API could then work with or trigger actions based on this. Custom Actions have been available within the application for many years now, and many developers continually argue them as being one of the most underrated features in Microsoft Dataverse. &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/commondataserviceforapps/#perform-a-bound-action?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;They are also fully supported for use as part of Power Automate flows too&lt;/a&gt;. In short, they can be incredibly useful if you need to group multiple default messages into a single action that can then be called instead of each one.&lt;/p&gt;
&lt;p&gt;Finally, it is worth touching upon how developers use the &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/webapi/discover-url-organization-web-api?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Global Discovery Endpoint&lt;/a&gt; from a plug-in standpoint, but we must first outline the concepts of early-binding and late binding. In the video demos above, I wrote all of the code using the &lt;em&gt;late-binding&lt;/em&gt; mechanism. This means that instead of declaring an object for the specific table I wanted to work with (such as Contact), I instead used the generic &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.entity?view=dynamics-general-ce-9?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Entity&lt;/a&gt; class and told the code which attributes I wanted to work with by specifying their logical names as strings. This is fine and gives me some degree of flexibility, but it ultimately means that I won&amp;rsquo;t detect any issues with my code (such as an incorrect field name) until runtime. Also, I have no easy way to tell how my table looks using Intellisense; instead, I must continuously refer to the application to view these properties. To get around this, we can use a mechanism known as &lt;em&gt;early-binding&lt;/em&gt;, where all of the appropriate table structures are generated within the project and referenced accordingly. &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/data-platform/org-service/generate-early-bound-classes?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;The CrmSvcUtil.exe application provides a streamlined means of creating these early-bound classes&lt;/a&gt;, and, as you might have guessed, you need to use the Global Discovery Endpoint to generate these classes successfully. There have been many previous wars and mounds of dead developers debates online regarding which mechanism is better. While early-binding does afford some great benefits, it does add some overhead into your development cycle, as you must continuously run the CrmSvcUtil application each time your tables change within Microsoft Dataverse. All I would recommend is to try both options, identify the one that works best for you and, most importantly, adopt your preferred solution consistently.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Plug-ins can help when modelling out complicated business logic that is impossible to achieve via other functional tools within the Power Platform. I hope this post has provided a good insight into their capabilities and to help you in your revision. In the next post, I&amp;rsquo;ll show you how you can extend Power Automate and Power Apps via custom API connectors, thereby allowing you to connect to a myriad of different systems.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Avoiding Parallel Execution within Power Apps / Common Data Service Plug-ins</title><link>/avoiding-parallel-execution-within-power-apps-common-data-service-plug-ins/</link><pubDate>Sun, 20 Sep 2020 00:00:00 +0000</pubDate><guid>/avoiding-parallel-execution-within-power-apps-common-data-service-plug-ins/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Avoiding Parallel Execution within Power Apps / Common Data Service Plug-ins" /&gt;&lt;p&gt;The &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/use-powerapps-checker?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Power Apps Solution Checker&lt;/a&gt; provides developers with a great mechanism to verify the quality of custom code targeting either Dynamics 365 Online or the Common Data Service. We can use the recommendations it produces to help write better, more optimised code, that will better benefit our deployments and the individuals working with the apps we&amp;rsquo;ve built. Typically, the recommendations it produces will be informative enough to get you on your way; Microsoft will provide a summary of the problem and a link to the relevant Docs article that contains links/code samples for you to adapt accordingly. However, this is not always the case, and you may need to scratch your head a &lt;em&gt;little&lt;/em&gt; harder to get to the root of the problem. This happened to me recently when I was dealing with the following recommendation:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/PowerApps-SolutionChecker-ParallelPatternRecommendation.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.microsoft.com/en-gb/powerapps/developer/common-data-service/best-practices/business-logic/do-not-use-parallel-execution-in-plug-ins?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;The Docs article link for this recommendation&lt;/a&gt; doesn&amp;rsquo;t give us much to go on when figuring out what to do to get our code fixed. But we must still, somehow, address the problem it raises - the idea of potentially conflicting transactions and generic SQL errors is enough, I&amp;rsquo;d warrant, to scare even the most hardened Dynamics 365 / Power Platform developer. 🙂 So let&amp;rsquo;s take a look at how I resolved the issue within this specific scenario. Hopefully, it might help you if you find yourself facing the same problem.&lt;/p&gt;
&lt;p&gt;As this is a code related issues, let&amp;rsquo;s, first of all, take a look at the offending blocks of code in question. First of all, we had the following method that would call an external OData endpoint. This formed part of a &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/virtual-entities/custom-ve-data-providers?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom Data Provider for a virtual entity&lt;/a&gt; that would require OAuth 2.0 authentication; something that, regrettably, is not supported by the &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/virtual-entities/get-started-ve?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;default OData provider Microsoft provides us with&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetRecordById&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Generate the OData endpoint request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;oDataURL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;{this.aadConfig.ODataURL}/{entity}({id})&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oDataURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HttpRequestMessage&lt;/span&gt; &lt;span class="n"&gt;oDataReq&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HttpRequestMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpMethod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oDataURL&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;oDataReq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Authorization&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AuthenticationHeaderValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Bearer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HttpHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetHttpClient&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HttpResponseMessage&lt;/span&gt; &lt;span class="n"&gt;oDataResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SendAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oDataReq&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;oDataResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessStatusCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oDataResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GenericDataAccessException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;A problem occurred when retrieving the {entity} data.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Retrieve data from the endpoint using the bearer token.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oDataResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAsStringAsync&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataContractJsonSerializerSettings&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataContractJsonSerializerSettings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UseSimpleDictionaryFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataContractJsonSerializer&lt;/span&gt; &lt;span class="n"&gt;ser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataContractJsonSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GenericDataAccessException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;A problem occurred when retrieving the {entity} data.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note the following with this method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It has been set to execute asynchronously as a task, as indicated by the &lt;strong&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/?WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;async&lt;/a&gt;&lt;/strong&gt; and &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/task-asynchronous-programming-model?WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Task&lt;/strong&gt;&lt;/a&gt; keyword.&lt;/li&gt;
&lt;li&gt;The core HTTP call is wrapped within a &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using?WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;&lt;strong&gt;using&lt;/strong&gt;&lt;/a&gt; statement and executed as a &lt;strong&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.6.2?WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;HttpClient&lt;/a&gt;&lt;/strong&gt; request.&lt;/li&gt;
&lt;li&gt;The method is generic in terms of its return type, therefore allowing us to retrieve and then cast out to a variety of different classes if required.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This method was then called at relevant points elsewhere in the code using the snippet below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;getEntityByIdTask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;GetRecordById&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Entity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getAccessToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getEntityByIdTask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getEntityByIdTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Entity found: {result.ID}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, and as mentioned earlier, we are calling the asynchronous task method to return us a result set of type &lt;strong&gt;Entity&lt;/strong&gt;, which represents our result from the OData endpoint.&lt;/p&gt;
&lt;p&gt;Going back then to the recommendation raised earlier, we can best summarise the main issues with the &amp;ldquo;as-is&amp;rdquo; code as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The method will always run as a separate, asynchronous call within the current database transaction. As well as being the cause of a solution checker recommendation, this could also lead to longer-running transactions and us unintentionally hitting the two-minute execution limit for sandbox, if our outbound call takes far longer to execute than expected.&lt;/li&gt;
&lt;li&gt;The HttpClient class supports asynchronous execution only; there is no way of forcing it to execute synchronously, meaning that we must instead resort to using other class types, such as &lt;strong&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/system.net.httpwebrequest?view=netframework-4.6.2?WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;HttpWebRequest&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/system.net.httpwebresponse?view=netframework-4.6.2?WT.mc_id=DOP-MVP-5003861" target="_blank" rel="noopener"
&gt;HttpWebResponse&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The code snippet itself is expecting the method to run asynchronously; this needs to be adjusted accordingly to match any changes to the &lt;strong&gt;GetRecordById&lt;/strong&gt; method.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With all this in mind, we can look to tweak our method&amp;hellip;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;GetRecordById&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Generate the OData endpoint request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;oDataURL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;{this.aadConfig.ODataURL}/{entity}({id})&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oDataURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;HttpWebRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpWebRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;WebRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oDataURL&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KeepAlive&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Authorization&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Bearer &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpWebResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;HttpStatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GenericDataAccessException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;A problem occurred when retrieving the {entity} data.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponseStream&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataContractJsonSerializerSettings&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataContractJsonSerializerSettings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UseSimpleDictionaryFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataContractJsonSerializer&lt;/span&gt; &lt;span class="n"&gt;ser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataContractJsonSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GenericDataAccessException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;A problem occurred when retrieving the {entity} data.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip;and the related snippet that calls it&amp;hellip;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetRecordById&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Entity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getAccessToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Entity found: {entity.ID}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, it is worth highlighting that Microsoft advises not to use the &lt;strong&gt;HttpWebRequest&lt;/strong&gt; class for new development work. However, I have struggled to find an alternative solution that fixes this problem.  Answers on a postcode if you think there&amp;rsquo;s a better way of doing this, and I will happily update this post and provide full credit for any solution that gets around this; but otherwise, looks like we are stuck with using this!&lt;/p&gt;
&lt;p&gt;The Solution Checker is a fantastic tool to have in your arsenal to provide you with an automated, bespoke way of flagging common issues with your Dynamics 365 / Power Apps solution. Granted, it will never take the place of a formal code review alongside a senior developer. Still, it can be a potential lifesaver if you find yourself performing solo development work targeting the application. Give it a go if you haven&amp;rsquo;t already and, hopefully, if you see yourself getting the same recommendation outlined in this post, you now know what to do to get your code sorted.&lt;/p&gt;</description></item><item><title>Exam MB-400 Revision Notes: Series Roundup</title><link>/exam-mb-400-revision-notes-series-roundup/</link><pubDate>Sun, 13 Sep 2020 00:00:00 +0000</pubDate><guid>/exam-mb-400-revision-notes-series-roundup/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Exam MB-400 Revision Notes: Series Roundup" /&gt;&lt;p&gt;Welcome to the final post in my series focused on providing a set of revision notes for the &lt;a class="link" href="https://docs.microsoft.com/en-us/learn/certifications/exams/mb-400?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;MB-400: Microsoft Power Apps + Dynamics 365 Developer exam&lt;/a&gt;. In today&amp;rsquo;s post, I wanted to consolidate all of the content from the series into a single, concise post for ease of access. I&amp;rsquo;ll also provide some general advice and tips that I hope will come in useful for when you sit the exam.&lt;/p&gt;
&lt;p&gt;This series has aimed to provide a broad outline of the core areas to keep in mind when tackling the exam, linked to appropriate resources for more focused study. Your revision should, ideally, involve a high degree of hands-on testing and familiarity in working with the platform if you want to do well in this exam.&lt;/p&gt;
&lt;p&gt;The MB-400 exam is split into several different areas, based on the specification found &lt;a class="link" href="https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE42uM0" target="_blank" rel="noopener"
&gt;here&lt;/a&gt;. For each applicable subject, I have linked below to the relevant blog/video content from the series.&lt;/p&gt;
&lt;h3 id="create-a-technical-design-10-15"&gt;Create a Technical Design (10-15%)
&lt;/h3&gt;&lt;h4 id="validate-requirements-and-design-technical-architecture"&gt;Validate requirements and design technical architecture
&lt;/h4&gt;&lt;h5 id="skills-measured"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;design and validate technical architecture&lt;/li&gt;
&lt;li&gt;design authentication and authorization strategy&lt;/li&gt;
&lt;li&gt;determine whether requirements can be met with out-of-the-box functionality&lt;/li&gt;
&lt;li&gt;determine when to use Logic Apps versus Power Automate flows&lt;/li&gt;
&lt;li&gt;determine when to use serverless computing vs. plug-ins&lt;/li&gt;
&lt;li&gt;determine when to build a virtual entity data source provider vs. when to use connectors&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-a-data-model"&gt;Create a data model
&lt;/h4&gt;&lt;h5 id="skills-measured-1"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;design a data model&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-creating-a-technical-design-with-the-power-platform/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Creating a Technical Design with the Power Platform&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="useful-resources"&gt;Useful Resources
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/common-data-model/?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Common Data Model Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-overview?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;What is Azure Logic Apps?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/power-automate/getting-started?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Get Started with Power Automate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/plug-ins?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Use plug-ins to extend business processes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/virtual-entities/get-started-ve?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Get started with virtual entities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/register-custom-api?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom connectors for canvas apps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="configure-common-data-service-15-20"&gt;Configure Common Data Service (15-20%)
&lt;/h3&gt;&lt;h4 id="configure-security-to-support-development"&gt;Configure security to support development
&lt;/h4&gt;&lt;h5 id="skills-measured-2"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;troubleshoot operational security issues&lt;/li&gt;
&lt;li&gt;create or update security roles and field-level security profiles&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="implement-entities-and-fields"&gt;Implement entities and fields
&lt;/h3&gt;&lt;h5 id="skills-measured-3"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;configure entities&lt;/li&gt;
&lt;li&gt;configure fields&lt;/li&gt;
&lt;li&gt;configure relationships&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-and-maintain-solutions"&gt;Create and maintain solutions
&lt;/h4&gt;&lt;h5 id="skills-measured-4"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;configure solutions&lt;/li&gt;
&lt;li&gt;import and export solutions&lt;/li&gt;
&lt;li&gt;manage solution dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-1"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-configuring-the-common-data-service/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Configuring the Common Data Service&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos"&gt;Videos
&lt;/h4&gt;&lt;h5 id="mb-400-exam-prep-creating-entities-fields-and-relationships"&gt;MB-400 Exam Prep: Creating Entities, Fields and Relationships
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/-nAUZdIGRY8"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-working-with-solutions"&gt;MB-400 Exam Prep: Working with Solutions
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/CsA7Dikl8Cg"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-security-roles--field-security-profiles"&gt;MB-400 Exam Prep: Security Roles &amp;amp; Field Security Profiles
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/hwEkaGst3Yc"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h4 id="useful-resources-1"&gt;Useful Resources
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/entity-overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Entity overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/fields-overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Fields overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/relationships-overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Entity relationships overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/solutions-overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Solutions overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="create-and-configure-power-apps-10-15"&gt;Create and Configure Power Apps (10-15%)
&lt;/h3&gt;&lt;h4 id="create-model-driven-apps"&gt;Create model-driven apps
&lt;/h4&gt;&lt;h5 id="skills-measured-5"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;configure a model-driven app&lt;/li&gt;
&lt;li&gt;configure forms&lt;/li&gt;
&lt;li&gt;configure views&lt;/li&gt;
&lt;li&gt;configure visualizations&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-canvas-apps"&gt;Create Canvas Apps
&lt;/h4&gt;&lt;h5 id="skills-measured-6"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;configure a Canvas App&lt;/li&gt;
&lt;li&gt;develop complex expressions&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-2"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-working-with-model-driven-apps/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Working with Model-Driven Apps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-working-with-canvas-apps/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Working with Canvas Apps&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-1"&gt;Videos
&lt;/h4&gt;&lt;h5 id="mb-400-exam-prep-building-a-model-driven-app"&gt;MB-400 Exam Prep: Building a Model-Driven App
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/EEBTENhcQ-0"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a class="link" href="https://youtu.be/EEBTENhcQ-0" target="_blank" rel="noopener"
&gt;https://youtu.be/EEBTENhcQ-0&lt;/a&gt;&lt;/p&gt;
&lt;h5 id="mb-400-exam-prep-creating-a-canvas-app"&gt;MB-400 Exam Prep: Creating a Canvas App
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/SMOxnnsHs6Q"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h4 id="useful-resources-2"&gt;Useful Resources
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/model-driven-apps/model-driven-app-overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;What are model-driven apps in Power Apps?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/model-driven-apps/create-design-forms?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Create and design model-driven app forms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/model-driven-apps/create-edit-views?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Understand model-driven app views&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/user/track-your-progress-with-dashboard-and-charts?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Track your progress with dashboards and charts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/getting-started?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;What are canvas apps in Power Apps?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="configure-business-process-automation-10-15"&gt;Configure business process automation (10-15%)
&lt;/h3&gt;&lt;h4 id="configure-power-automate"&gt;Configure Power Automate
&lt;/h4&gt;&lt;h5 id="skills-measured-7"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;configure a Flow&lt;/li&gt;
&lt;li&gt;configure actions to use Common Data Service connectors&lt;/li&gt;
&lt;li&gt;develop complex expressions&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implement-processes"&gt;Implement processes
&lt;/h4&gt;&lt;h5 id="skills-measured-8"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;create and configure business process flows&lt;/li&gt;
&lt;li&gt;create and configure business rule&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-3"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-using-power-automate-flows/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Using Power Automate Flows&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-mapping-a-business-process-with-business-process-flows/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Mapping a Business Process with Business Process Flows&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-implementing-business-rules/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Implementing Business Rules&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-2"&gt;Videos
&lt;/h4&gt;&lt;h5 id="mb-400-exam-prep-introduction-to-power-automate-flows"&gt;MB-400 Exam Prep: Introduction to Power Automate Flows
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/TSMyFrVxOPI"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-creating-a-business-process-flow"&gt;MB-400 Exam Prep: Creating a Business Process Flow
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/hv61WKRUv3A"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-working-with-business-rules"&gt;MB-400 Exam Prep: Working with Business Rules
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/7NQTLQenJB0"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h4 id="useful-resources-3"&gt;Useful Resources
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/power-automate/common-data-model-intro?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Create a flow that uses the Common Data Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/power-automate/use-expressions-in-conditions?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Use expressions in conditions to check multiple values&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/power-automate/business-process-flows-overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Business process flows overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/cds-processes?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Apply business logic in Common Data Service&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="extend-the-user-experience-15-20"&gt;Extend the user experience (15-20%)
&lt;/h3&gt;&lt;h4 id="apply-business-logic-using-client-scripting"&gt;Apply business logic using client scripting
&lt;/h4&gt;&lt;h5 id="skills-measured-9"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;configure supporting components&lt;/li&gt;
&lt;li&gt;create JavaScript or Typescript code&lt;/li&gt;
&lt;li&gt;register an event handler&lt;/li&gt;
&lt;li&gt;use the Web API from client scripting&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-a-power-apps-component-framework-pcf-component"&gt;Create a Power Apps Component Framework (PCF) component
&lt;/h4&gt;&lt;h5 id="skills-measured-10"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;initialize a new PCF component&lt;/li&gt;
&lt;li&gt;configure a PCF component manifest&lt;/li&gt;
&lt;li&gt;implement the component interfaces&lt;/li&gt;
&lt;li&gt;package, deploy, and consume the component&lt;/li&gt;
&lt;li&gt;use Web API device capabilities and other component framework services&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="create-a-command-button-function"&gt;Create a command button function
&lt;/h4&gt;&lt;h5 id="skills-measured-11"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;create the command function&lt;/li&gt;
&lt;li&gt;design command button triggers, rules, and actions&lt;/li&gt;
&lt;li&gt;edit the command bar using the Ribbon Workbench&lt;/li&gt;
&lt;li&gt;modify the form JavaScript library dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-4"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-implementing-client-side-scripting-on-model-driven-power-apps/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Implementing Client-Side Scripting on Model Driven Power Apps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-introduction-to-power-apps-component-framework-pcf-controls/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Introduction to Power Apps Component Framework (PCF) Controls&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-working-with-command-buttons/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Working with Command Buttons&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-3"&gt;Videos
&lt;/h4&gt;&lt;h5 id="mb-400-exam-prep-deploying-a-basic-javascript-form-function"&gt;MB-400 Exam Prep: Deploying a Basic JavaScript Form Function
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/srTvobF4O8M"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-setting-up-your-environment-for-power-apps-component-framework-control-development"&gt;MB-400 Exam Prep: Setting up your environment for Power Apps Component Framework Control Development
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/-scxLe6AfPI"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-developing-testing-and-deploying-a-power-apps-component-framework-pcf-control"&gt;MB-400 Exam Prep: Developing, Testing and Deploying a Power Apps Component Framework (PCF) Control
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/VJ43X8xRMys"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-creating-command-buttons-using-the-ribbon-workbench"&gt;MB-400 Exam Prep: Creating Command Buttons Using the Ribbon Workbench
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/fpRv3WuwEEk"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h4 id="useful-resources-4"&gt;Useful Resources
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/model-driven-apps/client-scripting?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Apply business logic using client scripting in model-driven apps using JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/webapi/get-started-web-api-client-side-javascript?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Client-side JavaScript using Web API in model-driven apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/component-framework/overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Power Apps component framework overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/model-driven-apps/customize-commands-ribbon?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Customize commands and the ribbon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="extend-the-platform-15-20"&gt;Extend the platform (15-20%)
&lt;/h3&gt;&lt;h4 id="create-a-plug-in"&gt;Create a plug-in
&lt;/h4&gt;&lt;h5 id="skills-measured-12"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;debug and troubleshoot a plug-in&lt;/li&gt;
&lt;li&gt;develop a plug-in&lt;/li&gt;
&lt;li&gt;use the global Discovery Service endpoint&lt;/li&gt;
&lt;li&gt;optimize plug-ins for performance&lt;/li&gt;
&lt;li&gt;register custom assemblies by using the Plug-in Registration Tool&lt;/li&gt;
&lt;li&gt;create custom actions&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="configure-custom-connectors-for-power-apps-and-flow"&gt;Configure custom connectors for Power Apps and Flow
&lt;/h4&gt;&lt;h5 id="skills-measured-13"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;create a definition for the API&lt;/li&gt;
&lt;li&gt;configure API security&lt;/li&gt;
&lt;li&gt;use policy templates&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="use-platform-apis"&gt;Use platform APIs
&lt;/h4&gt;&lt;h5 id="skills-measured-14"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;interact with data and processes using the Web API&lt;/li&gt;
&lt;li&gt;optimize for performance, concurrency, transactions, and batching&lt;/li&gt;
&lt;li&gt;perform discovery using the Web API&lt;/li&gt;
&lt;li&gt;perform entity metadata operations with the Web API&lt;/li&gt;
&lt;li&gt;use OAuth with the platform APIs&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-5"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-building-deploying-debugging-plug-ins-using-c/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Building, Deploying &amp;amp; Debugging Plug-ins using C#&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-building-a-custom-connector-for-power-apps-power-automate/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Building a Custom Connector for Power Apps &amp;amp; Power Automate&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-working-with-the-dynamics-365-web-api/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Working with the Dynamics 365 Web API&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-4"&gt;Videos
&lt;/h4&gt;&lt;h5 id="mb-400-exam-prep-building-a-c-plug-in-using-visual-studio-2019"&gt;MB-400 Exam Prep: Building a C# Plug-in Using Visual Studio 2019
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/EzT40-N8Kk4"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-deploying-a-c-plug-in-using-the-plug-in-registration-tool"&gt;MB-400 Exam Prep: Deploying a C# Plug-in Using the Plug-in Registration Tool
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/ybmt2AAKT8Q"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-debugging-a-c-plug-in-using-trace-logging"&gt;MB-400 Exam Prep: Debugging a C# Plug-in Using Trace Logging
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/60zGFRwhN4E"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-debugging-a-c-plug-in-using-the-plug-in-registration-tool"&gt;MB-400 Exam Prep: Debugging a C# Plug-in Using the Plug-in Registration Tool
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/c12eZQSKZO0"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-building-a-custom-connector-using-azure-cognitive-services"&gt;MB-400 Exam Prep: Building a Custom Connector Using Azure Cognitive Services
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/VvbWihTW3Bw"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-authenticating-to-the-dynamics-365-web-api"&gt;MB-400 Exam Prep: Authenticating to the Dynamics 365 Web API
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/D95mG1DYFGo"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-working-with-the-dynamics-365-discovery-url"&gt;MB-400 Exam Prep: Working with the Dynamics 365 Discovery URL
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/y0S1MfQ5JhA"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-retrieving-entity-metadata-using-the-web-api"&gt;MB-400 Exam Prep: Retrieving Entity Metadata using the Web API
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/X6PDlHlbr2A"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-performing-batch-operations-using-the-web-api"&gt;MB-400 Exam Prep: Performing Batch Operations using the Web API
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/onNfoOKgrT4"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h4 id="useful-resources-5"&gt;Useful Resources
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/plug-ins?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Use plug-ins to extend business processes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/tutorial-write-plug-in?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Tutorial: Write and register a plug-in&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/custom-actions?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Create your own actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/custom-connectors/?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Custom Connectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/webapi/overview?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Use the Common Data Service Web API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="develop-integrations-10-15"&gt;Develop Integrations (10-15%)
&lt;/h3&gt;&lt;h4 id="publish-and-consume-events"&gt;Publish and consume events
&lt;/h4&gt;&lt;h5 id="skills-measured-15"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;publish an event by using the API&lt;/li&gt;
&lt;li&gt;publish an event by using the Plug-in Registration Tool&lt;/li&gt;
&lt;li&gt;register a webhook&lt;/li&gt;
&lt;li&gt;create an Azure event listener application&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implement-data-synchronization"&gt;Implement data synchronization
&lt;/h4&gt;&lt;h5 id="skills-measured-16"&gt;Skills Measured
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;configure and use entity change tracking&lt;/li&gt;
&lt;li&gt;configure the data export service to integrate with Azure SQL Database&lt;/li&gt;
&lt;li&gt;create and use alternate keys&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="blog-posts-6"&gt;Blog Posts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-publishing-and-consuming-events/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Publishing and Consuming Events&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-implementing-data-synchronisation-with-the-data-export-service/" target="_blank" rel="noopener"
&gt;Exam MB-400 Revision Notes: Implementing Data Synchronisation with the Data Export Service&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="videos-5"&gt;Videos
&lt;/h4&gt;&lt;h5 id="mb-400-exam-prep-posting-dynamics-365-events-to-azure-service-bus"&gt;MB-400 Exam Prep: Posting Dynamics 365 Events to Azure Service Bus
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/ahybKdWR-Ig"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-registering--consuming-a-dynamics-365-webhook"&gt;MB-400 Exam Prep: Registering &amp;amp; Consuming a Dynamics 365 Webhook
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/Q8NlBofsZ48"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h5 id="mb-400-exam-prep-deploying-the-dynamics-365-data-export-service"&gt;MB-400 Exam Prep: Deploying the Dynamics 365 Data Export Service
&lt;/h5&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/nZyuMyrSIG4"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h4 id="useful-content"&gt;Useful Content
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/azure-integration?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Azure Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview?WT.mc_id=AZ-MVP-5003861" target="_blank" rel="noopener"
&gt;What is Azure Service Bus?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/configure-azure-integration?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Configure Azure Integration with Common Data Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/data-synchronization?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Data Synchronization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/data-export-service?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Data export service&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="general-exam-preparation-tips"&gt;General Exam Preparation Tips
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Hands-on preparation is &lt;strong&gt;essential&lt;/strong&gt; if you wish to do well in the exam. You should ideally set up a trial environment that you can use to experiment with the core functionality within Dynamics 365 / the Power Platform. &lt;a class="link" href="https://www.youtube.com/watch?v=lfGtjcxeKj4" target="_blank" rel="noopener"
&gt;You can watch this great video from Microsoft&amp;rsquo;s Chris Huntingford&lt;/a&gt;, where he will show you how to deploy an extended trial of Dynamics 365 Online and Microsoft 365 E5. These subscriptions will give you everything you need.&lt;/li&gt;
&lt;li&gt;Keep abreast of the latest Microsoft Docs and &lt;a class="link" href="https://docs.microsoft.com/en-gb/learn/browse/?roles=developer&amp;amp;resource_type=learning%20path&amp;amp;products=power-platform?WT.mc_id=BA-MVP-5003861" target="_blank" rel="noopener"
&gt;Learning Path materials&lt;/a&gt; that are related to this exam, as the platform is continually changing all of the time.&lt;/li&gt;
&lt;li&gt;Due to the ongoing COVID-19 situation, you will more than likely have to sit your exam using the online proctored experience. &lt;a class="link" href="https://home.pearsonvue.com/Test-takers/OnVUE-online-proctoring.aspx" target="_blank" rel="noopener"
&gt;Take some time to familiarise yourself with the process involved here&lt;/a&gt;, and perform a system test well in advance of your exam date - the last thing you need on the day of the exam is to stress out due to a system or access issue.&lt;/li&gt;
&lt;li&gt;At the time of writing this post, Microsoft has announced the deprecation of the MB-400 exam in January 2021. &lt;a class="link" href="https://crmchap.co.uk/some-thoughts-on-the-new-business-application-microsoft-certifications/" target="_blank" rel="noopener"
&gt;I&amp;rsquo;ve discussed these changes in-depth previously on the blog&lt;/a&gt; and what it means if you&amp;rsquo;ve got an exam booked over the next few months. I would still advise that you sit this exam while it is available, as it will count towards any certification pathway that you are working towards. Additionally, there will be more content (and I don&amp;rsquo;t necessarily mean my own here 🙂 ) available covering this exam, which will provide better aid as part of your revision.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;I hope that you&amp;rsquo;ve found this series useful. Good luck when sitting the exam and let me know how you got on!&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Working with the TryGetAttributeValue Method (Dynamics 365 / Common Data Service SDK)</title><link>/working-with-the-trygetattributevalue-method-dynamics-365-common-data-service-sdk/</link><pubDate>Sun, 23 Aug 2020 00:00:00 +0000</pubDate><guid>/working-with-the-trygetattributevalue-method-dynamics-365-common-data-service-sdk/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Working with the TryGetAttributeValue Method (Dynamics 365 / Common Data Service SDK)" /&gt;&lt;p&gt;You can discover all sorts of useful capabilities if you dive your nose deep enough into the &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk" target="_blank" rel="noopener"
&gt;Dynamics 365 Online / Common Data Service SDK&lt;/a&gt;. And, given that these products are evolving continually within the cloud, new features are being introduced all the time. With this in mind, it&amp;rsquo;s perhaps natural to expect that even the so-called &amp;ldquo;experts&amp;rdquo; of these platforms may sometimes overlook new or seemingly obvious changes&amp;hellip;😅  I&amp;rsquo;m unsure which of these categories the focus of today&amp;rsquo;s blog post fits into it but, given that Microsoft has not documented its capabilities very well, I thought I&amp;rsquo;d take some time to explore it further.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://crmchap.co.uk/the-benefits-of-using-getattributevalue-to-access-crm-attributes-late-bound-c/" target="_blank" rel="noopener"
&gt;We&amp;rsquo;ve seen previously on the blog how to use the GetAttributeValue method&lt;/a&gt;, as being the &amp;ldquo;nice&amp;rdquo; way of accessing the various attributes you may need to work with as part of your C# code targeting Dynamics 365 / the Common Data Service. I won&amp;rsquo;t repeat too much old ground here but, suffice to say, I would highly recommend you always use this method as much as possible. As much as I like it though, one issue it does have is that you must always know the underlying data type that you are attempting to process. If, for example, you&amp;rsquo;re working with a defined list of attributes, but without their corresponding types declared, this method becomes pretty useless. Consider the following code snippet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;myAttributes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;myAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;myAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;myAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;industrycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;9e03afdc-5d37-e911-a97c-0022480749f0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;myAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;aVal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aVal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code works fine and dandy up until it hits the &lt;strong&gt;industrycode&lt;/strong&gt; value in the &lt;strong&gt;myAttributes&lt;/strong&gt; list, as this is the name of an Option Set, not a Single Line of Text (i.e. string) field. If a user has not populated this field with a value, then the code will silently skip over this and return a &lt;strong&gt;null&lt;/strong&gt; value, but if it isn&amp;rsquo;t, you will get an error thrown with the following message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An error has occurred: Unable to cast object of type &amp;lsquo;Microsoft.Xrm.Sdk.OptionSetValue&amp;rsquo; to type &amp;lsquo;System.String&amp;rsquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this situation, therefore, it becomes desirable to &lt;em&gt;test&lt;/em&gt; our incoming attributes to confirm they are of the correct type before we try to access their values.&lt;/p&gt;
&lt;p&gt;Enter stage left the &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.entity.trygetattributevalue" target="_blank" rel="noopener"
&gt;TryGetAttribute method.&lt;/a&gt; You can probably make a reasonable guess as to what this is doing from its name alone; namely, that it allows us to &lt;em&gt;attempt&lt;/em&gt; to obtain an attribute&amp;rsquo;s value into our desired type, without necessarily throwing a nasty error if we screw up at all. What&amp;rsquo;s more, we can use the method to still obtain our attribute value, in much the same way as &lt;strong&gt;GetAttributeValue&lt;/strong&gt; does, provided we have made the correct assumption regarding its underlying type. The method requires us to declare an object that will potentially store our attribute value when we call it. Apart from this main difference, it works pretty much as we&amp;rsquo;d hope it to - as the tweaked example below demonstrates:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;myAttributes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;myAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;myAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;myAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;industrycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;9e03afdc-5d37-e911-a97c-0022480749f0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;myAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;strVal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;OptionSetValue&lt;/span&gt; &lt;span class="n"&gt;osVal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;tryStr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TryGetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;strVal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;tryOS&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TryGetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OptionSetValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;osVal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tryStr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strVal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tryOS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;osVal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As we can see, all we need to do is declare a Boolean type, through which our code stores the results of the &lt;strong&gt;TryGetAttributeValue&lt;/strong&gt; method. Using this, we can then determine whether to output the value &lt;strong&gt;strVal&lt;/strong&gt; or &lt;strong&gt;osVal&lt;/strong&gt; to our trace log, which will store value obtained by &lt;strong&gt;TryGetAttributeValue&lt;/strong&gt;, provided that this did not result in &lt;strong&gt;false&lt;/strong&gt; when called. If needed, we can extend the solution out to support all possible data types within Dynamics 365 / Common Data Service and, in the process, not worry about implementing a solution to figure out the correct data types or make subsequent API calls to determine this information. In short, the &lt;strong&gt;TryGetAttributeValue&lt;/strong&gt; method provides a flexible and easy means of working with many different types of attributes simultaneously, that may be subject to change at runtime or difficult to infer easily. What&amp;rsquo;s more, the method shares the same benefit as &lt;strong&gt;GetAttributeValue&lt;/strong&gt; by defaulting to a &lt;strong&gt;null&lt;/strong&gt; value if the attribute, or its underlying value, does not exist, avoiding any needless errors from cropping up in your code.&lt;/p&gt;
&lt;p&gt;I guess you could say I derive a weird sense of pleasure whenever I discover a cool new feature as part of Dynamics 365/ the Common Data Service and, as you might have guessed, &lt;strong&gt;TryGetAttributeValue&lt;/strong&gt; very much fits into this category. I&amp;rsquo;m unsure when Microsoft added this method to the SDK or, indeed, if it&amp;rsquo;s something that I have naively overlooked for many years now. Regardless, I would urge you to consider using it within your code if the right circumstances arise, and I hope this blog post has been useful in showing you how to use it in practice. 🙂&lt;/p&gt;</description></item><item><title>Exam MB-400 Revision Notes: Building, Deploying &amp; Debugging Plug-ins using C#</title><link>/exam-mb-400-revision-notes-building-deploying-debugging-plug-ins-using-c/</link><pubDate>Sun, 02 Aug 2020 00:00:00 +0000</pubDate><guid>/exam-mb-400-revision-notes-building-deploying-debugging-plug-ins-using-c/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Exam MB-400 Revision Notes: Building, Deploying &amp; Debugging Plug-ins using C#" /&gt;&lt;p&gt;Welcome to the eleventh post in my series focused on providing a set of revision notes for the &lt;a class="link" href="https://docs.microsoft.com/en-us/learn/certifications/exams/mb-400" target="_blank" rel="noopener"
&gt;MB-400: Microsoft Power Apps + Dynamics 365 Developer exam&lt;/a&gt;. For those following the series, apologies again for the mini-hiatus. In fact, it&amp;rsquo;s been so long &lt;a class="link" href="https://crmchap.co.uk/some-thoughts-on-the-new-business-application-microsoft-certifications/" target="_blank" rel="noopener"
&gt;that Microsoft has now announced that MB-400 will be going the way of the Dodo at the end of the year&lt;/a&gt;. Despite this, I will be continuing and, all being well, finishing off this blog series for the following reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;People may still choose to sit the current exam while they still can. For this reason, the series may yet have some value once completed entirely.&lt;/li&gt;
&lt;li&gt;Looking at the Skills Measured document for the new replacement &lt;a class="link" href="https://docs.microsoft.com/en-us/learn/certifications/exams/pl-400" target="_blank" rel="noopener"
&gt;PL-400: Microsoft Power Platform Developer&lt;/a&gt; exam, and there is a lot of crossover in content. Therefore, the existing posts and accompanying videos may still have some merit in the new state of play. I&amp;rsquo;ll be able to make an appropriate determination of this after Microsoft release PL-400 and I&amp;rsquo;ve been able to sit it. But, hopefully, some of this content will remain useful for at least another year or so.&lt;/li&gt;
&lt;li&gt;I set out to run this series to completion, no matter what it takes 🙂&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So with this in mind, I hope you continue to stick around for future posts and that they provide you with a useful tool as part of any revision or learning you are doing.&lt;/p&gt;
&lt;p&gt;Last time around in the series, &lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-working-with-command-buttons/" target="_blank" rel="noopener"
&gt;we took a deep-dive look into command buttons, as well as demonstrating how valuable the Ribbon Workbench tool is&lt;/a&gt; in helping us to fine-tune aspects of a &lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-working-with-model-driven-apps/" target="_blank" rel="noopener"
&gt;model-driven Power App&amp;rsquo;s interface&lt;/a&gt;. This topic rounded off our discussion of the &lt;strong&gt;Extend the user experience&lt;/strong&gt; area of the exam, meaning that we now move into the &lt;strong&gt;Extend the platform&lt;/strong&gt; section. This area has equal weighting to &lt;strong&gt;Extend the user experience&lt;/strong&gt; (15-20%), and the first topic concerns how we &lt;strong&gt;Create a plug-in&lt;/strong&gt;. Specifically, candidates must demonstrate knowledge of the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Create a plug-in&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;debug and troubleshoot a plug-in&lt;/li&gt;
&lt;li&gt;develop a plug-in&lt;/li&gt;
&lt;li&gt;use the global Discovery Service endpoint&lt;/li&gt;
&lt;li&gt;optimize plug-ins for performance&lt;/li&gt;
&lt;li&gt;register custom assemblies by using the Plug-in Registration Tool&lt;/li&gt;
&lt;li&gt;create custom actions&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Plug-ins have been a mainstay within Dynamics 365, and its predecessor Dynamics CRM, for well over a decade now. Longstanding developers are, therefore, probably going to be well-versed in how to build them, but it&amp;rsquo;s always useful to get a refresher of old topics. With that in mind, let&amp;rsquo;s dive in!&lt;/p&gt;
&lt;p&gt;As with all posts in this series, the aim is to provide a broad outline of the core areas to keep in mind when tackling the exam, linked to appropriate resources for more focused study. Your revision should, ideally, involve a high degree of hands-on testing and familiarity in working with the platform if you want to do well in this exam. I would also recommend that you have a good, general knowledge of how to work with the &lt;a class="link" href="https://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29" target="_blank" rel="noopener"
&gt;C# programming language&lt;/a&gt; before approaching plug-in development for the first time. &lt;a class="link" href="https://dotnet.microsoft.com/learn/csharp" target="_blank" rel="noopener"
&gt;Microsoft has published a whole range of introductory material to help you learn the language quickly.&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="what-is-a-plug-in"&gt;What is a Plug-in?
&lt;/h3&gt;&lt;p&gt;In the series so far, we&amp;rsquo;ve already touched upon the following, functional tools that developers may leverage when dealing with complex business requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-implementing-business-rules/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Business Rules&lt;/strong&gt;&lt;/a&gt;: These provide an excellent mechanism for handling simple logic, targeting both model-driven app forms and also platform-level operations.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-using-power-automate-flows/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Power Automate Flows&lt;/strong&gt;&lt;/a&gt;: Using this, you can typically go the extra mile when compared with classic workflows, thereby allowing you to integrate multiple systems when processing asynchronous actions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a class="link" href="https://crmchap.co.uk/exam-mb-400-revision-notes-implementing-client-side-scripting-on-model-driven-power-apps/" target="_blank" rel="noopener"
&gt;JavaScript&lt;/a&gt;:&lt;/strong&gt; For situations where Business Rules can&amp;rsquo;t meet your particular requirement, and you need specific logic to trigger as a user is working on a model-driven form, this is the best tool in your arsenal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these are great, but there may be situations where they are unsuitable, due to the sheer complexity of the business logic you are trying to implement. Also, some of the above tools do not support the ability to carry out synchronous actions (i.e. ones that happen straight away, as the user creates, updates, deletes etc. records in the application). Finally, it may be that you need to work with some specific elements of the SDK that are not exposed out straightforwardly via alternative routes. In these situations, a custom-authored plug-in is the only solution you can turn too.&lt;/p&gt;
&lt;p&gt;So what are they then? Plug-ins allow developers to write either C# or VB.NET code, that is then registered within the application as a .NET Framework class library (DLL) and executed based on specific conditions you specify within its configuration. For example, when a user creates a Contact, retrieve the details of the parent Account record and update the Contact so that these details match. Developers will use Visual Studio when authoring a plug-in, typically using a class library project template. The &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/developer-tools" target="_blank" rel="noopener"
&gt;Dynamics 365 SDK&lt;/a&gt; provides several modules that expose out the variety of different operations that a plug-in can support. Some of the other things that plug-ins support include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Both synchronous and asynchronous execution.&lt;/li&gt;
&lt;li&gt;Custom un-secure/secure configuration properties that can modify the behaviour of a plug-in at runtime. For example, by providing credentials to a specific environment to access.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/utilising-prepost-entity-images-in-a-dynamics-crm-plugin/" target="_blank" rel="noopener"
&gt;Pre and Post Entity Images&lt;/a&gt;, snapshots of how a record and its related attributes looked before and after a platform level operation occurs.&lt;/li&gt;
&lt;li&gt;For specific operations, such as Update, plug-ins can also support filtering attributes - basically, a list of defined fields that, when modified, will cause the plug-in to trigger.&lt;/li&gt;
&lt;li&gt;Being able to specify the execution order for one or multiple plug-in steps. This capability can be useful when you need to ensure a set of steps execute in your desired order.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These days, thanks to tools such as Business Rules and Power Automate, we see the lessening importance of plug-ins and, typically, you would want to avoid considering their usage straight out the gate. However, they still have a place and, when used appropriately, become the only mechanism you can resort to when working with complicated business processes.&lt;/p&gt;
&lt;h3 id="understanding-messages-the-execution-pipeline--steps"&gt;Understanding Messages, the Execution Pipeline &amp;amp; Steps
&lt;/h3&gt;&lt;p&gt;Before we start diving into building a plug-in for the first time, it is useful to provide an overview of the three core concepts that every plug-in developer needs to know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Messages&lt;/strong&gt;: These define a specific, platform level operation that the SDK exposes out. Some of the more commonly used Messages within the application include &lt;strong&gt;Create&lt;/strong&gt;, &lt;strong&gt;Update&lt;/strong&gt; or &lt;strong&gt;Delete&lt;/strong&gt;. Some system entities may have their own set of unique Messages; &lt;strong&gt;CalculatePrice&lt;/strong&gt; is an excellent example of this. From a plug-in perspective, developers essentially &amp;ldquo;piggyback&amp;rdquo; onto these operations as they are performed and inject their custom code. &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/supported-messages-entities-plugin" target="_blank" rel="noopener"
&gt;The following Microsoft Docs provides a detailed list of all supported messages and their corresponding entities&lt;/a&gt; and is well worth a read as part of preparing for the exam.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execution Pipeline&lt;/strong&gt;: As a user triggers a particular message, the application processes it using a defined set of stages, known as the execution pipeline. &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/event-framework#event-execution-pipeline" target="_blank" rel="noopener"
&gt;These are discussed in detail on this Microsoft Docs article&lt;/a&gt;, but the key ones we need to be aware of are:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PreValidation&lt;/strong&gt;: At this stage, the database transaction has not started. Also, the application has not yet performed any appropriate security checks; potentially meaning that the operation may fail if the user does not have the correct security privileges.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostValidation&lt;/strong&gt;: Here, the database transaction has already started. The platform knows at this stage that no security constraints are preventing the operation from completing, but the transaction may still fail for other reasons.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostOperation&lt;/strong&gt;: Although the database transaction has still not completed at this stage, the core operation of the message (executed within the &lt;strong&gt;MainOperation&lt;/strong&gt; stage) will have completed by this stage.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A failure at any of these stages will cause the database transaction to rollback entirely, returning the record(s) to their original state. Now, from a plug-in perspective, the execution pipeline is exposed out to developers as stages where your custom code can execute. This can provide developers with a high degree of flexibility and capability when it comes to running their custom code. As a general rule of thumb, developers would use each of these stages under the following circumstances:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PreValidation&lt;/strong&gt;: Use this stage to perform checks to cancel the operation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostValidation&lt;/strong&gt;: This stage is useful for when you need to modify any values, based on some kind of business logic. Doing this at this stage would also prevent triggering another platform Message.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostOperation&lt;/strong&gt;: Use this stage for when you need to carry out additional logic not related to the current record or potentially provide additional information back to the caller after the platform completes the core operation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Developers will typically need to give some thought towards the execution pipeline and the most appropriate one to select, based on the requirements being worked with.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Steps&lt;/strong&gt;: Simply writing a plug-in class and deploying out the library is not sufficient to trigger your custom logic. Developers must additionally provide a set of &amp;ldquo;instructions&amp;rdquo;, commonly known as Steps, that &lt;em&gt;tells&lt;/em&gt; the application when and where to execute your custom code. It is here where both the Message and Execution Pipeline come into play, and you would always specify this information when creating a Step. Additional info you can include here includes the execution order, whether the plug-in will execute synchronously or not and the display name of Step when viewed within the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will see shortly how these topics come into play, as part of using the Plug-in Registration Tool.&lt;/p&gt;
&lt;h3 id="building-your-first-plug-in-pre-requisites"&gt;Building Your First Plug-In: Pre-Requisites
&lt;/h3&gt;&lt;p&gt;Before you start thinking about building your very first plug-in, you need to make sure that you have a few things installed onto your development machine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://visualstudio.microsoft.com/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Visual Studio&lt;/strong&gt;&lt;/a&gt;: I would generally recommend using either Visual Studio 2017 or 2019 when developing for Dynamics 365 online. If you don&amp;rsquo;t have a Visual Studio/MSDN subscription, then the &lt;a class="link" href="https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&amp;amp;rel=16" target="_blank" rel="noopener"
&gt;Community Edition&lt;/a&gt; can be used instead.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A Dynamics 365 / Common Data Service Tenant&lt;/strong&gt;: Because where else are you going to deploy out and test your plug-in? 🙂&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowledge of C#  / VB.NET&lt;/strong&gt;: Attempting to write a plug-in for the first time without at least a &lt;em&gt;basic&lt;/em&gt; grasp of one of these languages will impede your progress.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plug-in Registration Tool&lt;/strong&gt;: To deploy your plug-in out, you will need access to this tool as well. We will cover this off later in the post.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="demo-creating-a-basic-plug-in-using-visual-studio-2019--c"&gt;Demo: Creating a Basic Plug-in using Visual Studio 2019 &amp;amp; C#
&lt;/h3&gt;&lt;p&gt;The best way to learn how to create a plug-in is to see someone build one from scratch. In the YouTube video below, I talk through how to build a straightforward plug-in using Visual Studio 2019 and C#:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/EzT40-N8Kk4"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;For those who would prefer to read a set of instructions, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/tutorial-write-plug-in" target="_blank" rel="noopener"
&gt;then this Microsoft Docs article provides a separate tutorial you can follow instead&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="using-the-plug-in-registration-tool"&gt;Using the Plug-in Registration Tool
&lt;/h3&gt;&lt;p&gt;Once you&amp;rsquo;ve written your first plug-in, you then need to consider how to deploy this out. In most cases, you will use the Plug-in Registration Tool to accomplish this. &lt;a class="link" href="https://www.nuget.org/packages/Microsoft.CrmSdk.XrmTooling.PluginRegistrationTool" target="_blank" rel="noopener"
&gt;Available on NuGet&lt;/a&gt;, this lightweight application supports the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Varied access options for when working with multiple Dynamics 365 environments, both online and on-premise.&lt;/li&gt;
&lt;li&gt;The ability to register one or multiple plug-in assemblies.&lt;/li&gt;
&lt;li&gt;The registering of plug-in steps and images, including the various settings, discussed earlier.&lt;/li&gt;
&lt;li&gt;Via the tool, you can install the &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/debug-plug-in#use-plug-in-profiler" target="_blank" rel="noopener"
&gt;Plug-in Profiler&lt;/a&gt;, an essential tool when it comes to remote debugging your plug-ins; more on this capability later.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Plug-In Registration Tool is also necessary for when you are deploying out other extensibility components, including &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/walkthrough-register-azure-aware-plug-in-using-plug-in-registration-tool" target="_blank" rel="noopener"
&gt;Service Endpoints&lt;/a&gt;, &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/use-webhooks" target="_blank" rel="noopener"
&gt;Web Hooks&lt;/a&gt; or &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/virtual-entities/custom-ve-data-providers" target="_blank" rel="noopener"
&gt;Custom Data Providers&lt;/a&gt;. We will touch upon some of these later on in the series. For this topic area and the exam, you must have a good general awareness of how to deploy and update existing plug-in assemblies.&lt;/p&gt;
&lt;h3 id="demo-deploying-a-basic-plug-in-using-the-plug-in-registration-tool"&gt;Demo: Deploying a Basic Plug-in using the Plug-in Registration Tool
&lt;/h3&gt;&lt;p&gt;In this next video, I&amp;rsquo;ll show you how to take the plug-in developed as part of the previous video and deploy it out using the Plug-in Registration Tool:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/ybmt2AAKT8Q"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/tutorial-write-plug-in#register-plug-in" target="_blank" rel="noopener"
&gt;There is also a corresponding Microsoft Docs tutorial that covers off these steps too&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="debugging-options-for-plug-ins"&gt;Debugging Options for Plug-ins
&lt;/h3&gt;&lt;p&gt;Plug-ins deployed out into Dynamics 365 must always run within sandbox execution mode. As a result, this imposes a couple of limitations (some of which I&amp;rsquo;ll highlight in detail later on), the main one being that it greatly hinders the ability to debug deployed plug-ins &lt;em&gt;easily&lt;/em&gt;. To get around this, Microsoft has provided two mechanisms that developers can leverage:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Plug-in Trace Logging&lt;/strong&gt;: Using this, developers can write out custom log messages into the application, at any point in their code. This can be useful in identifying the precise location where a plug-in is not working as expected, as you can output specific values to the log for further inspection. You can also utilise them to provide more accurate error messages for your code that you would not necessarily wish to show users as part of a dialog box. Getting to grips with trace logging is easy - it&amp;rsquo;s just a few lines of code that you need to add to your project - &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/logging-tracing" target="_blank" rel="noopener"
&gt;and you can find out more about how to get started with it on the Microsoft Docs site&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plug-in Registration Tool &amp;amp; Profiling&lt;/strong&gt;: While trace logging is undoubtedly useful, there will be situations where you need something &lt;em&gt;more&lt;/em&gt;. For example, it may become desirable to breakpoint code, inspect values/properties as they are processed through and determine when your plug-in hits specific conditions or error messages. For these situations, the Profiler comes into play, by allowing developers to &amp;ldquo;playback&amp;rdquo; their code execution using Visual Studio and the Plug-in Registration Tool. We mentioned the Plug-in Profiler tool earlier, which is a mandatory requirement as part of this and must be deployed out to your instance first. From there, you can generate a profile file that allows you to rewind execution within Visual Studio.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Developers will typically use both of these debugging methods in tandem when trying to figure out issues with their code. The first option provides a friendly, unobtrusive mechanism of inspecting how a plug-in has got on, with the Profiler acting as the nuclear option when the problem cannot be discerned easily via trace logging alone. Understanding the benefits/disadvantages of both and how to use them will be essential as part of your exam preparation. With this in mind, check out the two demo videos below that show you how to work with these features in-depth:&lt;/p&gt;
&lt;h3 id="demo-debugging-a-basic-plug-in-using-trace-logging"&gt;Demo: Debugging a Basic Plug-in using Trace Logging
&lt;/h3&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/60zGFRwhN4E"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="demo-debugging-a-basic-plug-in-using-the-plug-in-registration-tool"&gt;Demo: Debugging a Basic Plug-in Using the Plug-in Registration Tool
&lt;/h3&gt;&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/c12eZQSKZO0"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h3 id="general-performance--optimization-tips"&gt;General Performance / Optimization Tips
&lt;/h3&gt;&lt;p&gt;Anyone can build and deploy a plug-in, but it can take some time before you can do this &lt;em&gt;well&lt;/em&gt;. Here are a few tips that you should always follow to ensure your plug-ins perform well when deployed out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Always keep in mind some of the limitations as part of sandbox execution for your plug-ins, including:
&lt;ul&gt;
&lt;li&gt;The 2 minute limit on execution time.&lt;/li&gt;
&lt;li&gt;Restriction on the use of specific 3rd party DLL&amp;rsquo;s, such as &lt;a class="link" href="https://www.newtonsoft.com/json" target="_blank" rel="noopener"
&gt;Newtonsoft.Json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Various restrictions around accessing operating system level information, such as directories, system state etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For situations where sandbox limitation will cause issues in executing your business logic, you will need to consider moving away from a plug-in and adopting another solution.&lt;/li&gt;
&lt;li&gt;Filtering attributes provide a great way of ensuring your code only executes when you need it to. You should always use these wherever possible.&lt;/li&gt;
&lt;li&gt;Make sure to disable any plug-in profiling and remove the Profiler solution once you are finished. Active profiles can considerably slow down performance, and the Profile solution can also introduce unintended dependencies on core entities, causing difficulties when moving changes as part of a solution file.&lt;/li&gt;
&lt;li&gt;The &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/use-powerapps-checker" target="_blank" rel="noopener"
&gt;Solution Checker&lt;/a&gt; provides an excellent mechanism for quality checking your code and can give some constructive recommendations on where your plug-in can be improved. You should always run this at least once before moving your plug-in out into other environments.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/best-practices/business-logic/optimize-assembly-development" target="_blank" rel="noopener"
&gt;Read through the following Microsoft Docs article&lt;/a&gt; and take care to follow the suggestions it outlines.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dont-forgetcustom-actions--global-discovery-service-endpoint"&gt;Don&amp;rsquo;t Forget&amp;hellip;Custom Actions &amp;amp; Global Discovery Service Endpoint
&lt;/h3&gt;&lt;p&gt;As Microsoft has included them on the exam specification, it&amp;rsquo;s worth talking about these two topics briefly. However, only a general awareness of them should be sufficient, and I wouldn&amp;rsquo;t devote too much of your revision time towards them.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve already looked at Messages in-depth and seen how they can act as a &amp;ldquo;gateway&amp;rdquo; for developers to bolt on specific logic when an application-level event occurs. &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/custom-actions" target="_blank" rel="noopener"
&gt;Custom Actions&lt;/a&gt; allow you to take this a step further, by creating SDK/API exposable, custom Messages. For example, you could combine the Create/Update Messages of the Lead/Opportunity entities into a new message called &lt;strong&gt;SalesProgress&lt;/strong&gt;. Plug-ins or operations targeting the Web API could then work with or trigger actions based on this. Custom Actions have been available within the application for many years now, and many developers continually argue them as being one of the most underrated features in Dynamics 365. &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/commondataserviceforapps/#perform-a-bound-action" target="_blank" rel="noopener"
&gt;They are also fully supported for use as part of Power Automate flows too&lt;/a&gt;. In short, they can be incredibly useful if you need to group multiple default messages into a single action, that can then be called instead of each one.&lt;/p&gt;
&lt;p&gt;Finally, it is worth touching upon how developers use the &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/webapi/discover-url-organization-web-api" target="_blank" rel="noopener"
&gt;Global Discovery Endpoint&lt;/a&gt; from a plug-in standpoint, but we must first touch upon the concepts of early-binding and late binding. In the video demos above, I wrote all of the code out using the &lt;em&gt;late-binding&lt;/em&gt; mechanism. What this means is that, instead of declaring an object for the specific entity I wanted to work with (such as Contact), I instead used the generic &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.entity?view=dynamics-general-ce-9" target="_blank" rel="noopener"
&gt;Entity&lt;/a&gt; class and told the code which entity it&amp;rsquo;s supposed to represent. Which is fine, and gives me some degree of flexibility&amp;hellip;but it does ultimately mean that I won&amp;rsquo;t detect any issues with my code (such as an incorrect field name) until runtime. Also, I have no easy way to tell how my entity looks using Intellisense; instead, I must continuously refer back to the application to view these properties. To get around this, we can use a mechanism known as &lt;em&gt;early-binding&lt;/em&gt;, where all of the appropriate entity structures are generated within the project and referenced accordingly. &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/org-service/create-early-bound-entity-classes-code-generation-tool" target="_blank" rel="noopener"
&gt;The CrmSvcUtil.exe application provides a streamlined means of creating these early-bound classes&lt;/a&gt; and, as you might have guessed, you need to use the Global Discovery Endpoint to generate these classes successfully. There have been many previous wars and mounds of dead developers debates online regarding which mechanism is better. While early-binding does afford some great benefits, it does add some overhead into your development cycle, as you must continuously run the CrmSvcUtil application each time your entities change within Dynamics 365. All I would recommend is to try both options, identify the one that works best for you and, most importantly, adopt your preferred solution consistently.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Plug-ins can help when modelling out complicated business logic, that is impossible to achieve via other functional tools within the Power Platform. I hope this post has provided a good insight into their capabilities and to help you in your revision. In the next post, I&amp;rsquo;ll show you how you can extend Power Automate and Power Apps via custom API connectors, thereby allowing you to connect to a myriad of different systems.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Using SQL Server Views within Entity Framework Core (Code First Data Annotations)</title><link>/using-sql-server-views-within-entity-framework-core-code-first-data-annotations/</link><pubDate>Sun, 05 Jul 2020 00:00:00 +0000</pubDate><guid>/using-sql-server-views-within-entity-framework-core-code-first-data-annotations/</guid><description>&lt;img src="/images/CSharpVS-FI.png" alt="Featured image of post Using SQL Server Views within Entity Framework Core (Code First Data Annotations)" /&gt;&lt;p&gt;If you&amp;rsquo;ve done any serious work involving &lt;a class="link" href="https://docs.microsoft.com/en-us/ef/" target="_blank" rel="noopener"
&gt;Entity Framework (EF) Core&lt;/a&gt; in the past, there&amp;rsquo;s a good chance that you&amp;rsquo;ve worked with Code First Data Annotations when modelling your classes in C#. To summarise, these provide you with an in-line mechanism of &lt;em&gt;describing&lt;/em&gt; the various DDL objects that you are referencing from your underlying data source. Typically, this may be required when you need the names, attributes and other general properties of your classes to differ from what your data source is surfacing. They are also an almost mandatory requirement when you want EF Core to handle the creation of your database automatically when deploying out your project for the first time. While I do personally find this approach to be borderline heretical, it is nonetheless a valid means of modelling out a database that is intrinsically bound to your EF Core project. So don&amp;rsquo;t let me put you off from using it if it will meet your particular requirements.&lt;/p&gt;
&lt;p&gt;Now, it&amp;rsquo;s all well and good &lt;em&gt;saying&lt;/em&gt; that something is good, but it&amp;rsquo;s far more important, I think, to see how it works in action. With this in mind, let&amp;rsquo;s assume we are adopting a pious approach for our EF Core project - namely, our database is already existing - and we are dealing with a mismatch between our database and class object names. Specifically, suppose we want to expose out a class called &lt;strong&gt;MyClass&lt;/strong&gt;, but our underlying data source is a SQL Server table called &lt;strong&gt;MyTable&lt;/strong&gt;. We would have to utilise the &lt;a class="link" href="https://www.entityframeworktutorial.net/code-first/table-dataannotations-attribute-in-code-first.aspx" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Table&lt;/strong&gt;&lt;/a&gt; annotation, as demonstrated below, to ensure our code can navigate across to our intended location at runtime:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.ComponentModel.DataAnnotations.Schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyEFProject.Classes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Table(&amp;#34;MyTable&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Column definitions go here...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can extend this further if we happen to be using custom schemas within our database. So, if we choose to create our &lt;strong&gt;MyTable&lt;/strong&gt; within a schema called &lt;strong&gt;Sample&lt;/strong&gt;, we can adjust the annotation as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.ComponentModel.DataAnnotations.Schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyEFProject.Classes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Table(&amp;#34;MyTable&amp;#34;, Schema = &amp;#34;Sample&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Column definitions go here...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pretty neat. But what happens if we need to reference a view as opposed to a table instead? I dealt with this requirement recently when building out a read-only OData endpoint using ASP.NET Core MVC and, despite my efforts, I could not locate a valid source to tell me that views are a supported. Well, after experimenting further, I can confirm that it IS possible to do this via the very same &lt;strong&gt;Table&lt;/strong&gt; Annotation used earlier. So, if our SQL Server view is called &lt;strong&gt;vw_MyView&lt;/strong&gt; and exists on the very same schema referenced earlier, here&amp;rsquo;s how our class would need to look:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.ComponentModel.DataAnnotations.Schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyEFProject.Classes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Table(&amp;#34;vw_MyView&amp;#34;, Schema = &amp;#34;Sample&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Column definitions go here...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And, although I have not tested this myself, it should also be possible for you to then write or update data into the view, &lt;a class="link" href="https://docs.microsoft.com/en-us/sql/relational-databases/views/modify-data-through-a-view?view=sql-server-ver15" target="_blank" rel="noopener"
&gt;in much the same manner as we can write manual SQL queries to do just this.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Using Data Annotations within EF Core can significantly simplify the process for handling situations like the ones described in this post, without needing to write a whole bunch of specialised code instead. If you haven&amp;rsquo;t already, &lt;a class="link" href="https://docs.microsoft.com/en-us/ef/ef6/modeling/code-first/data-annotations" target="_blank" rel="noopener"
&gt;I will urge you to read through this informative Microsoft Docs article&lt;/a&gt;, which talks through in detail the types of things you can do with them. To summarise then, never treat Data Annotations as a one-trick pony. Regardless of whether you are getting EF Core to handle the creation of your database structure automatically or are referencing an existing database, there will be a whole host of options available here to help you along.&lt;/p&gt;</description></item><item><title>Using Logic Apps &amp; Azure Functions to Parse Variable Common Data Service Entity Data</title><link>/using-logic-apps-azure-functions-to-parse-variable-common-data-service-entity-data/</link><pubDate>Sun, 17 May 2020 00:00:00 +0000</pubDate><guid>/using-logic-apps-azure-functions-to-parse-variable-common-data-service-entity-data/</guid><description>&lt;img src="/images/Azure-e1557238846431.png" alt="Featured image of post Using Logic Apps &amp; Azure Functions to Parse Variable Common Data Service Entity Data" /&gt;&lt;p&gt;The great thing when you are working with &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-overview" target="_blank" rel="noopener"
&gt;Azure Logic Apps&lt;/a&gt; is that, if you have previously spent any amount of time understanding &lt;a class="link" href="https://flow.microsoft.com/en-us/" target="_blank" rel="noopener"
&gt;Power Automate flows&lt;/a&gt;, the knowledge gained in this area is instantly transferable. That&amp;rsquo;s mainly because Power Automate is utilising Logic Apps underneath the hood. In practice, therefore, you can anticipate that a lot of the same trigger actions, connectors and general functionality will be identical. So why would you consider using Logic Apps at all in the first place? There are a few reasons why:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Logic Apps are a consumption-based service, meaning you are charged based on the number of monthly executions. Depending on the volumes involved, this can come in significantly cheaper when compared to buying a Power Automate license.&lt;/li&gt;
&lt;li&gt;Logic Apps support the ability to execute within a dedicated location as part of &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/logic-apps/connect-virtual-network-vnet-isolated-environment-overview" target="_blank" rel="noopener"
&gt;integration service environments (ISE&amp;rsquo;s)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It is far easier to incorporate Logic Apps development as part of your Application Lifecycle Management (ALM) processes, with the ability to do one-click extracts of deployment templates. What&amp;rsquo;s more, you have a high degree of control over the parameterisation, deployment location and general functionality of Logic Apps when compared with Power Automate flows.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So in most senses, Logic Apps functionality can be argued as being on a par with that of Power Automate flows, often exceeding capabilities in some areas and being far better suited for large-scale, pro-developer integrations between systems.&lt;/p&gt;
&lt;p&gt;Now, I use the work &lt;em&gt;argued&lt;/em&gt;, as I cannot reliably say that the functionality on offer is complete like-for-like, especially when it comes to working with Dynamics 365 / the Common Data Service. Now it is true that we have a Common Data Service connector within Logic Apps, that has a list of actions that is equivalent to what is available within Power Automate:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/LogicApps-Connectors-CommonDataServiceActions.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;However, there are two issues I can specifically highlight here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Power Automate introduced the &lt;strong&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/commondataserviceforapps/" target="_blank" rel="noopener"
&gt;Common Data Service (current environment)&lt;/a&gt;&lt;/strong&gt; connector a while back, which does exactly what it says on the tin. Also, this connector offers several additional features/benefits, such as the ability to &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/commondataserviceforapps/#executes-a-changeset-request" target="_blank" rel="noopener"
&gt;execute change set requests&lt;/a&gt; or &lt;a class="link" href="https://docs.microsoft.com/en-us/connectors/commondataserviceforapps/#upload-file-or-image-content" target="_blank" rel="noopener"
&gt;upload files/images&lt;/a&gt; to an entity record. This connector is not exposed at all within Logic Apps, even if you are in the same tenant where your Common Data Service environments reside. Logic App users, therefore, lose some degree of functionality here compared to Power Automate flows.&lt;/li&gt;
&lt;li&gt;When using the &lt;strong&gt;List records&lt;/strong&gt; action, you have access to all of the common OData filter queries, such as &lt;strong&gt;filter&lt;/strong&gt;, &lt;strong&gt;top&lt;/strong&gt; and &lt;strong&gt;orderby&lt;/strong&gt;, thereby allowing you to return a specific subset of the data you require. However, you have no option here to indicate the precise fields you wish to return - via a &lt;strong&gt;select&lt;/strong&gt; option or similar. This limitation can lead to your requests into the Common Data Service processing far more data than necessary and lengthen the execution time of your Logic Apps.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can get around the second of these issues straightforwardly enough by using a &lt;a class="link" href="https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-perform-data-operations#parse-json-action" target="_blank" rel="noopener"
&gt;Parse JSON action&lt;/a&gt; to consume and then remove any fields you don&amp;rsquo;t wish to process any further as part of your Logic App. But what if the data you wish to process from the Common Data Service is variable? For example, let&amp;rsquo;s assume that the entity and list of fields to be processed differs each time the Logic App runs - dictated by either the creation of a database record or by the details of a request passed to an HTTP endpoint setup on the Logic App. In this instance, it is not possible to use the Parse JSON action to parameterise this information satisfactorily. Indeed, to the best of my knowledge, it is not possible to utilise &lt;em&gt;any&lt;/em&gt; of the collection/data operation functions available via the Workflow Definition Language to perform this action instead. Fortunately, where there is a will - and a bit of knowledge of C# - there is a way ;)&lt;/p&gt;
&lt;p&gt;Logic Apps have had the longstanding capability to integrate alongside Azure Functions, thereby allowing developers to off-load any complex processing to a programming interface that can do almost anything you can imagine. So, in this case, Azure Functions becomes our rescuer and allows us to build out a basic Function App to support us. We can design the function app to accept two core bits of information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A JSON array containing the response from Common Data Service. The JSON&amp;rsquo;s basic structure should look somewhat similar to the example below, representing two &lt;strong&gt;Lead&lt;/strong&gt; records, for the function to parse it correctly. As you can see, this is a LOT of data that Logic Apps returns by default, for a measly 2 Lead records:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;@odata.id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://mycrminstance.crm11.dynamics.com/api/data/v9.0/leads(cd4299fe-a080-ea11-a811-002248012503)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;@odata.etag&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;ItemInternalId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cd4299fe-a080-ea11-a811-002248012503&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;prioritycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_prioritycode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_addresstypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_address2_addresstypecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;merged&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;emailaddress1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;someonel1@example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;confirminterest&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;numberofemployees&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;decisionmaker&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;msdyn_ordertype&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;192350000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_msdyn_ordertype_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Item based&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;modifiedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2020-04-17T11:46:57Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;importsequencenumber&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_composite&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;789 Jones Blvd\r\nLa Vergne, TN 57332\r\nU.S.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;McKay (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotpostalmail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;revenue_base&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;100000.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;preferredcontactmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_preferredcontactmethodcode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Any&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_ownerid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9ec35ef0-9ec9-4e2e-b4af-e16bf5ba3b9b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_ownerid_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemusers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_campaignid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;e14099fe-a080-ea11-a811-002248012503&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_campaignid_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;campaigns&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Yvonne&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;evaluatefit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomifullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Yvonne McKay (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Yvonne McKay (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;msdyn_gdproptout&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_statuscode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;New&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;createdon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2020-04-17T11:46:57Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_stateorprovince&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;TN&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;companyname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Fourth Coffee (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotfax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;leadsourcecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_leadsourcecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Advertisement&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;jobtitle&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Purchasing Manager&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_country&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;U.S.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;versionnumber&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11127594&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_line1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;789 Jones Blvd&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;telephone1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;555-0146&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotsendmm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;leadqualitycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_leadqualitycode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Warm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotphone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_transactioncurrencyid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;d85b13bb-081f-ea11-a812-00224801bc51&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_transactioncurrencyid_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;transactioncurrencies&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;New store opened this year - follow up (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_addresstypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_address1_addresstypecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotbulkemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;exchangerate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_modifiedby_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9ec35ef0-9ec9-4e2e-b4af-e16bf5ba3b9b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_modifiedby_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemusers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;followemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;leadid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cd4299fe-a080-ea11-a811-002248012503&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_createdby_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9ec35ef0-9ec9-4e2e-b4af-e16bf5ba3b9b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_createdby_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemusers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;websiteurl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;http://www.fourthcoffee.com/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;La Vergne&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;salesstagecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_salesstagecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;revenue&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;100000.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;participatesinworkflow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_statecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Open&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_owningbusinessunit_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9941c9c6-f71e-ea11-a812-00224801bc51&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_owningbusinessunit_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;businessunits&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_postalcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;57332&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;budgetamount_base&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;salutation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_latitude&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_fax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomilastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_longitude&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;telephone2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;timespentbymeonemailandmeetings&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_upszone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;schedulefollowup_qualify&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_slainvokedid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;schedulefollowup_prospect&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;purchasetimeframe&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_purchasetimeframe_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_owningteam_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;industrycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_industrycode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;budgetstatus&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_budgetstatus_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;stageid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_accountid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;lastonholdtime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_country&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_utcoffset&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;onholdtime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_line2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_createdonbehalfby_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;telephone3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;fax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;emailaddress2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_parentcontactid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;businesscard&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;estimatedamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_telephone1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;overriddencreatedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_county&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_stateorprovince&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_masterid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_qualifyingopportunityid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;lastusedincampaign&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_composite&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_originatingcaseid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;utcconversiontimezonecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;purchaseprocess&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_purchaseprocess_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_line3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;emailaddress3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;salesstage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_salesstage_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_relatedobjectid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;processid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;pager&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_upszone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_modifiedonbehalfby_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mobilephone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;initialcommunication&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_initialcommunication_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_latitude&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;qualificationcomments&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;middlename&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_telephone2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_utcoffset&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entityimage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_parentaccountid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_telephone1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_county&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_line3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomicompanyname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;need&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_need_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomimiddlename&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entityimage_url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entityimageid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_telephone3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_slaid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_line1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_postofficebox&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_longitude&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_telephone2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_fax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;traversedpath&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_line2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;businesscardattributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_postofficebox&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entityimage_timestamp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_customerid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;teamsfollowed&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomifirstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;timezoneruleversionnumber&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_contactid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_telephone3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;estimatedvalue&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;estimatedclosedate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_postalcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;budgetamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;estimatedamount_base&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;@odata.id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://mycrminstance.crm11.dynamics.com/api/data/v9.0/leads(cf4299fe-a080-ea11-a811-002248012503)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;@odata.etag&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;ItemInternalId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cf4299fe-a080-ea11-a811-002248012503&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;prioritycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_prioritycode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_addresstypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_address2_addresstypecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;merged&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;emailaddress1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;someonel2@example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;confirminterest&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;numberofemployees&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;decisionmaker&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;msdyn_ordertype&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;192350000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_msdyn_ordertype_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Item based&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;modifiedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2020-04-17T11:46:58Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;importsequencenumber&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_composite&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;797 Roosevelt Ave NE\r\nSaint Louis, MO 83385\r\nU.S.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Stubberod (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotpostalmail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;revenue_base&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;150000.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;preferredcontactmethodcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_preferredcontactmethodcode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Any&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_ownerid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9ec35ef0-9ec9-4e2e-b4af-e16bf5ba3b9b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_ownerid_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemusers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_campaignid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;e14099fe-a080-ea11-a811-002248012503&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_campaignid_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;campaigns&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Susanna&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;evaluatefit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomifullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Susanna Stubberod (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Susanna Stubberod (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;msdyn_gdproptout&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_statuscode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;New&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;createdon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2020-04-17T11:46:58Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_stateorprovince&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MO&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;companyname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Litware, Inc. (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotfax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;leadsourcecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_leadsourcecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Trade Show&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;jobtitle&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Purchasing Manager&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_country&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;U.S.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;versionnumber&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11127601&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_line1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;797 Roosevelt Ave NE&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;telephone1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;555-0127&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotsendmm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;leadqualitycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_leadqualitycode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Hot&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotphone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_transactioncurrencyid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;d85b13bb-081f-ea11-a812-00224801bc51&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_transactioncurrencyid_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;transactioncurrencies&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Mailed an interest card back (sample)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_addresstypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_address1_addresstypecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;donotbulkemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;exchangerate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_modifiedby_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9ec35ef0-9ec9-4e2e-b4af-e16bf5ba3b9b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_modifiedby_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemusers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;followemail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;leadid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cf4299fe-a080-ea11-a811-002248012503&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_createdby_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9ec35ef0-9ec9-4e2e-b4af-e16bf5ba3b9b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_createdby_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;systemusers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;websiteurl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;http://www.litwareinc.com/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Saint Louis&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;salesstagecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_salesstagecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Default Value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;revenue&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;150000.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;participatesinworkflow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_statecode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Open&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_owningbusinessunit_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;9941c9c6-f71e-ea11-a812-00224801bc51&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_owningbusinessunit_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;businessunits&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_postalcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;83385&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;budgetamount_base&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;3000.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;salutation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_latitude&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_fax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomilastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_longitude&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;telephone2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;timespentbymeonemailandmeetings&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_upszone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;schedulefollowup_qualify&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_slainvokedid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;schedulefollowup_prospect&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;purchasetimeframe&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_purchasetimeframe_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Next Quarter&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_owningteam_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;industrycode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_industrycode_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;budgetstatus&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_budgetstatus_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;stageid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_accountid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;lastonholdtime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_country&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_utcoffset&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;onholdtime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_line2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_createdonbehalfby_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;telephone3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;fax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;emailaddress2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_parentcontactid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;businesscard&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;estimatedamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_telephone1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;overriddencreatedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_county&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_stateorprovince&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_masterid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_qualifyingopportunityid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;lastusedincampaign&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_composite&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_originatingcaseid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;utcconversiontimezonecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;purchaseprocess&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_purchaseprocess_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Committee&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_line3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;emailaddress3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;salesstage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_salesstage_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_relatedobjectid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;processid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;pager&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_upszone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_modifiedonbehalfby_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mobilephone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;initialcommunication&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_initialcommunication_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_latitude&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;qualificationcomments&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;middlename&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_telephone2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_utcoffset&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entityimage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_parentaccountid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_telephone1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_county&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_line3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomicompanyname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;need&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_need_label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomimiddlename&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entityimage_url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entityimageid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_telephone3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_slaid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_line1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_postofficebox&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_longitude&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_telephone2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_fax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;traversedpath&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_line2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;businesscardattributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_postofficebox&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;entityimage_timestamp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_customerid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;teamsfollowed&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;yomifirstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;timezoneruleversionnumber&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;_contactid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address1_telephone3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;estimatedvalue&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;estimatedclosedate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;address2_postalcode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;budgetamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;3000.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;estimatedamount_base&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;A query parameter header - called &lt;strong&gt;attributes&lt;/strong&gt; - containing the list of attributes we wish to return as a comma-separated list e.g. &lt;strong&gt;fullname,companyname&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can then feed these two bits of information into an Azure Function endpoint, with the complete code for this illustrated below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Mvc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Azure.WebJobs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Azure.WebJobs.Extensions.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Logging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Newtonsoft.Json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Newtonsoft.Json.Linq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Linq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;APIHelper.LogicApps&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SelectJSONAttributes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [FunctionName(&amp;#34;SelectJSONAttributes&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [HttpTrigger(AuthorizationLevel.Anonymous, &amp;#34;post&amp;#34;, Route = null)]&lt;/span&gt; &lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;C# HTTP trigger function processed a request.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;attributes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;requestBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ReadToEndAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;JArray&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BadRequestObjectResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;The &amp;#39;attributes&amp;#39; query parameter is missing from the request.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JObject&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Children&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;retainKeys&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;removeKeys&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Except&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retainKeys&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;removeKeys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OkObjectResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JsonReaderException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BadRequestObjectResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JsonSerializationException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BadRequestObjectResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To then add this onto your Logic Apps after deploying out to your function app, there are a few additional steps you&amp;rsquo;ll need to do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable the managed identity for your Logic App. I recommend using the system-assigned option, as it makes the setup process a whole lot easier.&lt;/li&gt;
&lt;li&gt;One enabled, this managed identity object needs to be granted &lt;strong&gt;Contributor&lt;/strong&gt; permission or higher onto the Azure Function App.&lt;/li&gt;
&lt;li&gt;When setting up the Logic App, ensure that the authentication settings mirror the options indicated below:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="/images/LogicApps-Connectors-AzureFunctionAuthenticationSettings.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;With all that done, we can test the Logic App and confirm everything works as expected:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/LogicApps-Connectors-AzureFunctionSelectJSONAttributesInputs.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/LogicApps-Connectors-AzureFunctionSelectJSONAttributesOutputs.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s working! 🙂 And thanks to the capabilities built into the &lt;a class="link" href="https://www.newtonsoft.com/json" target="_blank" rel="noopener"
&gt;Newtonsoft JSON framework&lt;/a&gt;, the amount of actual code written is kept to an absolute minimum.&lt;/p&gt;
&lt;p&gt;Now, even though I am blogging about this solution, I must highlight that I am not an overall fan and am frustrated slightly that Logic Apps does not have a way around this. Answers on a postcard if you think I have missed something glaringly obvious but, for now, and until the Common Data Service connector exposes out an appropriate &lt;strong&gt;select&lt;/strong&gt; column option, this is the best solution we have available to us. Ultimately, we should take solace in the fact that Azure Functions are blisteringly easy to get set up and running. Also, for this particular scenario, they provide a streamlined way for us to leverage the low-code capabilities of Logic Apps and dip into more complex, bespoke processing, without necessarily needing to throw Logic Apps out of the window in the first place.&lt;/p&gt;</description></item><item><title>A Few Observations on Using Custom Pricing Plugins Alongside Project Service Automation</title><link>/a-few-observations-on-using-custom-pricing-plugins-alongside-project-service-automation/</link><pubDate>Sun, 11 Aug 2019 00:00:00 +0000</pubDate><guid>/a-few-observations-on-using-custom-pricing-plugins-alongside-project-service-automation/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post A Few Observations on Using Custom Pricing Plugins Alongside Project Service Automation" /&gt;&lt;p&gt;The problem sometimes, when developing a bespoke solution, is that it is impossible to anticipate how it may evolve. Whether it becomes dependent on changed functionality or new systems introduced into the equation, this eventuality is not necessarily down to a scoping or requirements gathering error. Organisations can, and will, drive off into all sorts of unexpected directions over time and, like it or lump it, IT systems are generally the last to follow behind any change. In this week&amp;rsquo;s post, I want to focus on a recent example I was involved in related to this theme, involving &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customer-engagement/basics/basics-guide" target="_blank" rel="noopener"
&gt;Dynamics 365 Customer Engagement (D365CE)&lt;/a&gt; and the &lt;a class="link" href="https://dynamics.microsoft.com/en-us/project-service-automation/overview/" target="_blank" rel="noopener"
&gt;Project Service Automation (PSA)&lt;/a&gt; add-on.&lt;/p&gt;
&lt;h3 id="setting-the-scene-what-is-a-custom-pricing-plug-in"&gt;Setting the Scene: What is a Custom Pricing Plug-in?
&lt;/h3&gt;&lt;p&gt;Those familiar the D365CE will no doubt be able to explain how the application automatically totals up the various product line items for core, sales-related entities - &lt;strong&gt;Opportunity&lt;/strong&gt;, &lt;strong&gt;Quote&lt;/strong&gt; etc. Typically, this behaviour will be suitable for most scenarios, but there may be situations where fine-tuning is required to factor in additional calculations or perform a bespoke integration. For example, there may be a requirement to query an external ERP system to ensure that the &lt;strong&gt;Cost Price&lt;/strong&gt; value for a line item record is correct. And, while it is undoubtedly possible to customise the application &lt;em&gt;around&lt;/em&gt; how the default pricing calculations work, solutions of this nature can typically become unwieldy to maintain over time. Besides, you always remain at the mercy of how the application decides to perform sales entity calculations, which may be subject to change between major version releases of D365CE.&lt;/p&gt;
&lt;p&gt;Fortunately, one of (I believe) the best-kept secrets concerning this functionality is that a) it can be disabled entirely and b) replaced with new pricing logic of your choosing. &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/use-custom-pricing-products" target="_blank" rel="noopener"
&gt;The &lt;strong&gt;CalculatePrice&lt;/strong&gt; message is the C#/VB.NET developer&amp;rsquo;s gateway towards achieving this and, by developing a bespoke plug-in, it is possible to tailor all sales calculations completely.&lt;/a&gt; While implementing a solution of this nature does, invariably, introduce a degree of complexity into your D365CE deployment, it does have several benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoids a messy/&amp;ldquo;hacky&amp;rdquo; solution from being implemented using Business Rules, Flows or any other customisation feature within the application.&lt;/li&gt;
&lt;li&gt;Provides the capability to apply the same calculations to all sales entities quickly or implement bespoke logic to calculate &lt;strong&gt;Quotes&lt;/strong&gt; differently from &lt;strong&gt;Opportunity&lt;/strong&gt; records, for example.&lt;/li&gt;
&lt;li&gt;Allows you to achieve more complex integration requirements, such as those involving separate application systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am a major proponent of implementing custom pricing solutions &lt;a class="link" href="https://crmchap.co.uk/implementing-custom-calculations-for-sales-entities-dynamics-crmdynamics-365-for-enterprise/" target="_blank" rel="noopener"
&gt;and have discussed how to get started with custom pricing plug-ins previously on the blog&lt;/a&gt;. However, I do always heavily caution their use, and it is a &amp;ldquo;last resort&amp;rdquo; if you cannot work with D365CE&amp;rsquo;s default pricing functionality. The old maxim stands true: just because you &lt;em&gt;CAN&lt;/em&gt; do something, doesn&amp;rsquo;t necessarily mean you should 🙂&lt;/p&gt;
&lt;h3 id="psa--custom-pricing-plugin--"&gt;PSA + Custom Pricing Plugin = ?
&lt;/h3&gt;&lt;p&gt;Going back now to the example I alluded to at the start of this post&amp;hellip;I was contacted by a customer who was having issues with a custom pricing solution I had implemented for them a while back. Since then, the organisation had implemented PSA and had started to get very nasty error messages appearing when working with Project-based Line records, as indicated below:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/Dynamics365-CustomerEngagement-PSACustomPricingError.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;As the error message demonstrates, the culprit was the custom pricing plug-in, which was preventing the creation of any associated Line Detail record. Evaluating the tracing logs for this plug-in showed that everything worked fine and dandy, up until the point when any actual calculation values needed applying to the &lt;strong&gt;Quote Line&lt;/strong&gt; record. This step would fail with the following error message:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;CalculatePrice: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: The total line amount and estimated tax of all Sales Document Line Details must equal the line amount and estimated tax of the Sales Document Line. (Fault Detail is equal to Exception details:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Further investigation of the error logs pointed towards the PSA managed solution plug-in &lt;strong&gt;Microsoft.Dynamics.ProjectService.Plugins.PreValidatequotedetailUpdate&lt;/strong&gt; being the culprit for the raising of the OrganisationServiceFault error in the first place.&lt;/p&gt;
&lt;h3 id="understanding-how-psa-works"&gt;Understanding How PSA Works
&lt;/h3&gt;&lt;p&gt;At this stage, I had to get to grips with how this nice-looking PSA application worked under the hood, having previously only a surface-level awareness of its behaviour. PSA is designed to work very closely alongside the existing Sales functionality within D365CE. This approach provides not only the ability to manage/plan projects at a resource-level but ensures the appropriate factoring of any &lt;em&gt;delivery&lt;/em&gt; costs into generated sales records. For &amp;ldquo;time &amp;amp; material&amp;rdquo; projects, this is crucial, as providing sufficient accounting for a resources time and financial return is imperative. For the most part, PSA relies on the tried and tested Sales module functionality to deliver most of these requirements, but also provides the following, additional &lt;strong&gt;Line Detail&lt;/strong&gt; entities, linked to the corresponding sales/product line entity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Opportunity Line Detail&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quote Line Detail&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sales Contract&lt;/strong&gt; (i.e. &lt;strong&gt;Order&lt;/strong&gt;) &lt;strong&gt;Line Detail&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invoice Line Detail&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The purpose of these entities (except for the &lt;strong&gt;Opportunity Line Detail&lt;/strong&gt;, which records a &amp;ldquo;finger in the air&amp;rdquo; budget value instead) is to allow multiple resources to be associated with a &lt;strong&gt;Quote Line&lt;/strong&gt; record. For example, let&amp;rsquo;s assume you are charging a customer for &lt;strong&gt;Project&lt;/strong&gt; &lt;strong&gt;Scoping&lt;/strong&gt;. As part of this, the following resources need to be assigned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;4 hours for a Solution Architect&lt;/li&gt;
&lt;li&gt;6 hours for a Pre-Sales Consultant&lt;/li&gt;
&lt;li&gt;6 hours for a Project Manager&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this scenario, all three of these roles would be created as &lt;strong&gt;Line Detail&lt;/strong&gt; records against a &lt;strong&gt;Project Scoping&lt;/strong&gt; Line record. Although this process does involve a few additional steps compared to the default Sales module, this functionality is also useful as it allows you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Factor in whether a resource is chargeable as part of an activity or not.&lt;/li&gt;
&lt;li&gt;Allows you to categorise the type of cost that the &lt;strong&gt;Line Detail&lt;/strong&gt; is.&lt;/li&gt;
&lt;li&gt;Indicate the anticipated length of time that the resource will require involvement as part of an engagement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So with a combination of understanding how the application works and a thorough diagnosis of the error message in question, the answer to the problem seems relatively apparent. Any PSA custom pricing plug-in &lt;em&gt;must&lt;/em&gt; factor the total, &lt;em&gt;chargeable&lt;/em&gt; value of all related &lt;strong&gt;Line Detail&amp;rsquo;s&lt;/strong&gt;, ensuring the &lt;strong&gt;Amount&lt;/strong&gt; and &lt;strong&gt;Estimated Tax&lt;/strong&gt; fields update accordingly.&lt;/p&gt;
&lt;h3 id="the-techie-bit-evaluating-a-suggested-approach"&gt;The Techie Bit: Evaluating a Suggested Approach
&lt;/h3&gt;&lt;p&gt;Now that we know the problem, we can start to think about a potential resolution. The C# class below shows a potential approach for calculating PSA Product Line details records. Pass any Line record through, and the pesky error message shown above should no longer appear, and all expected calculation will be applied:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;CalculatePSAProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Determine which Line Detail records to retrieve from - throw an error if an unexpected record has been passed through.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Also need to determine the lookup field name as part of this operation - either msdyn_quotelineid or msdyn_salescontractlineid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;detailName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;detailRelatedEntityName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogicalName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;quotedetail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;detailName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;msdyn_quotelinetransaction&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;detailRelatedEntityName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;msdyn_quotelineid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Record being calculated = Quote Line Detail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;salesorderdetail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;detailName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;msdyn_orderlinetransaction&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;detailRelatedEntityName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;msdyn_salescontractlineid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Record being calculated = Order Line Detail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;An error occurred when applying custom pricing. An incorrect entity name was passed to the CalculatePSAProduct method&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Retrieve all related, chargeable Line Detail records that have a Transaction Type value of &amp;#34;Project Contract&amp;#34; with the Amount, Tax and amount_after_tax field values&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Retrieving all related, chargeable &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;detailName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; records...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;QueryByAttribute&lt;/span&gt; &lt;span class="n"&gt;qba&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QueryByAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detailName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qba&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;msdyn_amount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;msdyn_tax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;msdyn_amount_after_tax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qba&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;msdyn_billingtype&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qba&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;192350001&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qba&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;msdyn_transactiontypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qba&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;192350004&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qba&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detailRelatedEntityName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qba&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;lt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetrieveMultiple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qba&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Got &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;detailName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; records!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Total up each individual Line Detail record to determine Amount, Estimated Tax and Amount After Tax&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;ppu&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;ea&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//If no value in the returned fields, default to 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ppu&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;msdyn_amount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])?.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;msdyn_tax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])?.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ea&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;msdyn_amount_after_tax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])?.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//From here, you can begin to apply any custom calculations needed to satisfy your individual requirements.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//In this example, we simply pass the totals from above onto the relevant Line fields and then update the Line record.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;priceperunit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ppu&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Quoted/Contracted Amount = &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ppu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;tax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Estimated Tax = &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;extendedamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ea&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Quoted/Contracted Amount After Tax = &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogicalName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; updated successfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some further explanation on this class may be required, given some additional quirks that PSA throws into the mix:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The code is designed to be &lt;strong&gt;Line Detail&lt;/strong&gt; record agnostic, which is why a &lt;strong&gt;switch&lt;/strong&gt; statement is needed to determine certain field values needed within the &lt;strong&gt;QueryByAttribute&lt;/strong&gt; query. The Opportunity Line and Invoice Detail entities do not behave the same way as the Quote &amp;amp; Order Line entities, so these are specifically excluded.&lt;/li&gt;
&lt;li&gt;It would appear that the PSA application creates several, hidden &lt;strong&gt;Line Detail&lt;/strong&gt; records in the application for &lt;em&gt;every&lt;/em&gt; &lt;strong&gt;Line Detail&lt;/strong&gt; record that a user creates. These blank records do not contain any of the expected pricing values. Therefore, to avoid potential issues, the &lt;strong&gt;QueryByAttribute&lt;/strong&gt; filters specifically ensure these do not return and, also, ensures that only records marked as chargeable are brought back.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Beyond that, most of the code should be self-explanatory for those familiar working with C# - however, let me know in the comments below if you have any queries.&lt;/p&gt;
&lt;h3 id="all-change-ahead"&gt;All Change Ahead
&lt;/h3&gt;&lt;p&gt;At the time of writing this post, we have just recently seen a major upgrade of PSA take place, from version 2 to version 3. This particular release saw a lot of change within PSA and, indeed, &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customer-engagement/project-service/upgrade-psa-home-page" target="_blank" rel="noopener"
&gt;users of version 2 of the application need to specifically request Microsoft to allow them to upgrade to the newer version&lt;/a&gt;. This requirement is likely due to the risk of stuff breaking between versions. Now, I am hearing on the grapevine that &lt;em&gt;another&lt;/em&gt; significant upgrade will be coming as part of the fall 2019 release. &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365-release-plan/2019wave2/dynamics365-project-service-automation/joint-dynamics-office-offering-project-based-organizations" target="_blank" rel="noopener"
&gt;A reading of the release notes would seem to suggest this to be a major overhaul&lt;/a&gt;, likely involving the removal entirely of the current Microsoft Project embedded functionality. We will no doubt find out more about this soon, but I would caveat this entire post by saying it&amp;rsquo;s outlined fix could become redundant within months. All we can do for now is keep a keen eye on the release notes and see how things ultimately pan out.&lt;/p&gt;
&lt;h3 id="the-community-is-awesome"&gt;The Community is Awesome
&lt;/h3&gt;&lt;p&gt;In times of crisis new and exciting learning opportunities, you can always rest assured that the fantastic D365CE community will be on hand to assist. In this case, I must give thanks to the PSA wizard &lt;a class="link" href="https://twitter.com/anttipajunen" target="_blank" rel="noopener"
&gt;Antti Pajunen&lt;/a&gt; for being a reliable and authoritative steer on PSA and in helping to answer my questions relating to it. If you are working with PSA and are not already following &lt;a class="link" href="https://daytodaydynamics365.com/" target="_blank" rel="noopener"
&gt;his blog&lt;/a&gt;, then get over there today - you won&amp;rsquo;t be disappointed!&lt;/p&gt;
&lt;h3 id="i-could-talk-all-day-about-this-stuff"&gt;I Could Talk All Day About This Stuff&amp;hellip;
&lt;/h3&gt;&lt;p&gt;No, seriously, I could. Feel free to leave a comment below or &lt;a class="link" href="https://crmchap.co.uk/contact-me/" target="_blank" rel="noopener"
&gt;contact me&lt;/a&gt; if you would like to find out how to implement a custom pricing solution within your D365CE system.&lt;/p&gt;</description></item><item><title>Extract New Record GUID from Dynamics 365 Customer Engagement Create Web API Request (C#)</title><link>/extract-new-record-guid-from-dynamics-365-customer-engagement-create-web-api-request-c/</link><pubDate>Sun, 16 Jun 2019 00:00:00 +0000</pubDate><guid>/extract-new-record-guid-from-dynamics-365-customer-engagement-create-web-api-request-c/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Extract New Record GUID from Dynamics 365 Customer Engagement Create Web API Request (C#)" /&gt;&lt;p&gt;Typically, when working with a database/application to programmatically create new records, it is desirable for us to return some information relating to any newly created records; this would typically take the form of a Globally Unique Identifier (GUID), primary key value or something else that &lt;strong&gt;uniquely&lt;/strong&gt; identifies the record in question. Doing this may be useful for several reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By returning this type of data, we can implicitly confirm that the record has been created successfully, as such a value would not exist otherwise.&lt;/li&gt;
&lt;li&gt;There may be some additional operations that need to be carried out against the new record, post-creation. By returning its unique identifier, we can carry out such activities without any further impediment and do not need to rely on a separate retrieval operation to obtain this property.&lt;/li&gt;
&lt;li&gt;The unique identifier may be required elsewhere within our application. For example, we may want to store the unique identifier within a separate system, to satisfy any current/future data integration requirements.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.microsoft.com/en-gb/dynamics365/customer-engagement/" target="_blank" rel="noopener"
&gt;Dynamics 365 Customer Engagement (D365CE)&lt;/a&gt; is no different in this regard, and you traditionally may have had to devote some effort to accommodate this scenario. Fortunately, if you are working with tools such as &lt;a class="link" href="https://github.com/jlattimer/CRMRESTBuilder" target="_blank" rel="noopener"
&gt;Jason Lattimer&amp;rsquo;s CRM REST Builder&lt;/a&gt;, a lot of the hassle involved here becomes virtually non-existent, as you can very quickly generate code snippets that not only perform your entire create record operation but also return the records GUID after the transaction has completed successfully. An example of the type of code that the tool can generate is seen below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;entity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;CRM Chap&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;POST&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getClientUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/api/data/v9.1/accounts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OData-MaxVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;4.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OData-Version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;4.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;application/json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;application/json; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onreadystatechange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onreadystatechange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getResponseHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OData-EntityId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;regExp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/\(([^)]+)\)/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;regExp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;newEntityId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Utility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alertDialog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example, lines 14-17 of the snippet handle the process of returning the newly created records GUID, with some specific steps required to ensure this renders nicely. This is because D365CE returns the newly created record as part of a complete URL by default (e.g. the above example, unmodified, would return something like &lt;strong&gt;&lt;a class="link" href="https://mycrminstance.crm11.dynamics.com/api/data/v9.1/accounts%28711cd182-0f90-e911-a97b-002248014773%29" target="_blank" rel="noopener"
&gt;https://mycrminstance.crm11.dynamics.com/api/data/v9.1/accounts(711cd182-0f90-e911-a97b-002248014773)&lt;/a&gt;&lt;/strong&gt;). Therefore, a &lt;a class="link" href="https://en.wikipedia.org/wiki/Regular_expression" target="_blank" rel="noopener"
&gt;Regular Expression (RegEx)&lt;/a&gt; is used to strip out all of the URL components and, instead, supply us with the record GUID as part of the &lt;strong&gt;newEntityId&lt;/strong&gt; variable. VERY handy and another reason why we should all be thanking Jason for building such an amazing tool.&lt;/p&gt;
&lt;p&gt;While this is all well and good if you are working with the Web API using JScript, there may be other programming languages that you wish to utilise alongside D365CE&amp;rsquo;s Web API. A natural example of this is C# and, fortunately, &lt;a class="link" href="https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/webapi/samples/basic-operations-csharp" target="_blank" rel="noopener"
&gt;there are also code samples freely available to help simplify development.&lt;/a&gt; However, these samples do not implement the same kind of transformation that Jason&amp;rsquo;s tool very kindly does by default. So how can we replicate this functionality using C#? &lt;a class="link" href="https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expressions" target="_blank" rel="noopener"
&gt;Thanks mostly to the excellent Regular Expression engine built directly into .NET&lt;/a&gt;, the task of porting across similar functionality to C# is greatly simplified. By adding a &lt;strong&gt;using System.Text.RegularExpressions;&lt;/strong&gt; statement to the top of our C# class file, we can then use the following three lines of code to extract out the CRM record GUID as a string value (where &lt;strong&gt;entityUri&lt;/strong&gt; is the same URL example shown above):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Regex&lt;/span&gt; &lt;span class="nx"&gt;rx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;\(([^)]+)\)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Match&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entityUri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nx"&gt;entityID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From there, we could then look to cast the &lt;strong&gt;entityID&lt;/strong&gt; string into a &lt;strong&gt;Guid&lt;/strong&gt; data type to, for example, associate the record to another within the application, update our external application system, print it out to a log file/console window&amp;hellip;the possibilities are endless! What matters the most is that we can get something unique that identifies our newly created D365CE record and all it took was a few lines of code in C# - which is always nice. 🙂&lt;/p&gt;</description></item><item><title>Override the Modified On Field Value When Reassigning Resolved Cases (Dynamics 365 for Customer Service)</title><link>/override-the-modified-on-field-value-when-reassigning-resolved-cases-dynamics-365-for-customer-service/</link><pubDate>Sun, 22 Apr 2018 00:00:00 +0000</pubDate><guid>/override-the-modified-on-field-value-when-reassigning-resolved-cases-dynamics-365-for-customer-service/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Override the Modified On Field Value When Reassigning Resolved Cases (Dynamics 365 for Customer Service)" /&gt;&lt;p&gt;Typically, when working with Dynamics 365 for Customer Service entities, you expect a certain type of behaviour. A good example of this in practice is entity record activation and the differences between &lt;strong&gt;Active&lt;/strong&gt; and &lt;strong&gt;Inactive&lt;/strong&gt; record types. In simple terms, you are generally restricted in the actions that can be performed against an &lt;strong&gt;Inactive&lt;/strong&gt; record, most commonly being the modification of a field value. You can, however, perform actions such as deleting and reassigning records to other users in the application. The latter of these can be particularly useful if, for example, an individual leaves a business and you need to ensure that another employee requires access to old, inactive records.&lt;/p&gt;
&lt;p&gt;When it comes to reporting on time intervals for when a record was last changed, I often - rightly or wrongly - see the &lt;strong&gt;Modified On&lt;/strong&gt; field used for this purpose. This, essentially, stores the date and time of when the record was&amp;hellip;well&amp;hellip;last modified in the system! &lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customer-engagement/customize/business-process-flows-overview#preview-feature-business-process-flow-entity-customization-support" target="_blank" rel="noopener"
&gt;Since only more recent changes to the application have facilitated an alternative approach in reporting a record&amp;rsquo;s age and its current stage within a process&lt;/a&gt;, it is perhaps understandable why this field is often chosen when attempting to report, for example, the date on which a record was moved to &lt;strong&gt;Inactive&lt;/strong&gt; status. Where you may encounter issues with this is if you are working in a similar situation highlighted above - namely, an individual leaving a business - and you need to reassign all of the inactive records owned by them. Doing either of these steps will immediately update the &lt;strong&gt;Modified On&lt;/strong&gt; value to the current date and time, skewering any dependent reporting.&lt;/p&gt;
&lt;p&gt;Fortunately, there is a way of getting around this, if you don&amp;rsquo;t have any qualms about opening up Visual Studio and putting together a plug-in in C#. Via this route, you can prevent the &lt;strong&gt;Modified On&lt;/strong&gt; value of a record from being updated by capturing the original value and forcing the platform to commit this value to the database during the Pre-Operation stage of the transaction, as opposed to the date and time of when the record is reassigned. In fact, using this method, you can set the &lt;strong&gt;Modified On&lt;/strong&gt; value to be whatever you want. Here&amp;rsquo;s the code that illustrates how to achieve both scenarios:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Sample.OverrideCaseModifiedDate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PreOpCaseAssignOverrideModifiedDate&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Obtain the execution context from the service provider.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Extract the tracing service for use in debugging sandboxed plug-ins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tracing implemented successfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;incident&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;preIncident&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PreEntityImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;preincident&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//At this stage, you can either get the previous Modified On date value via the Pre Entity Image and set the value accordingly...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;modifiedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;preIncident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;modifiedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Or alternatively, set it to whatever you want - in this example, we get the Pre Entity Image createdon value, add on an hour and then set the value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;createdOn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;preIncident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;createdon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;newModifiedOn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createdOn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;modifiedon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newModifiedOn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When deploying out your plug-in code to the application (&lt;a class="link" href="https://crmchap.co.uk/dynamics-365-customer-engagement-deep-dive-creating-a-basic-plug-in/" target="_blank" rel="noopener"
&gt;something that I hope regular readers of the blog will be familiar with&lt;/a&gt;), make sure that the settings you configure for your Step and the all-important Entity image resemble the images below:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolStepForCaseOverrideModifiedDate.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolUpdateImageForCaseOverrideModifiedDate.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Now, the more eagle-eyed readers may notice that the step is configured on the &lt;strong&gt;Update&lt;/strong&gt; as opposed to the &lt;strong&gt;Assign&lt;/strong&gt; message, which is what you (and, indeed, I when I first started out with this) may expect. Unfortunately, because the Input Parameters of the &lt;strong&gt;Assign&lt;/strong&gt; message only returns two Entity Reference objects - the &lt;strong&gt;incident&lt;/strong&gt; (Case) and &lt;strong&gt;systemuser&lt;/strong&gt; (User) entities, respectively - as opposed to an Entity object for the &lt;strong&gt;incident&lt;/strong&gt; entity, we have no means of interfering with the underlying database transaction to override the required field values. The &lt;strong&gt;Update&lt;/strong&gt; message does not suffer from this issue and, by scoping the plug-in&amp;rsquo;s execution to the &lt;strong&gt;ownerid&lt;/strong&gt; field only, we can ensure that it will only ever trigger when a record is reassigned.&lt;/p&gt;
&lt;p&gt;With the above plug-in configured, you have the flexibility of re-assigning your &lt;strong&gt;Case&lt;/strong&gt; records without updating the &lt;strong&gt;Modified On&lt;/strong&gt; field value in the process or expanding this further to suit whatever business requirement is needed. In theory, as well, the approach used in this example could also be applied to other what we may term &amp;ldquo;system defined fields&amp;rdquo;, such as the &lt;strong&gt;Created On&lt;/strong&gt; field. Hopefully, this post may prove some assistance if you find yourself having to tinker around with inactive &lt;strong&gt;Case&lt;/strong&gt; records in the future.&lt;/p&gt;</description></item><item><title>Dynamics 365 Customer Engagement Deep Dive: Creating a Basic Custom Workflow Assembly</title><link>/dynamics-365-customer-engagement-deep-dive-creating-a-basic-custom-workflow-assembly/</link><pubDate>Sun, 18 Mar 2018 00:00:00 +0000</pubDate><guid>/dynamics-365-customer-engagement-deep-dive-creating-a-basic-custom-workflow-assembly/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Dynamics 365 Customer Engagement Deep Dive: Creating a Basic Custom Workflow Assembly" /&gt;&lt;p&gt;This is an accompanying blog post to my YouTube video &lt;strong&gt;Dynamics 365 Customer Engagement Deep Dive: Creating a Basic Custom Workflow Assembly&lt;/strong&gt;. The video is part of my tutorial series on how to accomplish developer focused tasks within Dynamics 365 Customer Engagement. You can watch the video in full below:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/0r02M71U140"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Below you will find links to access some of the resources discussed as part of the video and to further reading topics:&lt;/p&gt;
&lt;h2 id="full-code-sample"&gt;Full Code Sample
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Activities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.Workflow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.Query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;D365.SampleCWA&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CWA_CopyQuote&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeActivity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kd"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CodeActivityContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IWorkflowContext&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetExtension&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IWorkflowContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt; &lt;span class="n"&gt;serviceFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetExtension&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateOrganizationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetExtension&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tracing implemented successfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrimaryEntityId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;freightamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;discountamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;discountpercentage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;pricelevelid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;customerid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Copy of &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;newQuoteID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;quoteProducts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RetrieveRelatedQuoteProducts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RetrieveRelatedNotes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quoteProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalRecordCount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; Quote Product records returned.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;quoteProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quotedetailid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newQuoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;note&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;annotationid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;objectid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newQuoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Input(&amp;#34;Quote Record to Copy&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [ReferenceTarget(&amp;#34;quote&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;InArgument&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;QuoteReference&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;RetrieveRelatedQuoteProducts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quotedetail&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllColumns&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Criteria&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddCondition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ConditionOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReturnTotalRecordCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetrieveMultiple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;RetrieveRelatedNotes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;objectID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;annotation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllColumns&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Criteria&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddCondition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;objectid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ConditionOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;objectID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReturnTotalRecordCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetrieveMultiple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="downloadresource-links"&gt;Download/Resource Links
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&amp;amp;rel=15" target="_blank" rel="noopener"
&gt;Visual Studio 2017 Community Edition&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://portal.office.com/signup/logout?OfferId=bd569279-37f5-4f5c-99d0-425873bb9a4b&amp;amp;dl=DYN365_ENTERPRISE_PLAN1&amp;amp;Culture=en-gb&amp;amp;Country=gb&amp;amp;ali=1" target="_blank" rel="noopener"
&gt;Setup a free 30 day trial of Dynamics 365 Customer Engagement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.microsoft.com/en-gb/dotnet/csharp/" target="_blank" rel="noopener"
&gt;C# Guide (Microsoft Docs)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Source Code Management Solutions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://go.microsoft.com/fwlink/?LinkId=307137&amp;amp;clcid=0x409&amp;amp;wt.mc_id=o~msft~vscom~product-vsts-hero~464&amp;amp;campaign=o~msft~vscom~product-vsts-hero~464" target="_blank" rel="noopener"
&gt;Visual Studio Team Services&lt;/a&gt; - Free for up to 5 users and my recommended choice when working with Dynamics 365 Customer Engagement&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bitbucket.org/account/signup/" target="_blank" rel="noopener"
&gt;BitBucket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/" target="_blank" rel="noopener"
&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="further-reading"&gt;Further Reading
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/workflow/create-custom-workflow-activity" target="_blank" rel="noopener"
&gt;Microsoft Docs - Create a custom workflow activity&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/LIBRary/gg328153.aspx" target="_blank" rel="noopener"
&gt;MSDN - Register and use a custom workflow activity assembly&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg328011.aspx" target="_blank" rel="noopener"
&gt;MSDN - Update a custom workflow activity using assembly versioning&lt;/a&gt; (This topic wasn&amp;rsquo;t covered as part of the video, but I would recommend reading this article if you are developing an ISV solution involving custom workflow assemblies)&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg334455.aspx" target="_blank" rel="noopener"
&gt;MSDN - Sample: Create a custom workflow activity&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also check out some of my previous blog posts relating to Workflows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/implementing-tracing-in-your-crm-plug-ins/" target="_blank" rel="noopener"
&gt;Implementing Tracing in your CRM Plug-ins&lt;/a&gt; - We saw as part of the video how to utilise tracing, but this post goes into more detail about the subject, as well as providing instructions on how to enable the feature within the application (in case you are wondering why nothing is being written to the trace log 🙂 ). All code examples are for Plug-ins, but they can easily be repurposed to work with a custom workflow assembly instead.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/obtaining-the-user-who-executed-a-workflow-in-dynamics-365-for-customer-engagement-c-workflow-activity/" target="_blank" rel="noopener"
&gt;Obtaining the User who executed a Workflow in Dynamics 365 for Customer Engagement (C# Workflow Activity)&lt;/a&gt; - You may have a requirement to trigger certain actions within the application, based on the user who executed a Workflow. This post walks through how to achieve this utilising a custom workflow assembly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;If you have found the above video useful and are itching to learn more about Dynamics 365 Customer Engagement development, then be sure to take a look at my previous videos/blog posts using the links below:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/dynamics-365-customer-engagement-deep-dive-creating-a-basic-plug-in/" target="_blank" rel="noopener"
&gt;Dynamics 365 Customer Engagement Deep Dive: Creating a Basic Plug-in&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/dynamics-365-customer-engagement-deep-dive-creating-a-basic-jscript-form-function/" target="_blank" rel="noopener"
&gt;Dynamics 365 Customer Engagement Deep Dive: Creating a Basic Jscript Form Function&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Have a question or an issue when working through the code samples? Be sure to leave a comment below or &lt;a class="link" href="https://crmchap.co.uk/contact-me/" target="_blank" rel="noopener"
&gt;contact me&lt;/a&gt; directly, and I will do my best to help. Thanks for reading and watching!&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Top 10 Most Viewed CRM Chap Blog Posts</title><link>/top-10-most-viewed-crm-chap-blog-posts/</link><pubDate>Sun, 18 Feb 2018 00:00:00 +0000</pubDate><guid>/top-10-most-viewed-crm-chap-blog-posts/</guid><description>&lt;img src="/images/JJG-Caricature-250px.jpg" alt="Featured image of post Top 10 Most Viewed CRM Chap Blog Posts" /&gt;&lt;p&gt;Slight change of pace with this week&amp;rsquo;s blog post, which will be a fairly condensed and self-indulgent affair - due to personal circumstances, I have been waylaid somewhat when it comes to producing content for the blog and I have also been unable to make any further progress with &lt;a class="link" href="https://www.youtube.com/playlist?list=PLAuip8FYPopSzhX_tA7f-JkLqNuPc6ibx" target="_blank" rel="noopener"
&gt;my new YouTube video series&lt;/a&gt;. Hoping that normal service will resume shortly, meaning additional videos and more content-rich blog posts, so stay tuned.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been running the CRM Chap blog for just over 2 years now. Over this time, I have been humbled and proud to have received numerous visitors to the site, some of whom have been kind enough to provide feedback or to share some of their Dynamics CRM/365 predicaments with me. Having reached such a landmark now seems to be good a time as any to take a look back on the posts that have received the most attention and to, potentially, give those who missed them the opportunity to read them. In descending order, here is the list of the most viewed posts to date on the crmchap.co.uk website:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/utilising-sql-server-stored-procedures-with-powerbi/" target="_blank" rel="noopener"
&gt;Utilising SQL Server Stored Procedures with Power BI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/installing-dynamics-crm-2016-sp1-on-premise/" target="_blank" rel="noopener"
&gt;Installing Dynamics CRM 2016 SP1 On-Premise&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/powerbi-deep-dive-using-the-web-api-to-query-dynamics-crm365-for-enterprise/" target="_blank" rel="noopener"
&gt;Power BI Deep Dive: Using the Web API to Query Dynamics CRM/365 for Enterprise&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/utilising-prepost-entity-images-in-a-dynamics-crm-plugin/" target="_blank" rel="noopener"
&gt;Utilising Pre/Post Entity Images in a Dynamics CRM Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/modifying-systemcustom-views-fetchxml-query-in-dynamics-crm/" target="_blank" rel="noopener"
&gt;Modifying System/Custom Views FetchXML Query in Dynamics CRM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/grant-send-on-behalf-permissions-for-shared-mailbox-exchange-online/" target="_blank" rel="noopener"
&gt;Grant Send on Behalf Permissions for Shared Mailbox (Exchange Online)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/getting-started-with-portal-theming-adxstudiocrm-portals/" target="_blank" rel="noopener"
&gt;Getting Started with Portal Theming (ADXStudio/CRM Portals)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/microsoft-dynamics-365-data-export-service-review/" target="_blank" rel="noopener"
&gt;Microsoft Dynamics 365 Data Export Service Review&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/whats-new-in-the-dynamics-365-developer-toolkit/" target="_blank" rel="noopener"
&gt;What&amp;rsquo;s New in the Dynamics 365 Developer Toolkit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/implementing-tracing-in-your-crm-plug-ins/" target="_blank" rel="noopener"
&gt;Implementing Tracing in your CRM Plug-ins&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I suppose it is a testament to &lt;a class="link" href="https://crmchap.co.uk/about-this-blog/" target="_blank" rel="noopener"
&gt;the blog&amp;rsquo;s stated purpose&lt;/a&gt; that posts covering areas not exclusive to Dynamics CRM/365 rank so highly on the list and, indeed, represents how this application is so deeply intertwined with other technology areas within the Microsoft &amp;ldquo;stack&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To all new and long-standing followers of the blog, thank you for your continued support and appreciation for the content&lt;/strong&gt; 🙂&lt;/p&gt;</description></item><item><title>System.AggregateException: One or more errors occured (Dynamics CRM/Dynamics 365 Customer Engagement Plug-in)</title><link>/system-aggregateexception-one-or-more-errors-occured-dynamics-crm-dynamics-365-customer-engagement-plug-in/</link><pubDate>Sun, 11 Feb 2018 00:00:00 +0000</pubDate><guid>/system-aggregateexception-one-or-more-errors-occured-dynamics-crm-dynamics-365-customer-engagement-plug-in/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post System.AggregateException: One or more errors occured (Dynamics CRM/Dynamics 365 Customer Engagement Plug-in)" /&gt;&lt;p&gt;As part of developing Dynamics CRM/Dynamics 365 Customer Engagement (CRM/D365CE) plug-ins day in, day out, you can often forget about the &lt;strong&gt;Execution Mode&lt;/strong&gt; setting. &lt;a class="link" href="https://crmchap.co.uk/dynamics-365-customer-engagement-deep-dive-creating-a-basic-plug-in/" target="_blank" rel="noopener"
&gt;This can be evidenced by the fact that I make no mention of it in my recent tutorial video on plug-in development.&lt;/a&gt; In a nutshell, this setting enables you to customise whether your plug-in executes in &lt;strong&gt;Synchronous&lt;/strong&gt; or &lt;strong&gt;Asynchronous&lt;/strong&gt; mode. Now, you may be asking - just what the hell does that mean?!? The best way of understanding is by rephrasing the terminology; it basically tells the system &lt;em&gt;when&lt;/em&gt; you want your code to be executed. &lt;strong&gt;Synchronous&lt;/strong&gt; plug-ins execute all of your business logic whilst the record is being saved by the user, with this action not being considered complete and committed to the backend database until the plug-in completes. By comparison, &lt;strong&gt;Asynchronous&lt;/strong&gt; plug-ins are queued for execution after the record has been saved. A &lt;strong&gt;System Job&lt;/strong&gt; record is created and queued alongside other jobs in the system via the Asynchronous Service. Another way of remembering the difference between each one is to think back to the options available to you as part of a Workflow. They can either be executed in real time (synchronously) or in the background (asynchronously). Plug-ins are no different and give you the flexibility to ensure your business logic is applied immediately or, if especially complex, queued so that the system has sufficient time to process in the background.&lt;/p&gt;
&lt;p&gt;I came across a strange issue with an arguably even stranger &lt;strong&gt;Synchronous&lt;/strong&gt; plug-in the other day, which started failing after taking an inordinately long time saving the record:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Unexpected exception from plug-in (Execute): MyPlugin.MyPluginClass: System.AggregateException: One or more errors occurred.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &amp;ldquo;strange&amp;rdquo; plug-in was designed so that, on the &lt;strong&gt;Create&lt;/strong&gt; action of an Entity record, it goes out and creates various related records within the application, based on a set of conditions. We originally had issues with the plug-in a few months back erroring, due to the execution time exceeding the 2 minute limit for sandbox plug-ins. A rather ingenious and much more accomplished developer colleague got around the issue by implementing a degree of asynchronous processing within the plug-in, achieved like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;lock&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt; &lt;span class="n"&gt;stopwatch&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newRecord&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Record with ID &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; created successfully after: {0}ms.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElapsedMilliseconds&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I still don&amp;rsquo;t fully understand just exactly what this is doing, but I put this down to my novice level C# knowledge 🙂 The important thing was that the code worked&amp;hellip;until some additional processing was added to the plug-in, leading to the error message above.&lt;/p&gt;
&lt;p&gt;At this juncture, our only choice was to look at forcing the plug-in to execute in Asynchronous mode by modifying the appropriate setting on the plug-in step within the &lt;strong&gt;Plugin Registration Tool&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolAsynchronousPlugin.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;After making this change and attempting to create the record again in the application, everything worked as expected. However, this did create a new problem for us to overcome - end users of the application were previously used to seeing the related records created by the plug-in within sub-grids on the Primary Entity form, which would then be accessed and worked through accordingly. As the very act of creating these records now took place within the background and took some time to complete, we needed to display an informative message to the user to advise them to refresh the form after a few minutes. You do have the ability within plug-ins to display a custom message back to the user, but this is only in situations where you are throwing an error message and it didn&amp;rsquo;t seem to be a particularly nice solution for this scenario.&lt;/p&gt;
&lt;p&gt;In the end, the best way of achieving this requirement was to implement a JScript function on the form. This would trigger whenever the form is saved and displays a message box that the user has to click OK on before the save action is carried out:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;displaySaveMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;eventArgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getEventArgs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;saveMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eventArgs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSaveMode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saveMode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;saveMode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;saveMode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;saveMode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;59&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Records will be populated in the background and you will need to refresh the form after a few minutes to see them on the Sub-Grid. Press OK to save the record.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Utility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alertDialog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By feeding through the execution context parameter, you are able to determine the type of save action that the alert will trigger on; in this case, &lt;strong&gt;Save&lt;/strong&gt;, &lt;strong&gt;Save &amp;amp; Close&lt;/strong&gt;, &lt;strong&gt;Save &amp;amp; New&lt;/strong&gt; and &lt;strong&gt;Autosave&lt;/strong&gt;. Just make sure you configure your script with the correct properties on the form, which are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using the &lt;strong&gt;OnSave&lt;/strong&gt; event handler&lt;/li&gt;
&lt;li&gt;With the &lt;strong&gt;Pass execution context as first parameter&lt;/strong&gt; setting enabled&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From the end-users perspective, they will see something similar to the below when the record is saved:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-AlertDialogExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a pity that we don&amp;rsquo;t have similar kind of functionality exposed via Business Rules that enable us to display &lt;strong&gt;OnSave&lt;/strong&gt; alerts that are more in keeping with the applications look and feel. Nevertheless, the versatility of utilising JScript functions should be evident here and can often achieve these types of bespoke actions with a few lines of code.&lt;/p&gt;
&lt;p&gt;When it comes to plug-in development, understanding the impact and processing time that your code has within the application is important for two reasons - first, in ensuring that end users are not frustrated by long loading times and, secondly, in informing the choice of &lt;strong&gt;Execution Mode&lt;/strong&gt; when it comes to deploying out a plug-in. Whilst &lt;strong&gt;Asynchronous&lt;/strong&gt; plug-ins can help to mitigate any user woes and present a natural choice when working with bulk operations within the application, make sure you fully understand the impact that these have on the Asynchronous Service and avoid a scenario where the &lt;strong&gt;System Job&lt;/strong&gt; entity is queued with more jobs then it can handle.&lt;/p&gt;</description></item><item><title>Dynamics 365 Customer Engagement Deep Dive: Creating a Basic Plug-in</title><link>/dynamics-365-customer-engagement-deep-dive-creating-a-basic-plug-in/</link><pubDate>Sun, 28 Jan 2018 00:00:00 +0000</pubDate><guid>/dynamics-365-customer-engagement-deep-dive-creating-a-basic-plug-in/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Dynamics 365 Customer Engagement Deep Dive: Creating a Basic Plug-in" /&gt;&lt;p&gt;This is an accompanying blog post to my YouTube video &lt;strong&gt;Dynamics 365 Customer Engagement Deep Dive: Creating a Basic Plug-in&lt;/strong&gt;, the second in a series aiming to provide tutorials on how to accomplish developer focused tasks within Dynamics 365 Customer Engagement. You can watch the video in full below:&lt;/p&gt;
&lt;div class="video-wrapper"&gt;
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/y0SgyieGYU8"
allowfullscreen
title="YouTube Video"
&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Below you will find links to access some of the resources discussed as part of the video and to further reading topics:&lt;/p&gt;
&lt;h2 id="full-code-sample"&gt;Full Code Sample
&lt;/h2&gt;&lt;p&gt;[snippet id=&amp;ldquo;390&amp;rdquo;]&lt;/p&gt;
&lt;h2 id="downloadresource-links"&gt;Download/Resource Links
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&amp;amp;rel=15" target="_blank" rel="noopener"
&gt;Visual Studio 2017 Community Edition&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://portal.office.com/signup/logout?OfferId=bd569279-37f5-4f5c-99d0-425873bb9a4b&amp;amp;dl=DYN365_ENTERPRISE_PLAN1&amp;amp;Culture=en-gb&amp;amp;Country=gb&amp;amp;ali=1" target="_blank" rel="noopener"
&gt;Setup a free 30 day trial of Dynamics 365 Customer Engagement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.microsoft.com/en-gb/dotnet/csharp/" target="_blank" rel="noopener"
&gt;C# Guide (Microsoft Docs)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Source Code Management Solutions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://go.microsoft.com/fwlink/?LinkId=307137&amp;amp;clcid=0x409&amp;amp;wt.mc_id=o~msft~vscom~product-vsts-hero~464&amp;amp;campaign=o~msft~vscom~product-vsts-hero~464" target="_blank" rel="noopener"
&gt;Visual Studio Team Services&lt;/a&gt; - Free for up to 5 users and my recommended choice when working with Dynamics 365 Customer Engagement&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://bitbucket.org/account/signup/" target="_blank" rel="noopener"
&gt;BitBucket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/" target="_blank" rel="noopener"
&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="further-reading"&gt;Further Reading
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg328490.aspx" target="_blank" rel="noopener"
&gt;MSDN - Plug-in development&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg328576.aspx" target="_blank" rel="noopener"
&gt;MSDN - Supported messages and entities for plug-ins&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg594416.aspx" target="_blank" rel="noopener"
&gt;MSDN - Sample: Create a basic plug-in&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/gg328574.aspx" target="_blank" rel="noopener"
&gt;MSDN - Debug a plug-in&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve written a number of blog posts around plug-ins previously, so here&amp;rsquo;s the obligatory plug section 🙂 :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/why-crm-developers-should-use-business-rules-more/" target="_blank" rel="noopener"
&gt;Why CRM Developers Should Use Business Rules More&lt;/a&gt; - The post talks more about Business Rules in the context of JScript, but echoes some of the points made in the video in respect to considering plug-ins as a &amp;ldquo;last resort&amp;rdquo; solution.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/what-is-unsecuresecure-configuration-on-a-dynamics-crm365-for-enterprise-plugin/" target="_blank" rel="noopener"
&gt;What is Unsecure/Secure Configuration on a Dynamics CRM/365 for Enterprise Plugin?&lt;/a&gt; - Unsecure/Secure Configurations are, arguably, one of those features that people tend to forget about with plug-ins; this post walks through how to implement them within your code.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/utilising-prepost-entity-images-in-a-dynamics-crm-plugin/" target="_blank" rel="noopener"
&gt;Utilising Pre/Post Entity Images in a Dynamics CRM Plugin&lt;/a&gt; - One of the best features at your disposal with plug-ins, Entity Images allow you to take snapshots of record data before and after your plug-in executes, and then access this data during runtime.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crmchap.co.uk/whats-the-best-way-of-learning-crm-development/" target="_blank" rel="noopener"
&gt;What&amp;rsquo;s the best way of learning CRM Development?&lt;/a&gt; - In this post, I talk about some of the things that you can do to help speed your journey towards Dynamics 365 Customer Engagement developer extraordinaire 🙂&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Interested in learning more about JScript Form function development in Dynamics 365 Customer Engagement? &lt;a class="link" href="https://crmchap.co.uk/dynamics-365-customer-engagement-deep-dive-creating-a-basic-jscript-form-function/" target="_blank" rel="noopener"
&gt;Then check out my previous post for my video and notes on the subject&lt;/a&gt;. I hope you find these videos useful and do let me know if you have any comments or suggestions for future video content.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Mapping Product Attributes to Quote/Order/Invoice Line Items (Dynamics 365 Customer Engagement)</title><link>/mapping-product-attributes-to-quote-order-invoice-line-items-dynamics-365-customer-engagement/</link><pubDate>Sun, 24 Dec 2017 00:00:00 +0000</pubDate><guid>/mapping-product-attributes-to-quote-order-invoice-line-items-dynamics-365-customer-engagement/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Mapping Product Attributes to Quote/Order/Invoice Line Items (Dynamics 365 Customer Engagement)" /&gt;&lt;p&gt;Working in-depth amidst the Sales entities (e.g. &lt;strong&gt;Product&lt;/strong&gt;, &lt;strong&gt;Price List&lt;/strong&gt;, &lt;strong&gt;Quote&lt;/strong&gt; etc.) within Dynamics CRM/Dynamics 365 Customer Engagement (CRM/D365CE) can produce some unexpected complications. What you may think is simple to achieve on the outset, based on how other entities work within the system, often leads you in a completely different direction. A good rule of thumb is that any overtly complex customisations to these entities will mean having to get down and dirty with C#, VB.Net or even JScript. For example, &lt;a class="link" href="/implementing-custom-calculations-for-sales-entities-dynamics-crmdynamics-365-for-enterprise/" &gt;we&amp;rsquo;ve seen previously on the blog how, with a bit of a developer expertise, it is possible to overhaul the entire pricing engine within the application to satisfy specific business requirements.&lt;/a&gt; There is no way in which this can be modified directly through the application interface, which can lead to CRM deployments that make imaginative and complicated utilisation of features such as Workflows, Business Rules and other native features. Whilst there is nothing wrong with this approach per-say, the end result is often implementations that look messy when viewed cold and which become increasingly difficult to maintain in the long term. As always, there is a balance to be found, and any approach which makes prudent use of both application features and bespoke code is arguably the most desirous end goal for achieving certain business requirements within CRM/D365CE.&lt;/p&gt;
&lt;p&gt;To prove my point around Sales entity &amp;ldquo;oddities&amp;rdquo;, a good illustration can be found when it comes to working with relationship field mappings and &lt;strong&gt;Product&lt;/strong&gt; records. The most desirable feature at the disposal of CRM customisers is the ability to configure automated field mapping between Entities that have a one-to-many (1:N) relationship between them. What this means, in simple terms, is that when you create a many (N) record from the parent entity (1), you can automatically copy the field values to a matching field on the related entity. This can help to save data entry time when qualifying a &lt;strong&gt;Lead&lt;/strong&gt; to an &lt;strong&gt;Opportunity&lt;/strong&gt;, as all the important field data you need to continue working on the record will be there ready on the newly created &lt;strong&gt;Opportunity&lt;/strong&gt; record. Field mappings can be configured from the 1:N relationship setting window, via the &lt;strong&gt;Mappings&lt;/strong&gt; button:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-RelationshipDefinition.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;There are a few caveats to bear in mind - you can only map across fields that have the same underlying data type and you cannot map multiple source fields to the same target (it should be obvious why this is 🙂) - but on the whole, this is a handy application feature that those who are more accustomed to CRM development should always bear in the mind when working with CRM/D365CE.&lt;/p&gt;
&lt;p&gt;Field mappings are, as indicated, a standard feature within CRM/D365CE - but when you inspect the field relationships between the &lt;strong&gt;Product&lt;/strong&gt; and &lt;strong&gt;Quote Product&lt;/strong&gt; entity, there is no option to configure mappings at all:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-ProductQuoteRelationshipDefinition.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Upon closer inspection, many of the relationships between the &lt;strong&gt;Product&lt;/strong&gt; entity and others involved as part of the sales order process are missing the ability to configure field mappings. So, for example, if you have a requirement to map across the value of the &lt;strong&gt;Description&lt;/strong&gt; entity to a newly created &lt;strong&gt;Quote Product&lt;/strong&gt; record, you would have to look at implementing a custom plugin to achieve your requirements. The main benefit of this route is that we have relatively unrestricted access to the record data we need as part of a plugin execution session and - in addition - we can piggyback onto the record creation process to add on our required field &amp;ldquo;in-flight&amp;rdquo; - i.e. whilst the record is being created. The code for achieving all of this is as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.Query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;D365.BlogDemoAssets.Plugins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PreQuoteProductCreate_GetProductAttributeValues&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Obtain the execution context from the service provider.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Get a reference to the Organization service.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateOrganizationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Extract the tracing service for use in debugging sandboxed plug-ins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tracing implemented successfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;qp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Only execute for non-write in Quote Product records&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;productid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RetrieveProductID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;desc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Product Description = &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Quote Product with record ID &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;qp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quotedetailid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; does not have an associated Product record, cancelling plugin execution.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;RetrieveProductID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;productID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Additional fields can be specified using a comma seperated list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Retrieve matching record&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;product&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;productID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;They key thing to remember when registering your Plugin via the Plugin Registration Tool (&lt;a class="link" href="/obtaining-the-user-who-executed-a-workflow-in-dynamics-365-for-customer-engagement-c-workflow-activity/" &gt;steps which regular readers of the blog should have a good awareness of&lt;/a&gt;) is to ensure that the &lt;strong&gt;Event Pipeline Stage of Execution&lt;/strong&gt; is set to &lt;strong&gt;Pre-operation&lt;/strong&gt;. From there, the world is your oyster - you could look at returning additional fields from the &lt;strong&gt;Product&lt;/strong&gt; entity to update on your &lt;strong&gt;Quote Product&lt;/strong&gt; record or you could even look at utilising the same plugin for the &lt;strong&gt;Order Product&lt;/strong&gt; and &lt;strong&gt;Invoice Product&lt;/strong&gt; entities (both of these entities also have &lt;strong&gt;Description&lt;/strong&gt; field, so the above code &lt;em&gt;should&lt;/em&gt; work on these entities as well).&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a real shame that Field Mappings are not available to streamline the population of record data from the &lt;strong&gt;Product&lt;/strong&gt; entity; or the fact that there is no way to utilise features such as Workflows to give you an alternate way of achieving the requirement exemplified in this post. This scenario is another good reason why you should always strive to be a &lt;a class="link" href="/becoming-a-dynamics-crm365-for-enterprise-swiss-army-knife-essential-study-areas/" &gt;Dynamics 365 Swiss Army Knife&lt;/a&gt;, ensuring that you have a good awareness of periphery technology areas that can aid you greatly in mapping business requirements to CRM/D365CE.&lt;/p&gt;</description></item><item><title>Determining the Initiating User Details on a C# Plug-in (Dynamics 365 for Customer Engagement)</title><link>/determining-the-initiating-user-details-on-a-c-plug-in-dynamics-365-for-customer-engagement/</link><pubDate>Sun, 03 Dec 2017 00:00:00 +0000</pubDate><guid>/determining-the-initiating-user-details-on-a-c-plug-in-dynamics-365-for-customer-engagement/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Determining the Initiating User Details on a C# Plug-in (Dynamics 365 for Customer Engagement)" /&gt;&lt;p&gt;In last week&amp;rsquo;s post, &lt;a class="link" href="/obtaining-the-user-who-executed-a-workflow-in-dynamics-365-for-customer-engagement-c-workflow-activity/" &gt;we took a look at how a custom Workflow activity can be implemented within Dynamics CRM/Dynamics 365 for Customer Engagement to obtain the name of the user who triggered the workflow&lt;/a&gt;. It may be useful to retrieve this information for a variety of different reasons, such as debugging, logging user activity or to automate the population of key record information. I mentioned in the post the &amp;ldquo;treasure trove&amp;rdquo; of information that the &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.workflow.iworkflowcontext.aspx" target="_blank" rel="noopener"
&gt;IWorkflowContext&lt;/a&gt; interface exposes to developers. Custom Workflow activities are not unique in having execution-specific information exposable, with an equivalent interface at our disposal when working with plug-ins. No prizes for guessing its name - the &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/microsoft.xrm.sdk.ipluginexecutioncontext.aspx" target="_blank" rel="noopener"
&gt;IPluginExecutionContext&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When comparing both interfaces, some comfort can be found in that they share almost identical properties, thereby allowing us to replicate the functionality demonstrated in last weeks post as Post-Execution Create step for the &lt;strong&gt;Lead&lt;/strong&gt; entity. The order of work for this is virtually the same:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Develop a plug-in C# class file that retrieves the &lt;strong&gt;User&lt;/strong&gt; ID of the account that has triggered the plugin.&lt;/li&gt;
&lt;li&gt;Add supplementary logic to the above class file to retrieve the Display Name of the &lt;strong&gt;User&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Deploy the compiled .dll file into the application via the Plug-in Registration Tool, adding on the appropriate execution step.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The emphasis on this approach, as will be demonstrated, is much more focused towards working &lt;em&gt;outside&lt;/em&gt; of the application; something you may not necessarily be comfortable with. Nevertheless, I hope that the remaining sections will provide enough detail to enable you to replicate within your own environment.&lt;/p&gt;
&lt;h2 id="developing-the-class-file"&gt;Developing the Class File
&lt;/h2&gt;&lt;p&gt;As before, you&amp;rsquo;ll need to have ready access to a Visual Studio C# Class file project and the Dynamics 365 SDK. You&amp;rsquo;ll also need to ensure that your project has a Reference added to the &lt;strong&gt;Microsoft.Xrm.Sdk.dll&lt;/strong&gt;. Create a new &lt;strong&gt;Class&lt;/strong&gt; file and copy and paste the following code into the window:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.Query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;D365.BlogDemoAssets.Plugins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostLeadCreate_GetInitiatingUserExample&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Obtain the execution context from the service provider.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Obtain the organization service reference.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt; &lt;span class="n"&gt;serviceFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateOrganizationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// The InputParameters collection contains all the data passed in the message request.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;lead&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Use the Context to obtain the Guid of the user who triggered the plugin - this is the only piece of information exposed.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InitiatingUserId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Then, use GetUserDisplayCustom method to retrieve the fullname attribute value for the record.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;displayName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetUserDisplayName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Build out the note record with the required field values: Title, Regarding and Description field&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;note&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;annotation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Test Note&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;objectid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;lead&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;notetext&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@&amp;#34;This is a test note populated with the name of the user who triggered the Post Create plugin on the Lead entity:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLine&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLine&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Executing User: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Finally, create the record using the IOrganizationService reference&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note also that you will need to rename the n&lt;strong&gt;amespace&lt;/strong&gt; value to match against the name of your project.&lt;/p&gt;
&lt;p&gt;To explain, the code replicates the same functionality developed as part of the Workflow on last week&amp;rsquo;s post - namely, create a &lt;strong&gt;Note&lt;/strong&gt; related to a newly created &lt;strong&gt;Lead&lt;/strong&gt; record and populate it with the Display Name of the &lt;strong&gt;User&lt;/strong&gt; who has triggered the plugin.&lt;/p&gt;
&lt;h2 id="retrieving-the-users-display-name"&gt;Retrieving the User&amp;rsquo;s Display Name
&lt;/h2&gt;&lt;p&gt;After copying the above code snippet into your project, you may notice a squiggly red line on the following method call:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-GetUserDisplayNameMethodError.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;GetUserDisplayName&lt;/strong&gt; is a custom method that needs to be added in manually and is the only way in which we can retrieve the Display Name of the user, which is not returned as part of the &lt;strong&gt;IPluginExecutionContext&lt;/strong&gt;. We, therefore, need to query the &lt;strong&gt;User&lt;/strong&gt; (&lt;strong&gt;systemuser&lt;/strong&gt;) entity to return the &lt;strong&gt;Full Name&lt;/strong&gt; (&lt;strong&gt;fullname)&lt;/strong&gt; field, which we can then use to populate our newly create &lt;strong&gt;Note&lt;/strong&gt; record. We use a custom method to return this value, which is provided below and should be placed after the last 2 curly braces after the &lt;strong&gt;Execute&lt;/strong&gt; method, but before the final 2 closing braces:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GetUserDisplayName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;systemuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="deploy-to-the-application-using-the-plug-in-registration-tool"&gt;Deploy to the application using the Plug-in Registration Tool
&lt;/h2&gt;&lt;p&gt;The steps involved in this do not differ greatly from what was demonstrated in last week&amp;rsquo;s post, so I won&amp;rsquo;t repeat myself. 🙂 The only thing you need to make sure you do after you have registered the plug-in is to configure the plug-in &lt;strong&gt;Step&lt;/strong&gt;. Without this, your plug-in will not execute. Right-click your newly deployed plug-in on the main window of the Registration Tool and select &lt;strong&gt;Register New Step&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolRegisterNewStep.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;On the form that appears, populate the fields/values indicated below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Message:&lt;/strong&gt; Create&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Primary Entity&lt;/strong&gt;: Lead&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Run in User&amp;rsquo;s Context&lt;/strong&gt;: Calling User&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Event Pipeline Stage of Execution&lt;/strong&gt;: Post-Operation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The window should look similar to the below if populated correctly. If so, then you can click &lt;strong&gt;Register New Step&lt;/strong&gt; to update the application:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolGetInitiatingUserExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;All that remains is to perform a quick test within the application by creating a new &lt;strong&gt;Lead&lt;/strong&gt; record. After saving, we can then verify that the plug-in has created the &lt;strong&gt;Note&lt;/strong&gt; record as intended:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-GetInitiatingUserLeadExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="having-compared-both-solutions-to-achieve-the-same-purpose-is-there-a-recommended-approach-to-take"&gt;Having compared both solutions to achieve the same purpose, is there a recommended approach to take?
&lt;/h2&gt;&lt;p&gt;The examples shown in the past two blog posts indicate excellently how solutions to specific scenarios within the application can be achieved via differing ways. As clearly evidenced, one could argue that there is a code-heavy (plug-in) and a light-touch coding (custom Workflow assembly) option available, depending on how comfortable you are with working with the SDK. Plug-ins are a natural choice if you are confident working solely within Visual Studio or have a requirement to perform additional business logic as part of your requirements. This could range from complex record retrieval operations within the application or even an external integration piece involving &lt;em&gt;specific&lt;/em&gt; and &lt;em&gt;highly tailored&lt;/em&gt; code. The Workflow path clearly favours those of us who prefer to work within the application in a supported manner and, in this particular example, can make certain tasks easier to accomplish. As we have seen, the act of retrieving the Display Name of a user is greatly simplified when we go down the Workflow route. Custom Workflow assemblies also offer greater &lt;em&gt;portability&lt;/em&gt; and &lt;em&gt;reusability&lt;/em&gt;, meaning that you can tailor logic that can be applied to multiple different scenarios in the future. Code reusability is one of the key drivers in many organisations these days, and the use of custom Workflow assemblies neatly fits into this ethos.&lt;/p&gt;
&lt;p&gt;These are perhaps a few considerations that you should make when choosing the option that fits the needs of your particular requirement, but it could be that the way you feel most comfortable with ultimately wins the day - so long as this does not compromise the organisation as a consequence, then this is an acceptable stance to take. Hopefully, this short series of posts have demonstrated the versatility of the application and the ability to approach challenges with equally acceptable pathways for resolution.&lt;/p&gt;</description></item><item><title>Obtaining the User who executed a Workflow in Dynamics 365 for Customer Engagement (C# Workflow Activity)</title><link>/obtaining-the-user-who-executed-a-workflow-in-dynamics-365-for-customer-engagement-c-workflow-activity/</link><pubDate>Sun, 26 Nov 2017 00:00:00 +0000</pubDate><guid>/obtaining-the-user-who-executed-a-workflow-in-dynamics-365-for-customer-engagement-c-workflow-activity/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Obtaining the User who executed a Workflow in Dynamics 365 for Customer Engagement (C# Workflow Activity)" /&gt;&lt;p&gt;It&amp;rsquo;s sometimes useful to determine the name of the user account that executes a Workflow within Dynamics CRM/Dynamics 365 for Customer Engagement (CRM/D365CE). What can make this a somewhat fiendish task to accomplish is the default behaviour within the application, which exposes very little contextual information each time a Workflow is triggered. Take, for example, the following simplistic Workflow which creates an associated &lt;strong&gt;Note&lt;/strong&gt; record whenever a new &lt;strong&gt;Lead&lt;/strong&gt; record is created:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-CreateNoteForLeadWorkflow.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The Note record is set to be populated with the default values available to us regarding the Workflow execution session - &lt;strong&gt;Activity Count, Activity Count including Process&lt;/strong&gt; and &lt;strong&gt;Execution Time&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-WorkflowCreateNoteExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;We can verify that this Workflow works - and view the exact values of these details - by creating a new &lt;strong&gt;Lead&lt;/strong&gt; record and refreshing the record page:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-CreateNoteForLeadWorkflowRecordExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Execution Time&lt;/strong&gt; field is somewhat useful, but the &lt;strong&gt;Activity Count&lt;/strong&gt; &amp;amp; &lt;strong&gt;Activity Count including Process&lt;/strong&gt; values relate to Workflow execution sessions and are only arguably useful for diagnostic review - not something that end users of the application will generally be interested in. 🙂&lt;/p&gt;
&lt;p&gt;Going back to the opening sentence of this post, if we were wanting to develop this example further to include the Name of the user who executed the Workflow in the note, we would have to look at deploying a Custom Workflow Assembly to extract the information out. &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.workflow.iworkflowcontext.aspx" target="_blank" rel="noopener"
&gt;The IWorkflowContext Interface&lt;/a&gt; is a veritable treasure trove of information that can be exposed to developers to retrieve not just the name of the user who triggers a Workflow, but the time when the corresponding system job was created, the Business Unit it is being executed within and information to determine whether the Workflow was triggered by a parent. There are three steps involved in deploying out custom code into the application for utilisation in this manner:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Develop a &lt;strong&gt;CodeActivity&lt;/strong&gt; C# class file that performs the desired functionality.&lt;/li&gt;
&lt;li&gt;Deploy the compiled .dll file into the application via the Plugin Registration Tool.&lt;/li&gt;
&lt;li&gt;Modify the existing Workflow to include a step that accesses the custom Workflow Activity.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of these steps will require ready access to Visual Studio, a C# class plugin project (either a new one or existing) and &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/hh547453.aspx" target="_blank" rel="noopener"
&gt;the CRM SDK that corresponds to your version for the application&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="developing-the-class-file"&gt;Developing the Class File
&lt;/h2&gt;&lt;p&gt;To begin with, make sure your project includes References to the following Frameworks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System.Activities&lt;/li&gt;
&lt;li&gt;Microsoft.Xrm.Sdk&lt;/li&gt;
&lt;li&gt;Microsoft.Xrm.Sdk.Workflow&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Add a new Class (.cs) file to your project and copy &amp;amp; paste the below code, overwriting any existing code in the window. Be sure to update the &lt;strong&gt;namespace&lt;/strong&gt; value to reflect your project name:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Activities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.Workflow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;D365.Demo.Plugins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetWorkflowInitiatingUser&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CodeActivity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kd"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CodeActivityContext&lt;/span&gt; &lt;span class="n"&gt;executionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IWorkflowContext&lt;/span&gt; &lt;span class="n"&gt;workflowContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executionContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetExtension&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IWorkflowContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CurrentUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executionContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;systemuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workflowContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InitiatingUserId&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Output(&amp;#34;Current User&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [ReferenceTarget(&amp;#34;systemuser&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;OutArgument&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CurrentUser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Right-click your project and select &lt;strong&gt;Build&lt;/strong&gt;. Verify that no errors are generated and, if so, then that&amp;rsquo;s the first step done and dusted 🙂&lt;/p&gt;
&lt;h2 id="deploy-to-crmd365ce"&gt;Deploy to CRM/D365CE
&lt;/h2&gt;&lt;p&gt;Open up the Plugin Registration Tool and connect to your desired instance. If you are deploying an existing, updated plugin class, then right-click it on the list of &lt;strong&gt;Registered Plugins &amp;amp; Custom Workflow Activities&lt;/strong&gt; and click &lt;strong&gt;Update&lt;/strong&gt;; otherwise, select &lt;strong&gt;Register -&amp;gt; Register New Assembly&lt;/strong&gt;. The same window opens in any event. Load the newly built assembly from your project (can be located in the &lt;strong&gt;\bin\Debug\&lt;/strong&gt; folder by default) and ensure the &lt;strong&gt;Workflow Activity&lt;/strong&gt; entry is ticked before selecting &lt;strong&gt;Register Selected Plugins&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolRegisterNewAssembly.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;After registration, the Workflow Activity becomes available for use within the application; so time to return to the Workflow we created earlier!&lt;/p&gt;
&lt;h2 id="adding-the-custom-workflow-activity-to-a-process"&gt;Adding the Custom Workflow Activity to a Process
&lt;/h2&gt;&lt;p&gt;By deactivating the &lt;strong&gt;Workflow Default Process Values Example&lt;/strong&gt; Workflow and selecting &lt;strong&gt;Add Step&lt;/strong&gt;, we can verify that the Custom Workflow Assembly is available for use:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-WorkflowCustomCodeActivityExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Select the above, making sure first of all that the option &lt;strong&gt;Insert Before Step&lt;/strong&gt; is toggled (to ensure it appears before the already configured &lt;strong&gt;Create Note for Lead&lt;/strong&gt; step). It should look similar to the below if done correctly:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-WorkflowCustomCodeActivityStepExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Now, when we go and edit the &lt;strong&gt;Create Note for Lead&lt;/strong&gt; step, we will see a new option under &lt;strong&gt;Local Values&lt;/strong&gt; which, when selected, bring up a whole range of different fields that correspond to fields from the &lt;strong&gt;User&lt;/strong&gt; Entity. Modify the text within the &lt;strong&gt;Note&lt;/strong&gt; to retrieve the &lt;strong&gt;Full Name&lt;/strong&gt; value and save it onto the &lt;strong&gt;Note&lt;/strong&gt; record, as indicated below:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-CustomWorkflowAssemblyValuesExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;After saving and reactivating the Workflow, we can verify its working by again creating a new &lt;strong&gt;Lead&lt;/strong&gt; record and refreshing to review the &lt;strong&gt;Note&lt;/strong&gt; text:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-CustomWorkflowAssemblyRecordExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;All working as expected!&lt;/p&gt;
&lt;p&gt;The example shown in this post has very limited usefulness in a practical business scenario, but could be useful in different circumstances:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If your Workflow contains branching logic, then you can test to see if a Workflow has executed by a specific user and then perform bespoke logic based on this value.&lt;/li&gt;
&lt;li&gt;Records can be assigned to other users/teams, based on who has triggered the Workflow.&lt;/li&gt;
&lt;li&gt;User activity could be recorded in a separate entity for benchmarking/monitoring purposes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s useful to know as well that the same kind of functionality can also be deployed when working with plugins as well in the application. We will take a look at how this works as part of next week&amp;rsquo;s blog post.&lt;/p&gt;</description></item><item><title>Modifying Default Lead Qualification Behaviour via C# (Dynamics CRM/Dynamics 365 for Customer Engagement)</title><link>/modifying-default-lead-qualification-behaviour-via-c-dynamics-crmdynamics-365-for-customer-engagement/</link><pubDate>Sun, 15 Oct 2017 00:00:00 +0000</pubDate><guid>/modifying-default-lead-qualification-behaviour-via-c-dynamics-crmdynamics-365-for-customer-engagement/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Modifying Default Lead Qualification Behaviour via C# (Dynamics CRM/Dynamics 365 for Customer Engagement)" /&gt;&lt;p&gt;Dynamics CRM/Dynamics 365 for Customer Engagement (CRM/D365CE) is an incredibly flexible application for the most part. Regardless of how your business operates, you can generally tailor the system to suit your requirements and extend it to your heart&amp;rsquo;s content; often to the point where it is completely unrecognisable from the base application. Notwithstanding this argument, you will come across aspects of the application that are (literally) hard-coded to behave a certain way and cannot be straightforwardly overridden via the application interface. The most recognisable example of this is the Lead Qualification process. You are heavily restricted in how this piece of functionality acts by default but, thankfully, there are ways in which it can be modified if you are comfortable working with C#, JScript and Ribbon development.&lt;/p&gt;
&lt;p&gt;Before we can start to look at options for tailoring the Lead Qualification process, it is important to understand what occurs during the default action within the application. In developer-speak, this is generally referred to as the &lt;strong&gt;QualifyLead&lt;/strong&gt; message and most typically executes when you click the button below on the &lt;strong&gt;Lead&lt;/strong&gt; form:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-QualifyLeadButton.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;When called by default, the following occurs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Status/Status Reason of the &lt;strong&gt;Lead&lt;/strong&gt; is changed to &lt;strong&gt;Qualified&lt;/strong&gt;, making the record inactive and read-only.&lt;/li&gt;
&lt;li&gt;A new &lt;strong&gt;Opportunity&lt;/strong&gt;, &lt;strong&gt;Contact&lt;/strong&gt; and &lt;strong&gt;Account&lt;/strong&gt; record is created and populated with (some) of the details entered on the &lt;strong&gt;Lead&lt;/strong&gt; record. For example, the &lt;strong&gt;Contact&lt;/strong&gt; record will have a &lt;strong&gt;First Name&lt;/strong&gt;/&lt;strong&gt;Last Name&lt;/strong&gt; value supplied on the preceding &lt;strong&gt;Lead&lt;/strong&gt; record.&lt;/li&gt;
&lt;li&gt;You are automatically redirected to the newly created &lt;strong&gt;Opportunity&lt;/strong&gt; record.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is all well and good if you are able to map your existing business processes to the application, but most organisations will typically differ from the applications B2B orientated focus. For example, if you are working within a B2C business process, creating an &lt;strong&gt;Account&lt;/strong&gt; record may not make sense, given that this is typically used to represent a company/organisation. Or, conversely, you may want to jump straight from a &lt;strong&gt;Lead&lt;/strong&gt; to a &lt;strong&gt;Quote&lt;/strong&gt; record. Both of these scenarios would require bespoke development to accommodate currently within CRM/D365CE. This can be broadly categorised into two distinct pieces of work:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Modify the &lt;strong&gt;QualifyLead&lt;/strong&gt; message during its execution to force the desired record creation behaviour.&lt;/li&gt;
&lt;li&gt;Implement client-side logic to ensure that the user is redirected to the appropriate record after qualification.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The remaining sections of this post will demonstrate how you can go about achieving the above requirements in two different ways.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Our first step is to &amp;ldquo;intercept&amp;rdquo; the QualifyLead message at runtime and inject our own custom business logic instead&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have seen a few ways that this can be done. One way, &lt;a class="link" href="https://jlattimer.blogspot.co.uk/2014/09/qualify-leads-without-creating.html" target="_blank" rel="noopener"
&gt;demonstrated here by the always helpful Jason Lattimer&lt;/a&gt;, involves creating a custom JScript function and a button on the form to execute your desired logic. As part of this code, you can then specify your record creation preferences. A nice and effective solution, but one in its guise above will soon obsolete as a result of the &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/dn281891.aspx#Crm2011Endpoint" target="_blank" rel="noopener"
&gt;SOAP endpoint deprecation&lt;/a&gt;. An alternative way is to instead deploy a simplistic C# plugin class that ensures your custom logic is obeyed across the application, and not just when you are working from within the &lt;strong&gt;Lead&lt;/strong&gt; form (e.g. you could have a custom application that qualifies leads using the SDK). Heres how the code would look in practice:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Obtain the execution context from the service provider.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageName&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;QualifyLead&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Get a reference to the Organization service.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateOrganizationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Extract the tracing service for use in debugging sandboxed plug-ins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Input parameters before:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{0}: {1}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Modify the below input parameters to suit your requirements.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//In this example, only a Contact record will be created&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CreateContact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CreateAccount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CreateOpportunity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Input parameters after:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{0}: {1}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To work correctly, you will need to ensure this is deployed out on the &lt;strong&gt;Pre-Operation&lt;/strong&gt; stage, as by the time the message reaches the &lt;strong&gt;Post-Operation&lt;/strong&gt; stage, you will be too late to modify the &lt;strong&gt;QualifyLead&lt;/strong&gt; message.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The next challenge is to handle the redirect to your record of choice after Lead qualification&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Jason&amp;rsquo;s code above handles this effectively, with a redirect after the &lt;strong&gt;QualifyLead&lt;/strong&gt; request has completed successfully to the newly created Account (which can be tweaked to redirect to the Contact instead). The downside of the plugin approach is that this functionality is not supported. So, if you choose to disable the creation of an Opportunity record and then press the Qualify Lead button&amp;hellip;nothing will happen. The record will qualify successfully (which you can confirm by refreshing the form) but you will then have to manually navigate to the record(s) that have been created.&lt;/p&gt;
&lt;p&gt;The only way around this with the plugin approach is to look at implementing a similar solution to the above - a Web API request to retrieve your newly created &lt;strong&gt;Contact&lt;/strong&gt;/&lt;strong&gt;Account&lt;/strong&gt; record and then perform the necessary redirect to your chosen entity form:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;redirectOnQualify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;leadID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;leadID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;leadID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;leadID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;leadID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getClientUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/api/data/v8.0/leads(&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;leadID&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;)?$select=_parentaccountid_value,_parentcontactid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OData-MaxVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;4.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OData-Version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;4.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;application/json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;application/json; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Prefer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;odata.include-annotations=\&amp;#34;OData.Community.Display.V1.FormattedValue\&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onreadystatechange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onreadystatechange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Uncomment based on which record you which to redirect to.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Currently, this will redirect to the newly created Account record
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;accountID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;_parentaccountid_value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Utility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openEntityForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;account&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accountID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//var contactID = result[&amp;#34;_parentcontactid_value&amp;#34;];
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Xrm.Utility.openEntityForm(&amp;#39;contact&amp;#39;, contactID);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;6000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The code is set to execute the Web API call 6 seconds after the function triggers. This is to ensure adequate time for the &lt;strong&gt;QualifyLead&lt;/strong&gt; request to finish and make the fields we need available for accessing.&lt;/p&gt;
&lt;p&gt;To deploy out, we use the eternally useful &lt;a class="link" href="https://www.develop1.net/public/rwb/ribbonworkbench.aspx" target="_blank" rel="noopener"
&gt;Ribbon Workbench&lt;/a&gt; to access the existing Qualify Lead button and add on a custom command that will fire alongside the default one:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/XrmToolBox-Apps-RibbonWorkbenchCustomQualifyLeadButton.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;As this post has hopefully demonstrated, overcoming challenges within CRM/D365CE can often result in different - but no less preferred - approaches to achieve your desired outcome. Let me know in the comments below if you have found any other ways of modifying the default Lead Qualification process within the application.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>What is Unsecure/Secure Configuration on a Dynamics CRM/365 for Enterprise Plugin?</title><link>/what-is-unsecuresecure-configuration-on-a-dynamics-crm365-for-enterprise-plugin/</link><pubDate>Sun, 11 Jun 2017 00:00:00 +0000</pubDate><guid>/what-is-unsecuresecure-configuration-on-a-dynamics-crm365-for-enterprise-plugin/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post What is Unsecure/Secure Configuration on a Dynamics CRM/365 for Enterprise Plugin?" /&gt;&lt;p&gt;When working with applications day in, day out, you sometimes overlook something that is sitting there, staring at you in the face. It may be an important feature or an inconsequential piece of functionality, but you never really take the time to fully understand either way just &lt;em&gt;what&lt;/em&gt; it is and whether it can offer any distinct benefits or assistance. I realised a great example of this when recently deploying some new Plug-ins into Dynamics CRM/Dynamics 365 for Enterprise (CRM/D365E). When you are setting up a new Step for your Plug-in, you are given the option of specifying an &lt;strong&gt;Unsecure Configuration&lt;/strong&gt; and &lt;strong&gt;Secure Configuration&lt;/strong&gt; via a multi-line text box to the right of the window:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolUnsecureSecureConfiguration.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;I was curious about just what these are and why it is not something that you ever really come across when you are first learning about Plug-in development with the application. I took a closer look at what these text boxes do and, as part of this week&amp;rsquo;s blog post, I wanted to share my findings and provide a demonstration of how they work in practice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Theoretical Bit: Unsecure/Secure Configuration Overview&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Typically, when we want to get some juicy information relating to a piece of CRM/D365E functionality, we would turn to our good friends TechNet or MSDN. In this instance, however, there is no dedicated page that covers this topic in-depth. We must instead navigate to the &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/gg328263.aspx#bkmk_writeconstructor" target="_blank" rel="noopener"
&gt;Write a Plug-in Constructor page&lt;/a&gt; to find dedicated information about how these work:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Microsoft Dynamics 365 platform supports an optional plug-in constructor that accepts either one or two string parameters. If you write a constructor like this, you can pass any strings of information to the plug-in at run time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These &amp;ldquo;one or two&amp;rdquo; parameters are the multi-line text boxes indicated above. Information is exposed as &lt;strong&gt;string&lt;/strong&gt; objects within you C# code and you enable this feature within your code by specifying the following, SDK adapted constructor within your Plug-in class:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;MyPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;unsecureString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;secureString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsecureString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secureString&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Unsecure and secure strings are required for this plugin to execute.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_unsecureString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unsecureString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_secureString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secureString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As with anything, there are a number of important caveats to bear in mind with this feature. These can be gleaned via additional online sources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://us.hitachi-solutions.com/blog/use-secure-vs-unsecure-configuration-plugins/" target="_blank" rel="noopener"
&gt;Secure configuration parameters can only be viewed by CRM/D365E Administrators, whereas unsecure can be viewed by any user of the application.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;As highlighted on the above MSDN page, Secure Configuration text is not passed to any Plug-in executing offline via the CRM/D365E for Outlook client.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blogs.msdn.microsoft.com/emeadcrmsupport/2011/05/26/crm-2011-online-secure-configuration-not-stored-in-solution/" target="_blank" rel="noopener"
&gt;Secure configuration parameters are not transportable between environments via a solution export/import.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In terms of use cases, the above articles highlight some potential scenarios that they are best utilised within. Perhaps the best example is for an ISV solution that requires integration with external web services to retrieve data that is then consumed by CRM/D365E. Credentials for these web services can be stored securely when the Plug-in is deployed via the use of Secure configuration parameters. Other than that, if you are developing a Plug-in for internal use, that is unlikely to be deployed/managed across multiple environments, then it is probably not worthwhile to look at utilising configuration parameters when you can just as easily specify these within your code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Practice Makes (for) Perfect (Understanding)!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The best way to see how something works is by getting hands-on and seeing how it works in action. Let&amp;rsquo;s assume you wish to deploy a plugin that executes whenever a record is opened/viewed by any user across the platform. The plugin should update the First Name (&lt;strong&gt;firstname&lt;/strong&gt;) and Last Name (&lt;strong&gt;lastname&lt;/strong&gt;) fields to match the value(s) in the Unsecure and Secure Configuration properties accordingly. The below plugin code will achieve these requirements:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;D365.BlogDemoAssets.Plugins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostContactRetrieve_PluginConfigurationTest&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_unsecureString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_secureString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;PostContactRetrieve_PluginConfigurationTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;unsecureString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;secureString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsecureString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secureString&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Unsecure and secure strings are required for this plugin to execute.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_unsecureString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unsecureString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_secureString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secureString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Obtain the execution context from the service provider.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Obtain the organization service reference.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt; &lt;span class="n"&gt;serviceFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateOrganizationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// The InputParameters collection contains all the data passed in the message request.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_unsecureString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_secureString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When deploying the plug-in using the &lt;strong&gt;Plugin Registration Tool&lt;/strong&gt;, we specify the step to execute on the &lt;strong&gt;Retrieve&lt;/strong&gt; message and to execute in the Pre-Operation Stage (otherwise the form will need to be refreshed to see the updated values!). We also need to specify our desired values for the First Name and Last Name fields in the appropriate Configuration fields. The &lt;strong&gt;Register New Step&lt;/strong&gt; window should look similar to the below if configured correctly:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolUnsecureSecureConfigurationExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;When we navigate into the &lt;strong&gt;Jim Glynn (sample)&lt;/strong&gt; Contact record within CRM/D365E, we can see that the Plug-in has triggered successfully and updated the fields to match against the values specified on Step above:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-UnsecureSecureConfigurationExampleContact.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-UnsecureSecureConfigurationExampleContactPostExecution.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;We can also confirm that the appropriate error is thrown when one of the configuration properties is missing a value, by modifying our Plug-in step and attempting to reload our sample &lt;strong&gt;Contact&lt;/strong&gt; record:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolUnsecureSecureConfigurationMissingValuesExample.png"
loading="lazy"
alt="Can you spot what’s missing? 🙂"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-UnsecureSecureConfigurationExampleError.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;By clicking &lt;strong&gt;Download Log File&lt;/strong&gt;, we can view the error message specified as part of the &lt;strong&gt;InvalidPluginExecutionException&lt;/strong&gt; call. Below is a modified excerpt of the ErrorDetails XML that is generated:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;InnerFault&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;ActivityId&amp;gt;&lt;/span&gt;ed4a2021-9c87-4f06-a493-6d804676bf96&lt;span class="nt"&gt;&amp;lt;/ActivityId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;ErrorCode&amp;gt;&lt;/span&gt;-2147220891&lt;span class="nt"&gt;&amp;lt;/ErrorCode&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;ErrorDetails&lt;/span&gt; &lt;span class="na"&gt;xmlns:d3p1=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://schemas.datacontract.org/2004/07/System.Collections.Generic&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Message&amp;gt;&lt;/span&gt;Unsecure and secure strings are required for this plugin to execute.&lt;span class="nt"&gt;&amp;lt;/Message&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;ExceptionSource&lt;/span&gt; &lt;span class="na"&gt;i:nil=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;InnerFault&lt;/span&gt; &lt;span class="na"&gt;i:nil=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;OriginalException&lt;/span&gt; &lt;span class="na"&gt;i:nil=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;TraceText&lt;/span&gt; &lt;span class="na"&gt;i:nil=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/InnerFault&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Conclusions or Wot I Think&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It is impossible to become what I would like to term a &amp;ldquo;pub quiz champion&amp;rdquo; in CRM/D365E; what I mean by this is that I would defy anyone to rattle off every little detail and fact about the entire platform. As with any pub-quiz, those that do may more than likely end up cheating by &lt;a class="link" href="http://google.com" target="_blank" rel="noopener"
&gt;having their phone out&lt;/a&gt;. With this metaphor in mind, I think Plug-in configuration properties would be an excellent topic for a quiz of this nature. As mentioned previously, it is not something that I was ever made aware of when starting to learn about Plug-in development and is not a feature touted regularly within the online community. Perhaps this is because of its very specific and limited application - although it is handy to have at our disposal, I think its usage is really only targeted towards those who are developing solutions that are deployed across multiple environments AND require the need to store configuration properties for external URL&amp;rsquo;s/web services in a compact and secure manner. Therefore, if you are currently having to use a custom entity within the application to store this type of information, it would make sense to reduce the footprint of your solution within the application itself and make the appropriate changes to use Secure configuration parameters instead. Using a bit of ingenuity (&lt;a class="link" href="https://blogs.msdn.microsoft.com/crm/2008/10/24/storing-configuration-data-for-microsoft-dynamics-crm-plug-ins/" target="_blank" rel="noopener"
&gt;such as XML configuration parameters&lt;/a&gt;), you can achieve the same requirements without the need to customise the application unnecessarily.&lt;/p&gt;</description></item><item><title>Automatically Populate Extended Amount Field When Using Custom Pricing (Dynamics CRM/365 for Enterprise)</title><link>/automatically-populate-extended-amount-field-when-using-custom-pricing-dynamics-crm365-for-enterprise/</link><pubDate>Sun, 04 Jun 2017 00:00:00 +0000</pubDate><guid>/automatically-populate-extended-amount-field-when-using-custom-pricing-dynamics-crm365-for-enterprise/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Automatically Populate Extended Amount Field When Using Custom Pricing (Dynamics CRM/365 for Enterprise)" /&gt;&lt;p&gt;Generally, when you are looking at adopting Dynamics CRM/Dynamics 365 for Enterprise (D365E) within your business, you can be reasonably satisfied that the majority of what is already configured within the system can be very quickly adapted to suit your business needs. Whether it&amp;rsquo;s the &lt;strong&gt;Lead&lt;/strong&gt; to &lt;strong&gt;Opportunity&lt;/strong&gt; sales process or the entire &lt;strong&gt;Case&lt;/strong&gt; management module, the functionality at your disposal is suitable for many organisations across the globe. The great thing as well is that, should you wish to fine-tune things further, you have a broad range of options at your disposal that can help you achieve your objectives - sometimes in very specific and highly unique ways. I have previously looked at a good example of this on the blog - &lt;a class="link" href="/implementing-custom-calculations-for-sales-entities-dynamics-crmdynamics-365-for-enterprise/" &gt;namely, how to override the systems built-in pricing engine in favour of your own&lt;/a&gt; - and, assuming you have a good understanding of C# and &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg309620.aspx" target="_blank" rel="noopener"
&gt;how to deploy plugins to the application,&lt;/a&gt; you can spin an important aspect of the systems functionality on its head to match how your business operates.&lt;/p&gt;
&lt;p&gt;Having this ability is, undoubtedly, a real boon, but can present some odd behaviours. For example, you may start to notice that suddenly the &lt;strong&gt;Extended Amount&lt;/strong&gt; field is no longer being populated with data after implementing your custom pricing engine. The example pictures below demonstrate a before and after example of adding a Product line item to the &lt;strong&gt;Quote&lt;/strong&gt; entity, using the exact same sample &lt;strong&gt;Product&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-ExtendedAmountBefore.png"
loading="lazy"
alt="Before…"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-ExtendedAmountAfter.png"
loading="lazy"
alt="…and after."
&gt;&lt;/p&gt;
&lt;p&gt;The odd thing about this is that, as soon as you click into the record, you will suddenly see a value appear in this field. Very strange!&lt;/p&gt;
&lt;p&gt;It is difficult to pinpoint exactly what is causing the problem, but I can do a &amp;ldquo;stab in the dark&amp;rdquo;. CRM/D365E uses the &lt;strong&gt;CalculatePrice&lt;/strong&gt; message to determine the points when either a) the default price engine or b) a custom one is triggered to perform all necessary calculations. Although there is no official documentation to back this up, I suspect that this message is only triggered when you &lt;strong&gt;Update&lt;/strong&gt; or &lt;strong&gt;Retrieve&lt;/strong&gt; an existing Product line item record (regardless of whether it is an &lt;strong&gt;Opportunity Product&lt;/strong&gt;, &lt;strong&gt;Quote Product&lt;/strong&gt; etc.). This is proven by the fact that, as soon as we click into our Product record, the Extended Amount field is suddenly populated - the platform has triggered the &lt;strong&gt;Retrieve&lt;/strong&gt; message as a result of you opening the record and then, as a next step, forces the &lt;strong&gt;CalculatePrice&lt;/strong&gt; message to also fire. The important thing to clarify with this point is that you &lt;em&gt;must&lt;/em&gt; have a custom pricing implemented successfully within the application for this to work. Otherwise, don&amp;rsquo;t be too surprised if the &lt;strong&gt;Extended Amount&lt;/strong&gt; value remains at 0.&lt;/p&gt;
&lt;p&gt;Whilst the workaround for this is somewhat tolerable if you are working with a small subset of records and do not rely on the &lt;strong&gt;Extended Amount&lt;/strong&gt; as part of any existing reporting within the application, this could really start to cause problems for your end users in the long term and give an impression that the application does not &amp;ldquo;work&amp;rdquo; as it should do. Fortunately, there is a solution that we can look at implementing that will hopefully lead to some happy fingers from not needing to click into records anymore 🙂 &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/hh547453.aspx" target="_blank" rel="noopener"
&gt;Be sure to have the CRM/D365E SDK handy before you begin&lt;/a&gt; the below!&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open up the Plugin Registration Tool from within the SDK, and log into your CRM/D365E instance.&lt;/li&gt;
&lt;li&gt;Scroll down to your Assembly and Plugin that contains your custom pricing engine. If already configured correctly, it should have a step configured for the &lt;strong&gt;CalculatePrice&lt;/strong&gt; message on any entity, as a Synchronous, Post-Operation step.&lt;/li&gt;
&lt;li&gt;Right click your plugin and click on &lt;strong&gt;Register New Step&lt;/strong&gt; to open the window that lets you specify the required settings for your step. Populate the form as follows:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Message&lt;/strong&gt;: Create&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Primary Entity&lt;/strong&gt;: Select one of the Product line item entities that your custom pricing engine uses. The list of accepted entities are &lt;strong&gt;invoicedetail&lt;/strong&gt;, &lt;strong&gt;opportunityproduct&lt;/strong&gt;, &lt;strong&gt;salesorderdetail&lt;/strong&gt; or &lt;strong&gt;quotedetail&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Event Pipeline Stage of Execution&lt;/strong&gt;: Post-Operation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Execution Mode&lt;/strong&gt;: Synchronous&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All other settings can be left as default. Your window should look similar to the below if configured correctly for the &lt;strong&gt;quotedetail&lt;/strong&gt; entity:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolExtendedAmountExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Click on &lt;strong&gt;Register New Step&lt;/strong&gt; to add the step to the application.&lt;/li&gt;
&lt;li&gt;Repeat steps 3-4 for any additional Product line item entities that are using with your custom pricing engine&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, when you go back into CRM/D36E, the Extended Amount values will start to be populated automatically as soon as you add a new &lt;strong&gt;Product&lt;/strong&gt; onto the Product line item subgrid.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusions or Wot I Think&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Whilst the ability to override an important piece of CRM&amp;rsquo;s/D365E&amp;rsquo;s functionality is welcome, you do need to bear in mind the additional overhead and responsibility this leaves your organisation in ensuring that your custom pricing engine is correct and that you have adequately tested the solution to properly identify actions which are out of the ordinary, such as the one discussed in this post. What is slightly frustrating about this quirk, in particular, is the lack of clear documentation regarding the &lt;strong&gt;CalculatePrice&lt;/strong&gt; message from Microsoft. Granted, the message is only exposed for minimal interaction from an SDK point of view and is, for all intents and purposes, an internal application message that we shouldn&amp;rsquo;t really mess with or care about. Having said this, even just a brief summary of &lt;em&gt;when&lt;/em&gt; the message is triggered on the platform would have made it instantly more understandable why any custom pricing calculation engine will fail to provide you with an instant amount within your &lt;strong&gt;Extended Amount&lt;/strong&gt; field. In the end, however, I am pleased that there is a straightforward workaround that can be put into place to ensure that things work as expected; hopefully to the extent that it becomes virtually impossible to determine easily whether your organisation is using the default or a custom pricing engine in the first place.&lt;/p&gt;</description></item><item><title>Automatically Publish Duplicate Detection Rules (Dynamics CRM/Dynamics 365 for Enterprise)</title><link>/automatically-publish-duplicate-detection-rules-dynamics-crmdynamics-365-for-enterprise/</link><pubDate>Sun, 12 Feb 2017 00:00:00 +0000</pubDate><guid>/automatically-publish-duplicate-detection-rules-dynamics-crmdynamics-365-for-enterprise/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Automatically Publish Duplicate Detection Rules (Dynamics CRM/Dynamics 365 for Enterprise)" /&gt;&lt;p&gt;For those who are well versed in rolling out solution updates within Dynamics CRM/365 for Enterprise (CRM/D365E), the process will always have a certain familiarity to it, with a few surprises rolled in now and again. Often, the update will proceed as anticipated; sometimes, you may encounter bizarre issues. I can remember a particularly strange incident I had last year where a solution import would get to about 90-95% completion&amp;hellip;and then the green progress bar would suddenly start rolling back to nothing. The import progress window would then hang with no further guidance or error message. To try and determine the root cause, &lt;a class="link" href="/checking-crm-solution-import-progress-on-premiseonline" &gt;we had to interrogate the &lt;strong&gt;importjob&lt;/strong&gt; entity within the system&lt;/a&gt;, which ended up showing the import job progress stuck at 0.15846281% 😕 In the end, we had to escalate the issue to Microsoft for further investigation, but rest assured that if you have not yet witnessed your own curious solution import experience, it&amp;rsquo;s definitely in the post 🙂&lt;/p&gt;
&lt;p&gt;Thankfully, if you are new to the whole &amp;ldquo;rolling out solution update&amp;rdquo; thing, you can be assured that the process is relatively straightforward, and mostly without issue. If you have been handed a set of solution import instructions for the first time, though, you may be wondering why something similar to the following step is included:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Go into the &lt;strong&gt;Data Management&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Duplicate Detection Rules&lt;/strong&gt; page and click &lt;strong&gt;Publish&lt;/strong&gt; on all &lt;strong&gt;Duplicate Detection Rules&lt;/strong&gt; that have a Status Reason of &lt;strong&gt;Unpublished&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unfortunately, after importing a solution update, CRM/D365E will automatically unpublish all of your &lt;strong&gt;Duplicate Detection Rules&lt;/strong&gt; automatically. You are therefore required to explicitly publish them again, lest you start to encounter a sudden increase in duplicate records and database storage within your system. The reason why this happens is both understandable and frustrating in equal measure. &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg309427.aspx" target="_blank" rel="noopener"
&gt;As outlined in the following MSDN article on the subject&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A duplicate rule condition specifies the name of a base attribute and the name of a matching attribute. For example, specify an account as a base entity and a contact as a matching entity to compare last names and addresses&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As part of the above, explicit matchcodes are created for &lt;em&gt;every&lt;/em&gt; record that the &lt;strong&gt;Duplicate Detection Rule&lt;/strong&gt; is targeting, based on the current metadata of your CRM/D365E entities and attributes. Because your solution update can potentially alter significant aspects of this metadata, the system automatically unpublishes all &lt;strong&gt;Duplicate Detection Rules&lt;/strong&gt; as a precaution.&lt;/p&gt;
&lt;p&gt;The above is perhaps trivial in nature, as the actual process of re-publishing all &lt;strong&gt;Duplicate Detection Rules&lt;/strong&gt; is somewhat negligible in effort terms. Where difficulties can arise is if someone innocently overlooks this part of the process or if your system has many different &lt;strong&gt;Duplicate Detection Rules&lt;/strong&gt;, in a mixture of &lt;strong&gt;Unpublished&lt;/strong&gt;/&lt;strong&gt;Published&lt;/strong&gt; state. You would have to specifically make a note of which rules were &lt;strong&gt;Published&lt;/strong&gt; before beginning your solution import so that you can ensure that the correct rules are published after the fact. I would have thought that after so many versions of the product, that something would be added to address this - for example, perhaps a checkbox at the start of the Solution Import Wizard that lets you specify whether all currently published rules should be reactivated after the import completes successfully.&lt;/p&gt;
&lt;p&gt;If you find that the above is an annoyance that you can do without no longer, like with many things on the platform, there is a solution that can be deployed in code. The SDK exposes the &lt;strong&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/microsoft.crm.sdk.messages.publishduplicaterulerequest.aspx" target="_blank" rel="noopener"
&gt;PublishDuplicateRuleRequest&lt;/a&gt;&lt;/strong&gt; class, which does exactly what it says on the tin - meaning that you can write a plugin that applies this functionality accordingly. The tricky bit comes in determining which Message (i.e. action) on the platform that you wish to run this against. CRM/D365E does not expose a &lt;strong&gt;SolutionUpdate&lt;/strong&gt; or &lt;strong&gt;SolutionImport&lt;/strong&gt; message that we can piggy-back onto, so we have to look at the &lt;strong&gt;PublishAll&lt;/strong&gt; message instead - the action that is triggered when you press &lt;strong&gt;Publish All Customizations&lt;/strong&gt; in the system. This is because this is generally the action you will always need to take when importing an (unmanaged) solution. As a result, we can write a plugin class that is triggered on the &lt;strong&gt;Post-Operation&lt;/strong&gt; event of this entity to automatically publish all &lt;strong&gt;Unpublished&lt;/strong&gt; &lt;strong&gt;Duplicate Detection Rules&lt;/strong&gt; in the system!&lt;/p&gt;
&lt;p&gt;The snippet below is adapted from the sample code provided by Microsoft, but has been tweaked as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.query.queryexpression.aspx" target="_blank" rel="noopener"
&gt;&lt;strong&gt;QueryExpression&lt;/strong&gt;&lt;/a&gt; is used as opposed to &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.query.querybyattribute.aspx" target="_blank" rel="noopener"
&gt;&lt;strong&gt;QueryByAttribute&lt;/strong&gt;&lt;/a&gt;, since we need to query on two separate attributes and their values - &lt;strong&gt;statecode&lt;/strong&gt; and &lt;strong&gt;statuscode&lt;/strong&gt;. You also cannot return an easily accessible count on all results returned with &lt;strong&gt;QueryByAttribute&lt;/strong&gt;. We will see why is useful in a few moments.&lt;/li&gt;
&lt;li&gt;The code explicitly checks for if there are any Unpublished rules first before attempting to proceed further - no point in running code unnecessarily!&lt;/li&gt;
&lt;li&gt;Instead of activating each rule one-by-one using an Execute request, all of the requests are collected together as part of an ExecuteMultipleRequest, &lt;a class="link" href="/bulk-creating-dynamics-crm365-for-enterprise-records-in-c-create-request-vs-executemultiplerequest" &gt;given that we now know the performance benefits that this can have&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="/implementing-tracing-in-your-crm-plug-ins" &gt;Tracing has been implemented in liberal amounts&lt;/a&gt;, to provide remote debugging from within CRM/D365E.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s the code - just copy into an empty class file on your plugin project, modify the namespace to reflect the name of your project and you will be good to go!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Linq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.Query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk.Messages&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Crm.Sdk.Messages&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyPlugin.Plugins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostPublishAll_PublishDuplicateDetectionRules&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Obtain the execution context from the service provider. &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Get a reference to the Organization service. &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationServiceFactory&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateOrganizationService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Extract the tracing service for use in debugging sandboxed plug-ins&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tracing implemented successfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;PublishAll&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PublishRules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;PublishRules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;rules&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetDuplicateDetectionRules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Obtained &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalRecordCount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; duplicate detection rules.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalRecordCount&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Create an ExecuteMultipleRequest object.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ExecuteMultipleRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ExecuteMultipleRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Assign settings that define execution behavior: don&amp;#39;t continue on error, don&amp;#39;t return responses. &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ExecuteMultipleSettings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ContinueOnError&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ReturnResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Create an empty organization request collection.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Requests&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrganizationRequestCollection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Create a collection of PublishDuplicateRuleRequests, and execute them in one batch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PublishDuplicateRuleRequest&lt;/span&gt; &lt;span class="n"&gt;publishReq&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PublishDuplicateRuleRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;DuplicateRuleId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publishReq&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Plugin execution cancelled, as there are no duplicate detection rules to publish.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;GetDuplicateDetectionRules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt; &lt;span class="n"&gt;qe&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;duplicaterule&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;duplicateruleid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConditionExpression&lt;/span&gt; &lt;span class="n"&gt;condition1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConditionExpression&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;condition1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;condition1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Operator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConditionOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;condition1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ConditionExpression&lt;/span&gt; &lt;span class="n"&gt;condition2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ConditionExpression&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;condition2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;condition2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Operator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConditionOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;condition2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FilterExpression&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;FilterExpression&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FilterOperator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LogicalOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;And&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conditions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Conditions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Criteria&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Have to add this, otherwise the record count won&amp;#39;t be returned correctly&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReturnTotalRecordCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetrieveMultiple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The only caveat with the above is that it is arguably only useful for if you are regularly importing &lt;strong&gt;Unmanaged&lt;/strong&gt;, as opposed to &lt;strong&gt;Managed&lt;/strong&gt; solutions, as the &lt;strong&gt;Publish All Customizations&lt;/strong&gt; option is not displayed on the import wizard for unmanaged solutions. Nevertheless, by rolling out the above into your environment, you no longer need to scrabble around for the mental note you have to make when performing a solution update.&lt;/p&gt;</description></item><item><title>Bulk Creating Dynamics CRM/365 for Enterprise Records in C#: Create Request vs. ExecuteMultipleRequest</title><link>/bulk-creating-dynamics-crm365-for-enterprise-records-in-c-create-request-vs-executemultiplerequest/</link><pubDate>Sun, 05 Feb 2017 00:00:00 +0000</pubDate><guid>/bulk-creating-dynamics-crm365-for-enterprise-records-in-c-create-request-vs-executemultiplerequest/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Bulk Creating Dynamics CRM/365 for Enterprise Records in C#: Create Request vs. ExecuteMultipleRequest" /&gt;&lt;p&gt;It is often the case, as part of any application or database system, that certain record types will be well-suited towards duplication. Whilst this is generally a big no-no for individual customer records or invoice details, for example, there are other situations where the ability to duplicate and slightly modify an existing record becomes incredibly desirable. This is then expanded further to the point where end-users are given the ability to perform such duplication themselves.&lt;/p&gt;
&lt;p&gt;A good example of this can be found within Dynamics CRM/Dynamics 365 for Enterprise (CRM/D365E). Email Templates are, in essence, a record type that is duplicated whenever a user selects the &lt;strong&gt;Template&lt;/strong&gt; and creates a new &lt;strong&gt;Email&lt;/strong&gt; record from within the application. Whilst there will always be details that need to be modified once the duplication is performed, having the ability to essentially &amp;ldquo;copy + paste&amp;rdquo; an existing record can generate the following benefits for a business:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Streamlining and adherence to business processes&lt;/li&gt;
&lt;li&gt;Efficiency savings&lt;/li&gt;
&lt;li&gt;Brand consistency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CRM/D365E does a pretty good job of making available a number of record types designed solely for this purpose, but a recent real-life example demonstrated a potential gap. A business I was working with was implementing the full sales process within the application - &lt;strong&gt;Lead&lt;/strong&gt; to &lt;strong&gt;Opportunity&lt;/strong&gt; to &lt;strong&gt;Quote&lt;/strong&gt; etc. At the &lt;strong&gt;Quote&lt;/strong&gt; stage, the businesses existing process would generally involve having a number of predefined &amp;ldquo;templates&amp;rdquo; for Quotes. This was due to the fact that the business would very regularly quote for the same kind of work, often with little or no variation. Out of the box with CRM/D365E, the sales team would have to create a new &lt;strong&gt;Quote&lt;/strong&gt; record and add on &lt;em&gt;every&lt;/em&gt; &lt;strong&gt;Quote Product&lt;/strong&gt; line item each time a &lt;strong&gt;Quote&lt;/strong&gt; was required - leading to little or no efficiency benefit of using the application.&lt;/p&gt;
&lt;p&gt;To get around the issue, I was tasked with creating a means of setting up a number of &amp;ldquo;template&amp;rdquo; &lt;strong&gt;Quote&lt;/strong&gt; records and then have the ability to quickly copy these template records, along with all of their associated &lt;strong&gt;Quote Product&lt;/strong&gt; records, with some minor details changed in the process (for example, the &lt;strong&gt;Name&lt;/strong&gt; value of the Quote). A workflow is immediately the best candidate for addressing the second requirement of this task but would require some additional development work to bring to fruition. I decided then to look, rather nervously, at creating a &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg309745.aspx" target="_blank" rel="noopener"
&gt;custom workflow assembly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Why nervously? To be frank, although I have had plenty experience to date with writing &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/gg328490.aspx" target="_blank" rel="noopener"
&gt;plugins&lt;/a&gt; for CRM/D365E, I had not previously developed a custom workflow assembly. So I was a little concerned that the learning curve involved would be steep and take much longer than first anticipated. Fortunately, my fears were unfounded, and I was able to grasp the differences between a plugin and a custom workflow assembly very quickly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instead of inheriting from the &lt;strong&gt;IPlugin&lt;/strong&gt; interface, your class instead needs to be set to the &lt;strong&gt;CodeActivity&lt;/strong&gt; interface. As with plugins and, depending on Visual Studio version, you can then use CTRL + . to implement your &lt;strong&gt;Execute&lt;/strong&gt; method.&lt;/li&gt;
&lt;li&gt;Context (i.e. the information regarding the who, what and why of the execution; the User, the Entity and the action) is derived from the &lt;strong&gt;IWorkflowContext&lt;/strong&gt; as opposed to the IPluginExecutionContext&lt;/li&gt;
&lt;li&gt;Input/Output Parameters are specified within your &lt;strong&gt;Execute&lt;/strong&gt; method and can be given a label, a target entity and then information regarding the data type that will be passed in/out. For example, to specify an Input Parameter for a Quote &lt;strong&gt;EntityReference&lt;/strong&gt;, with the label &lt;strong&gt;Quote Record to Copy,&lt;/strong&gt; you can use the following snippet:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;[Input(&amp;#34;Quote Record to Copy&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;[ReferenceTarget(&amp;#34;quote&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;InArgument&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;QuoteReference&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The rest is as you would expect when writing a C# plugin. It is good to know that the jump across from plugins to custom workflow assemblies is not too large, so I would encourage anyone to try writing one if they haven&amp;rsquo;t done so already.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Back to the task at hand&amp;hellip;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I implemented the appropriate logic within the custom workflow assembly to first create the &lt;strong&gt;Quote&lt;/strong&gt;, using a &lt;strong&gt;Retrieve&lt;/strong&gt; request to populate the &lt;strong&gt;quote&lt;/strong&gt; variable with the Entity details and fields to copy over:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;newQuote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;newQuote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;newQuote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;newQuote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Copy of &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;newQuote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quotenumber&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;newQuoteID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newQuote&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The important thing to remember with this is that you &lt;strong&gt;must&lt;/strong&gt; set the ID of the record to blank and then remove it from the &lt;strong&gt;newQuote&lt;/strong&gt; - otherwise, your code will attempt to create the new record with the existing GUID of the copied record, resulting in an error.&lt;/p&gt;
&lt;p&gt;Next, I performed a &lt;strong&gt;RetrieveMultiple&lt;/strong&gt; request based off a &lt;strong&gt;QueryExpression&lt;/strong&gt; to return all &lt;strong&gt;Quote Product&lt;/strong&gt; records related to the existing records. Once I had my results in my &lt;strong&gt;qp EntityCollection&lt;/strong&gt;, I then implemented my logic as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;qp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quotedetailid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newQuoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newProduct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After deploying to CRM and setting up the corresponding Workflow that referenced the assembly, I began testing. I noticed that the Workflow would occasionally fail on certain &lt;strong&gt;Quote&lt;/strong&gt; records, with the following error message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The plug-in execution failed because the operation has timed-out at the Sandbox Client.System.TimeoutException&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The word &lt;strong&gt;Sandbox&lt;/strong&gt; immediately made me think back to some of the &lt;a class="link" href="/to-online-or-not-online-factors-to-consider-when-comparing-crm-onlineon-premise" &gt;key differences between CRM/D365E Online and On-Premise version&lt;/a&gt;, precisely the following detail pertaining to custom code deployed to Online versions of the application - it must always be deployed in Sandbox mode which, by default, only allows your code to process for 2 minutes maximum. If it exceeds this, the plugin/workflow will immediately fail and throw back the error message above. Upon closer investigation, the error was only being thrown for &lt;strong&gt;Quote&lt;/strong&gt; records that had a lot of &lt;strong&gt;Quote Products&lt;/strong&gt; assigned to them. I made the assumption that the reason why the workflow was taking longer than 2 minutes is because my code was performing a &lt;strong&gt;Create&lt;/strong&gt; request into CRM for &lt;em&gt;every&lt;/em&gt; &lt;strong&gt;Quote Product&lt;/strong&gt; record and, as part of this, only proceeding to the next record once a success/failure response was returned from the application.&lt;/p&gt;
&lt;p&gt;The challenge was therefore to find an alternative means of creating the &lt;strong&gt;Quote Product&lt;/strong&gt; records without leading the Workflow to fail. After doing some research, I came across a useful MSDN article and &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/jj863604.aspx" target="_blank" rel="noopener"
&gt;code example&lt;/a&gt; that utilised the &lt;strong&gt;ExecuteMultipleRequest&lt;/strong&gt; message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can use the ExecuteMultipleRequest message to support higher throughput bulk message passing scenarios in Microsoft Dynamics 365 (online &amp;amp; on-premises), particularly in the case of Microsoft Dynamics 365 (online) where Internet latency can be the largest limiting factor. ExecuteMultipleRequest accepts an input collection of message Requests, executes each of the message requests in the order they appear in the input collection, and optionally returns a collection of Responses containing each message&amp;rsquo;s response or the error that occurred.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source: &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/jj863631.aspx" target="_blank" rel="noopener"
&gt;https://msdn.microsoft.com/en-us/library/jj863631.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Throwing caution to the wind, I repurposed my code as follows, in this instance choosing not to return a response for each request:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Create an ExecuteMultipleRequest object.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ExecuteMultipleRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ExecuteMultipleRequest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Assign settings that define execution behavior: continue on error, return responses. &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ExecuteMultipleSettings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ContinueOnError&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ReturnResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Create an empty organization request collection.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Requests&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrganizationRequestCollection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;qp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quotedetailid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quoteid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quote&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newQuoteID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CreateRequest&lt;/span&gt; &lt;span class="n"&gt;cr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CreateRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newProduct&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Thankfully, after re-testing, we no longer encountered the same errors on our particularly large &lt;strong&gt;Quote&lt;/strong&gt; test records.&lt;/p&gt;
&lt;p&gt;As a learning experience, the above has been very useful in showcasing how straightforward custom workflow assemblies are when coming from a primarily plugin development background. In addition, the above has also presented an alternative method for creating batch records within CRM/D365E, in a way that will not cause severe performance detriment. I was surprised, however, that there is no out of the box means of quickly copying existing records, thereby requiring an approach using code to resolve. &lt;strong&gt;Quotes&lt;/strong&gt; are an excellent example of an Entity that could benefit from Template-isation in the near future, in order to expedite common order scenarios and help prevent carpel tunnel syndrome from CRM users the world over. 🙂&lt;/p&gt;</description></item><item><title>Implementing Custom Calculations for Sales Entities (Dynamics CRM/Dynamics 365 for Enterprise)</title><link>/implementing-custom-calculations-for-sales-entities-dynamics-crmdynamics-365-for-enterprise/</link><pubDate>Sun, 29 Jan 2017 00:00:00 +0000</pubDate><guid>/implementing-custom-calculations-for-sales-entities-dynamics-crmdynamics-365-for-enterprise/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Implementing Custom Calculations for Sales Entities (Dynamics CRM/Dynamics 365 for Enterprise)" /&gt;&lt;p&gt;Organisations that deploy Dynamics CRM/Dynamics 365 for Enterprise (CRM/D365E) can immediately take advantage of a number of inbuilt functionality, processes and data models that can be re-purposed with minimal effort. Whilst this approach can often lead to more streamlined deployment of your CRM/D365E solution, individuals customising the system should take care not to make the system fit around a business too much; rather, the opposite must be achieved where ever possible and careful analysis should be carried out in the outset to ensure that this balance is maintained. Sacrificing sensible business processes to accommodate for the quirks of a particular business system is a major pitfall that should be avoided as part of any major IT system deployment.&lt;/p&gt;
&lt;p&gt;A good example of this can be found in the pricing calculation engine within CRM/D365E, which is utilised by the following entities within the system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Opportunity&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opportunity Product&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quote&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quote Product&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Order&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Order Product&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invoice&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invoice Product&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rather than having to implement your own logic to generate prices for these entities, businesses can choose to utilise the pricing engine to automatically generate the net total for your Products, calculate appropriate Discounts and then figure out the final total at the end.&lt;/p&gt;
&lt;p&gt;For those who are dissatisfied with how CRM performs this calculation, you will be pleased to hear that you have the option to override the default pricing engine and specify your own via a C# plugin. More information, &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/dn817877.aspx" target="_blank" rel="noopener"
&gt;and a very handy code example&lt;/a&gt;, can be found on our good friend MSDN:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The pricing engine in Microsoft Dynamics 365 supports a standard set of pricing and discounting methods, which might be limiting to your business depending on your specific requirements for applying taxation, discounts, and other pricing rules for your products. If you want to define custom pricing for your products in opportunities, quotes, orders and invoices, you can use the &lt;strong&gt;CalculatePrice&lt;/strong&gt; message.&lt;/p&gt;
&lt;p&gt;To use the custom pricing for your opportunities, quotes, orders, and invoices:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set the value of the &lt;strong&gt;Organization.OOBPriceCalculationEnabled&lt;/strong&gt; attribute to &lt;strong&gt;0&lt;/strong&gt; (false). You can also use the &lt;strong&gt;Sales&lt;/strong&gt; tab in the system settings area in Microsoft Dynamics 365 or Microsoft Dynamics 365 for Outlook to disable system pricing. More information:  &lt;a class="link" href="http://go.microsoft.com/fwlink/p/?LinkId=512492" target="_blank" rel="noopener"
&gt;Configure product catalog information&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Create a plug-in that contains your custom pricing code for calculating the price for your opportunity, quote, order, or invoice.&lt;/li&gt;
&lt;li&gt;Register the plug-in on the &lt;strong&gt;CalculatePrice&lt;/strong&gt; message.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source: &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/dn817885.aspx" target="_blank" rel="noopener"
&gt;https://msdn.microsoft.com/en-us/library/dn817885.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I think the most key thing as part of the above is not to overlook the simplest step - namely, modifying the setting within CRM/D365E that lets you specify your custom pricing engine in the first place. If this is not set, then you may spend many hours trying to figure out why your beautifully developed plugin is not working! It can be found very straightforwardly in &lt;strong&gt;Administration&lt;/strong&gt; area of the application, on the &lt;strong&gt;System Settings&lt;/strong&gt; page:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-SystemSettings.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-UseSystemPricingCalculation.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Whilst the code example provided by Microsoft gives you a good flavour of what you can potentially achieve with your own custom logic, I thought I would share two further examples that I recently was involved in developing, which may also prove useful when putting together your own custom pricing engine.&lt;/p&gt;
&lt;h2 id="calculating-custom-fieldsattributes"&gt;Calculating Custom Fields/Attributes
&lt;/h2&gt;&lt;p&gt;Arguably one of the biggest benefits of implementing your own custom pricing engine is being able to incorporate additional fields as part of the calculation. A recent real life example best demonstrates this. I was implementing a quoting solution for a business within Dynamics CRM 2015. The organisation was, fortunately, able to utilise much of the out of the box functionality within CRM as part of their existing processes. The only caveat was that they wanted the ability to add a Margin value at the Order level, in a similar vein to the Discount fields currently on the Quote entity - a Discount value and a Discount percentage value. The organisation wanted the option to do both, either or neither i.e. have the ability to specify a Margin value AND an additional percentage on top of that.&lt;/p&gt;
&lt;p&gt;After configuring the appropriate fields within CRM to store both a currency value for the &lt;strong&gt;Margin&lt;/strong&gt; and a decimal value for the &lt;strong&gt;Margin&lt;/strong&gt; &lt;strong&gt;(%)&lt;/strong&gt;, we then proceeded to write some custom code that would achieve this aim. A snippet of this can be found below, which takes an existing &lt;strong&gt;total&lt;/strong&gt; value of all &lt;strong&gt;Products&lt;/strong&gt; on a Quote and then applies the correct calculation. It is worth explaining that the system returns NULL values if there is no data in the field when using the &lt;strong&gt;GetAttributeValue&lt;/strong&gt; method (&lt;a class="link" href="/the-benefits-of-using-getattributevalue-to-access-crm-attributes-late-bound-c/" &gt;a fact I was already well aware of&lt;/a&gt;), which is why we have to specifically set the variables with a default value of 0 and perform the NULL check:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;margin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;marginPercent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;new_mycustommarginamountfield&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;margin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;new_mycustommarginamountfield&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;new_mycustommarginpercentagefield&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;marginPercent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;new_mycustommarginpercentagefield&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Calculate margin amount based on the total amount&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;totalamountlessfreight&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Calculate margin percentage based on the total amount&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;marginPercentVal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;marginPercent&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;marginPercentVal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;totalamountlessfreight&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="calculating-sales-tax"&gt;Calculating Sales Tax
&lt;/h2&gt;&lt;p&gt;CRM/D365E makes the assumption that tax will always be calculated on the Product Detail level. That&amp;rsquo;s why the &lt;strong&gt;Quote Product&lt;/strong&gt;, &lt;strong&gt;Opportunity Product&lt;/strong&gt;, &lt;strong&gt;Order Product&lt;/strong&gt; and &lt;strong&gt;Invoice Product&lt;/strong&gt; entities have a &lt;strong&gt;Tax&lt;/strong&gt; field, demonstrated below on the &lt;strong&gt;Quote Product&lt;/strong&gt; form:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-PricingSalesText.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;There are a few problems with this, however:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You cannot set a default Tax for each &lt;strong&gt;Product&lt;/strong&gt; in the system. What this means is that you have to drill down to &lt;em&gt;every&lt;/em&gt; &lt;strong&gt;Product&lt;/strong&gt; details entity and populate the Tax manually. Whilst you could look at a Business Rule, Workflow or some custom code to get around this issue, this seems like a rather complicated solution to something that you would expect to be easy to configure.&lt;/li&gt;
&lt;li&gt;My experience indicates that most companies in the UK calculates tax on the gross amount of an order, and not at an individual Product level. Attempting to try and change a common practice to fit around a business system is a good example of what I spoke about in the introduction to this blog post.&lt;/li&gt;
&lt;li&gt;Generally, most organisations will work with a flat rate of Tax for all Products (unless they are dealing with other countries). With this in mind, it seems a little crazy having to set this on an individual basis.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By using our own custom calculation logic, we can get around the above and implement a solution that best meets our need. For example, here is a code snippet that will take the total value of all Products on the Order entity and then calculate the VAT tax amount at 20%, saving the tax-only amount and the Net Total back to the system:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;vat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.20&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;tax&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quantity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;priceperunit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;extendedamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="kt"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;quantity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;priceperunit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Calculate total from tax&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tax&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;vat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;totaltax&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;totalamount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Money&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It would be disingenuous of me not to point out that the above solution has its own faults - the biggest one being that your code would require manually updating if the tax rate ever changes in the future. You can perhaps get around this issue by instead storing the current tax rate within a CRM entity, that can be updated in line with any future changes. Your plugin could then query this entity/attribute each time the plugin is executed.&lt;/p&gt;
&lt;h2 id="conclusions-or-wot-i-think"&gt;Conclusions or Wot I Think
&lt;/h2&gt;&lt;p&gt;Whilst the ability to override a key feature within CRM/D365E is incredibly welcome and a great example of how you can leverage the system without compromising on your existing business processes, it is arguable that this process is hardly straightforward. A passing knowledge of C# is mandatory to even begin to start implementing your own custom pricing engine, as well as good awareness of how CRM/D365E plugins work. This is all stuff that an administrator of the application may struggle to grasp, thereby requiring dedicated resource or knowledge within the business to implement the desired solution. It would be nice to perhaps see, as part of a future version of D365E, the ability to specify a custom pricing engine within the application itself - similar to how Business Rules were introduced and reduced the need for form-level JScript functions to achieve common tasks. Nevertheless, it has been good to discover that the &lt;strong&gt;CalculatePricing&lt;/strong&gt; message is exposed within the application and that the application has the flexibility for end users to modify (and perhaps improve upon 🙂) one of its key features.&lt;/p&gt;</description></item><item><title>Utilising Views with the CRM/Dynamics 365 for Enterprise Web API</title><link>/utilising-views-with-the-crmdynamics-365-for-enterprise-web-api/</link><pubDate>Sun, 08 Jan 2017 00:00:00 +0000</pubDate><guid>/utilising-views-with-the-crmdynamics-365-for-enterprise-web-api/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Utilising Views with the CRM/Dynamics 365 for Enterprise Web API" /&gt;&lt;p&gt;I was recently showing a colleague how to use the rather excellent &lt;a class="link" href="https://github.com/jlattimer/CRMRESTBuilder" target="_blank" rel="noopener"
&gt;CRM REST Builder Managed Solution&lt;/a&gt;, in particular, its ability to generate code snippets for predefined query requests into Dynamics CRM/Dynamics 365 for Enterprise (CRM/D365E). During the demo, I noticed the following options under the &lt;strong&gt;Query Type&lt;/strong&gt; drop-down with interest:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-CRMRESTBuilder-QueryType.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;I did some further digging on MSDN to confirm that my suspicions were correct, and I was pleased to be able to confirm the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Microsoft Dynamics 365 allows you to define, save, and execute two types of queries as listed here.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Saved Query&lt;/td&gt;
&lt;td&gt;System-defined views for an entity. These views are stored in the &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/mt607896.aspx" target="_blank" rel="noopener"
&gt;savedquery EntityType&lt;/a&gt;. More information: &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/gg328457.aspx" target="_blank" rel="noopener"
&gt;Customize entity views&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User Query&lt;/td&gt;
&lt;td&gt;Advanced Find searches saved by users for an entity. These views are stored in the &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/mt593110.aspx" target="_blank" rel="noopener"
&gt;userquery EntityType&lt;/a&gt;. More information: &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/gg509053.aspx" target="_blank" rel="noopener"
&gt;UserQuery (saved view) entity&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Records for both of these types of entities contain the FetchXML definition for the data to return. You can query the respective entity type to retrieve the primary key value. With the primary key value, you can execute the query by passing the primary key value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source: &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/mt607533.aspx" target="_blank" rel="noopener"
&gt;https://msdn.microsoft.com/en-gb/library/mt607533.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So to clarify the above, there are 3 ways we can query CRM&amp;rsquo;s/D365&amp;rsquo;s Web Services with FetchXML based queries: either with a direct FetchXML query, by referencing a System View or by referencing a Personal View. The benefits of using a System/Personal view are significant, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By having your Web API query setup as a view within CRM, you can utilise it within the application as part of a dashboard, entity view etc.&lt;/li&gt;
&lt;li&gt;You can reduce the size of your request and obfuscate information relating to your CRM instance (such as entity and attribute names) by using a saved query.&lt;/li&gt;
&lt;li&gt;Your FetchXML query can be stored within the application, meaning that you don&amp;rsquo;t need to worry about finding alternative means of backing up/storing your query.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="/powerbi-deep-dive-using-the-web-api-to-query-dynamics-crm365-for-enterprise" &gt;Knowing the above would have been quite useful during my recent PowerBI exploits involving the CRM/D365 Web API&lt;/a&gt;, so this is definitely something that I will be reviewing again in future. If you want to get started using Saved/User queries in the application yourself, there are a few things to decide on in the first instance and slight hurdles to overcome initially, depending on the nature of your FetchXML query.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So first things first, how do I create my user/system query in CRM?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This will depend on the complexity of the query you are attempting to execute. To demonstrate this, let&amp;rsquo;s take a look at FetchXML Query # 1:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;fetch&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;output-format=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;xml-platform&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;mapping=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;logical&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;distinct=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;false&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;entity&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;phonecall&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;prioritycode&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;scheduledend&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;createdby&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;regardingobjectid&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;activityid&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;order&lt;/span&gt; &lt;span class="na"&gt;attribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;descending=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;false&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;filter&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;and&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;condition&lt;/span&gt; &lt;span class="na"&gt;attribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;directioncode&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;operator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;eq&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;0&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/entity&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/fetch&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above is a nice and straightforward query to return Phone Call records with a &lt;strong&gt;directioncode&lt;/strong&gt; of &amp;ldquo;Incoming&amp;rdquo;, that can be built as an &lt;a class="link" href="https://www.microsoft.com/en-US/dynamics/crm-customer-center/create-edit-or-save-an-advanced-find-search.aspx" target="_blank" rel="noopener"
&gt;Advanced Find Personal View&lt;/a&gt; or &lt;a class="link" href="https://www.microsoft.com/en-us/dynamics/crm-customer-center/create-or-edit-a-public-view-for-an-entity.aspx" target="_blank" rel="noopener"
&gt;System View&lt;/a&gt; very straightforwardly. But things change significantly when we take a look at FetchXML Query # 2 (an adapted query, &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/dn531006.aspx" target="_blank" rel="noopener"
&gt;provided courtesy of MSDN&lt;/a&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;fetch&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;output-format=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;xml-platform&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;mapping=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;logical&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;distinct=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;entity&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;lead&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;link-entity&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;task&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;from=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;regardingobjectid&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;leadid&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;alias=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ab&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;link-type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;outer&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;filter&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;and&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;condition&lt;/span&gt; &lt;span class="na"&gt;entityname=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ab&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;attribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;regardingobjectid&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;operator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;null&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/entity&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/fetch&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There is no way that we can specify an outer join query within the CRM interface; so the only way in which we can get this query saved back into CRM is by writing a bespoke C# app that will add it in for us. Here is a code example for a method achieving this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;CreateSystemView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;viewID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;layoutXML&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@&amp;#34;&amp;lt;grid name=&amp;#39;resultset&amp;#39; object=&amp;#39;4&amp;#39; jump=&amp;#39;fullname&amp;#39; select=&amp;#39;1&amp;#39; preview=&amp;#39;1&amp;#39; icon=&amp;#39;1&amp;#39;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;row name=&amp;#39;result&amp;#39; id=&amp;#39;leadid&amp;#39;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;cell name=&amp;#39;fullname&amp;#39; width=&amp;#39;150&amp;#39; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/row&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/grid&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fetchXML&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@&amp;#34;&amp;lt;fetch version=&amp;#39;1.0&amp;#39; output-format=&amp;#39;xml-platform&amp;#39; mapping=&amp;#39;logical&amp;#39; distinct=&amp;#39;true&amp;#39;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;entity name=&amp;#39;lead&amp;#39;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;attribute name=&amp;#39;fullname&amp;#39; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;link-entity name=&amp;#39;task&amp;#39; from=&amp;#39;regardingobjectid&amp;#39; to=&amp;#39;leadid&amp;#39; alias=&amp;#39;ab&amp;#39; link-type=&amp;#39;outer&amp;#39; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;filter type=&amp;#39;and&amp;#39;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;condition entityname=&amp;#39;ab&amp;#39; attribute=&amp;#39;regardingobjectid&amp;#39; operator=&amp;#39;null&amp;#39; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/filter&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/entity&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/fetch&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;savedQuery&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;savedquery&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;savedQuery&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Complex View Test&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;savedQuery&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Test view to demonstrate how to create a view with a complex FetchXML query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;savedQuery&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;returnedtypecode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;lead&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;savedQuery&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fetchxml&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fetchXML&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;savedQuery&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;layoutxml&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layoutXML&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;savedQuery&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;querytype&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;viewID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedQuery&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Created system view &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;viewID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Two things to point out with the above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For the layoutXML, be sure to modify the &lt;strong&gt;object&lt;/strong&gt; value so that it is the correct value for the entity you are working with. Otherwise, although your view will be successfully created within the application, you will be unable to load it correctly from within the interface. You can find a list of all system Entity codes &lt;a class="link" href="https://msdynamicscrmblog.wordpress.com/2013/07/18/entity-type-codes-in-dynamics-crm-2011/" target="_blank" rel="noopener"
&gt;here&lt;/a&gt;. For custom Entity codes, you will need to use a tool like the &lt;a class="link" href="https://github.com/MscrmTools/MsCrmTools.MetadataBrowser" target="_blank" rel="noopener"
&gt;Metadata Browser in the XRMToolBox&lt;/a&gt; to determine the correct value.&lt;/li&gt;
&lt;li&gt;The above code example is using late-bound classes to generate the appropriate data to create the view, &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg594431.aspx" target="_blank" rel="noopener"
&gt;contrary to the official sample code provided by Microsoft&lt;/a&gt;. I was a little bit unsure initially whether views could be created in the manner, so I was pleased when I was able to confirm the opposite 🙂&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;With your view created, what&amp;rsquo;s next?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll need to obtain the database GUID for the view record in CRM. If you have created your view for the complex example above, then you can very easily grab this value by setting a breakpoint in your application in Visual Studio and accessing the &lt;strong&gt;viewID&lt;/strong&gt; value. An alternative way is via the application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For System Views, navigate to the View within the solutions page and open it up as if you were about to edit it. Maximise the window to full screen by pressing the F11 key. The URL of the page should now be visible if you move your mouse to the top of the screen, and available for copying. It should look something like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;http://mycrminstance/tools/vieweditor/viewManager.aspx?appSolutionId=%7bFD140AAF-4DF4-11DD-BD17-0019B9312238%7d&amp;amp;entityId=%7bDC6574CB-92CE-446C-A5D6-885A75107D52%7d&amp;amp;id=%7b6979F60B-D5D4-E611-80DC-00155D02DD0D%7d&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The GUID of the view will be the last query parameter string, with the encoded curly braces values (%7b and %7d) removed. So, based on the above, the GUID is:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;6979F60B-D5D4-E611-80DC-00155D02DD0D&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Personal Views are a little more tricky. The most straightforward way I can think of obtaining this is by going to a Users list of &lt;strong&gt;Active Saved Views&lt;/strong&gt;, exporting the list to Excel via the &lt;strong&gt;Static Worksheet (Page Only)&lt;/strong&gt; button and then grabbing the GUID from the hidden Cell A in Excel:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-ExportSavedViews.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/MicrosoftOffice-Excel-D365SavedViews.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;This would obviously require you to have access to the Personal View, either via user login details or by having the user share the view to you. An alternative way to get this information would be via querying the &lt;strong&gt;Saved View&lt;/strong&gt; entity via FetchXML/T-SQL.&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve got your GUID, you&amp;rsquo;re all set - you can now build your web service request in the language/format of your choosing. An example via XmlHttpRequest in JScript can be found below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getClientUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/api/data/v8.1/leads?savedQuery=6979F60B-D5D4-E611-80DC-00155D02DD0D&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OData-MaxVersion&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;4.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OData-Version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;4.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;application/json&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Prefer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;odata.include-annotations=\&amp;#34;*\&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onreadystatechange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onreadystatechange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Xrm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Utility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alertDialog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The actual request header should resemble the below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /JG/api/data/v8.1/leads?savedQuery=6979F60B-D5D4-E611-80DC-00155D02DD0D HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;OData-MaxVersion: 4.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;OData-Version: 4.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Accept: application/json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Prefer: odata.include-annotations=&amp;#34;*&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Accept-Language: en-GB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Accept-Encoding: gzip, deflate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Connection: Keep-Alive
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Cookie: ReqClientId=9f48373a-aa68-462c-aab0-15ebd9311ce4; persistentNavTourCookie=HideNavTour; dea5e364-6f18-e611-80b5-00155d02dd0d_08f6129c-ce5b-4b98-8861-b15d01523fe1=/Date(1472324901665)/; excelDownloadToken=-1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Encapsulating your CRM/D365E queries as part of a System or Personal View is an effective way of reducing the size of your web service requests and simplifying the contents of the request whilst in transit. I would argue that a System View is a far better candidate for this job compared to a Personal View. Unless you have a specific business requirement not to have the view available to all users within the application, utilising this could save on lots of troubleshooting and administrative headroom down the line compared with a Personal View (such as if, for example, the person who has created the view originally leaves the business).&lt;/p&gt;</description></item><item><title>Becoming a Dynamics CRM/365 for Enterprise Swiss Army Knife: Essential Study Areas</title><link>/becoming-a-dynamics-crm365-for-enterprise-swiss-army-knife-essential-study-areas/</link><pubDate>Sun, 18 Dec 2016 00:00:00 +0000</pubDate><guid>/becoming-a-dynamics-crm365-for-enterprise-swiss-army-knife-essential-study-areas/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Becoming a Dynamics CRM/365 for Enterprise Swiss Army Knife: Essential Study Areas" /&gt;&lt;p&gt;Getting to grips with how to use Dynamics CRM/365 for Enterprise (D365E) is no easy feat. You can imagine just how difficult it is for an end user to get to grips with how the application works and functions; with more detailed knowledge around customisation and development being an entirely different ball game altogether. Compounding this problem further is the fact that the product has evolved at an increasingly more rapid pace over recent years, to the point where it is literally impossible to become a master of &lt;em&gt;everything&lt;/em&gt; that you can do within CRM/D365E. Those venturing into the product for the first time may find their learning journey significantly simplified if they already have a good general knowledge about some of the underlying technology that powers CRM/D365E. This was certainly true in my case; I had a good background already in managing Office 365, writing SQL queries/reports and some experience with C#. This is all incredibly useful knowledge to have in your arsenal and is all directly applicable towards CRM/D365E in some way. For those who are getting to grips with the product for the first time, either without this previous experience or as part of an apprentice/graduate type role, your journey may not be as swift and issue-free. With this in mind, here&amp;rsquo;s my list of essential knowledge that you can add to your own &amp;ldquo;swiss army knife&amp;rdquo; of personal knowledge. Experience and good knowledge of these technologies will not only help you greatly in working with CRM/D365E, but present an excellent learning opportunity for Microsoft technologies more generally and something that you can add to your CV with pride:&lt;/p&gt;
&lt;h2 id="sql-server"&gt;SQL Server
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;What is it? :&lt;/strong&gt; SQL Server is Microsoft&amp;rsquo;s proprietary database knowledge, based on the ANSI standard. SQL stands for Structured Query Language and is one the most widely used database programming languages on the planet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why Knowing It Is Useful:&lt;/strong&gt; The underlying database technology that CRM/D365E uses is SQL Server, so having a general awareness of relational database systems work and how SQL Server differs from the standard goes a long way in understanding what is capable from a customisation/development viewpoint. For example, you can very quickly grasp which data types the application supports, as they will all ultimately be based on a supported SQL Server column data type. If you are running on-premise versions of CRM/D365E, then knowledge of SQL Server immediately moves from being a nice bonus to an essential requirement. This is because administrators will need to have good knowledge of how to manage their Dynamics CRM database instance, perform backups and also, potentially, write transact-SQL (T-SQL) queries against your database for reporting or diagnostic work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Area of Study:&lt;/strong&gt; Focusing your attention towards SQL Server Reporting Services (SSRS) report writing will benefit you the most. Through this, you can begin to establish good knowledge of how SQL Server databases work generally, and be in a position to write FetchXML for Online/On-Premise deployments of the application or Transact-SQL (T-SQL) based reports for On-Premise only. Having a good awareness of what is capable via a standard SQL query will also hold your good stead when working with FetchXML, as you can immediately make a number of assumptions about what is possible with FetchXML (for example, filtering results using an IN block containing multiple values and performing grouping/aggregate actions on datasets)&lt;/p&gt;
&lt;h2 id="office-365"&gt;Office 365
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt; : Office 365 is Microsofts primary - and perhaps most popular - cloud offering for businesses, individuals or home users. Through a wide array of different subscription offers, home and business users can &amp;ldquo;pick &amp;rsquo;n&amp;rsquo; mix&amp;rdquo; the range of solutions they require - from Exchange-based email accounts to licenses for Microsoft Visio/Project, through to PowerBI.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why Knowing It Is Useful:&lt;/strong&gt; Although it is arguable that knowledge of Office 365 is not essential if you anticipate working with on-premises versions of the application, you may be doing yourself a disservice in the long term. Microsoft is increasingly incentivising organisations to move towards the equivalent cloud versions of their on-premise applications, meaning that as much knowledge as possible of how CRM/D365E Online works in the context of Office 365 is going to become increasingly more mandatory. If you are looking to secure a career change in the near future, and have not had much experience with Office 365, then this is definitely an area that you should focus on for future learning. From a day-to-day management point of view for the Online version of the product, some basic awareness of how to navigate around and use Office 365 is pretty much essential if you are going to succeed working with the product on a day-to-day basis.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Area of Study&lt;/strong&gt;: &lt;a class="link" href="https://technet.microsoft.com/en-us/library/mt772202.aspx" target="_blank" rel="noopener"
&gt;Spin up a D365E trial&lt;/a&gt;, and you can very quickly start getting to grips with how the product sits within the Office 365 &amp;ldquo;ecosystem&amp;rdquo;. Practice licensing users, configuring security group level access to your D365E trial tenant and modify the details on Office 365 user accounts to see how these details are synced through into D365E. &lt;a class="link" href="https://mva.microsoft.com/product-training/office-365#!index=2&amp;amp;lang=1033" target="_blank" rel="noopener"
&gt;The Microsoft Virtual Academy also has a number of general courses related to Office 365&lt;/a&gt; however, due to the frequent updates, it may not always be in-line with the current version. &lt;a class="link" href="https://www.microsoft.com/en-gb/learning/mcsa-office365-certification.aspx" target="_blank" rel="noopener"
&gt;The official curriculum/certification paths for Office 365&lt;/a&gt; may also suffer the same from this but are worthwhile in demonstrating your experience and ability to integrate D365E with the various related Office 365 services.&lt;/p&gt;
&lt;h2 id="active-directory"&gt;Active Directory
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;What is it? :&lt;/strong&gt; For the rookie, intermediate and experienced IT admins, Active Directory needs no introduction. It is essentially Microsoft&amp;rsquo;s implementation of the Lightweight Directory Access Protocol (LDAP), having first being introduced in Windows Server 2000, providing a means of managing user, security and access rights for domain objects. There are now two distinct versions of Active Directory that are available - the more traditional, Windows server based, on-premise Active Directory and Azure Active Directory, which is utilised primarily by Office 365.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why Knowing It Is Useful:&lt;/strong&gt; User account records for both On-Premise and Online versions of CRM/D365E use Active Directory objects, with a number of important information synchronised between an Active Directory user and the equivalent User entity record. For example, &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/hh670617.aspx#data_sync" target="_blank" rel="noopener"
&gt;as indicated in this MSDN article&lt;/a&gt;, the only way in which you can synchronise a user&amp;rsquo;s Job Title through to CRM/D365E is by updating the equivalent field on the Azure Active Directory. Active Directory objects are also the only way in which you can authenticate with the application via the Web Interface or other means, with no option to create a database user or other kind of authenticated user type.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Area of Study:&lt;/strong&gt; &lt;a class="link" href="https://azure.microsoft.com/en-gb/pricing/details/active-directory/" target="_blank" rel="noopener"
&gt;It&amp;rsquo;s free to set up your own Azure Active Directory&lt;/a&gt;, so this is an excellent starting point for getting to grips with the technology. There&amp;rsquo;s also nothing preventing you from downloading a trial of Windows Server and installing the Active Directory server role on this machine. Once configured, you can then start to create users, update attributes, configure permissions and setup roles that contain collections of privileges. If you already have an Office 365 tenant with CRM/D365E Online, then you can use the Office 365 portal to manage your user accounts and test the synchronisation of attribute values from the Active Directory through to the application.&lt;/p&gt;
&lt;h2 id="powershell"&gt;PowerShell
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt; : A good way to remember what PowerShell is that it is essentially a blue command prompt window 🙂 . Traditionally only being relevant and important for those working extensively with Windows Server or Exchange, PowerShell is now increasingly important as part of administrating on-premise CRM/D365E, Office 365 and Azure, to name a few. Indeed, one of the major shock announcements this year was that &lt;a class="link" href="https://azure.microsoft.com/en-gb/blog/powershell-is-open-sourced-and-is-available-on-linux/" target="_blank" rel="noopener"
&gt;PowerShell became open sourced and can be installed on Linux&lt;/a&gt;; representing the increasing demand and importance of Linux-based resources within the Microsoft cloud.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why Knowing It is Useful:&lt;/strong&gt; Similar to SQL Server, PowerShell is something that is instantly more applicable for on-premise CRM/D365E deployments. For example, the only way to modify the default number of Dashboard items is via executing the &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/dn833084%28v=crm.7%29.aspx" target="_blank" rel="noopener"
&gt;Get-CRMSetting cmdlet&lt;/a&gt; against your on-premise organisation. I would also, again, argue having a general awareness of PowerShell can help greatly when performing administration work against an Office 365 tenant that contains a CRM/D365E organisation, such as user provisioning or license assignment. If you are utilising the Azure Service Bus to integrate CRM/D365E for Azure-based applications, then PowerShell immediately becomes a desirable skill to have in your arsenal, allowing you to remotely administer, deploy or update Azure resources programmatically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Area of Study&lt;/strong&gt;: The fact that PowerShell is now open sourced means that there is a plethora of online tools and guides to refer to, and you can be assured that you can get it working on your platform of choice. &lt;a class="link" href="https://github.com/PowerShell/PowerShell" target="_blank" rel="noopener"
&gt;The GitHub page for PowerShell is a great place to get started&lt;/a&gt;. Beyond that, you have a few options about how you can practice further. If you have spun up a D365E trial, then you can choose to &lt;a class="link" href="https://technet.microsoft.com/en-gb/library/dn975125.aspx" target="_blank" rel="noopener"
&gt;hook up PowerShell to Office 365&lt;/a&gt; to see what you can do from a remote management perspective (&lt;a class="link" href="/grant-send-on-behalf-permissions-for-shared-mailbox-exchange-online" &gt;such as granting Send On Behalf permissions for a shared mailbox&lt;/a&gt;). Alternatively, you can run it from your local Windows machine, connect it up to a Windows Server instance or attempt to create new services in Azure and experiment that way.&lt;/p&gt;</description></item><item><title>Beware the AliasedValue Attribute (Dynamics CRM)</title><link>/beware-the-aliasedvalue-attribute-dynamics-crm/</link><pubDate>Sun, 04 Sep 2016 00:00:00 +0000</pubDate><guid>/beware-the-aliasedvalue-attribute-dynamics-crm/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Beware the AliasedValue Attribute (Dynamics CRM)" /&gt;&lt;p&gt;I was writing some code recently for a CRM plugin, that involved working with multiple link entity attributes as part of a QueryExpression. Accomplishing this is relatively straightforward, thanks to some of the code samples provided within the SDK. For example, &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg328149.aspx" target="_blank" rel="noopener"
&gt;the following sample code&lt;/a&gt; gives you everything you would need; how to build the query and, more importantly, include the attributes you would need to return as part of the request:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Create a query expression specifying the link entity alias and the columns of the link entity that you want to return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;QueryExpression&lt;/span&gt; &lt;span class="n"&gt;qe&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QueryExpression&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EntityName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LinkEntities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;LinkEntity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;primarycontactid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;contactid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;JoinOperator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LinkEntities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddColumns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LinkEntities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;EntityAlias&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;primarycontact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;EntityCollection&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_orgService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetrieveMultiple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qe&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Retrieved {0} entities&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;account name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primary contact first name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primary contact last name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Very handy! But there are two problems that you may encounter when attempting to run the code yourself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The code snippet attempts to print out the value of the LinkEntity First Name and Last Name Contact fields to the console. So, for example, when your code retrieves the &lt;strong&gt;Fourth Coffee (sample)&lt;/strong&gt; record, we would expect to see &lt;strong&gt;Rene Valdes (sample)&lt;/strong&gt; printed out. Unfortunately, this doesn&amp;rsquo;t happen, and we are instead greeted with a value that may precipitate some serious head-scratching:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="/images/Windows-CommandLine-AliasedValueExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The issue lies in how the SDK handles link-entity attributes included as part of a query. Instead of returning the value in the data type we would expect and, despite appending the appropriate namespace within our code to indicate the link entity our attribute is from (in this case, &lt;strong&gt;primarycontact&lt;/strong&gt;), CRM instead gives us the attribute as part of an &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/microsoft.xrm.sdk.aliasedvalue.aspx" target="_blank" rel="noopener"
&gt;AliasedValue&lt;/a&gt; object. The comforting thing to know is that the attribute value that we may (desperately!) want to grab is in this object somewhere, and we will look at the best way of accessing this later on in this post.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Putting aside the above issue, let&amp;rsquo;s assume that we weren&amp;rsquo;t working with an AliasedValue and just a standard CRM data type - for example, Single Line of Text/string. Our above code would work fine against all of the sample data records within CRM. But if we add a new Account record and add a Primary Contact record that doesn&amp;rsquo;t have a &lt;strong&gt;First Name&lt;/strong&gt; value, we get an error thrown within our code when it attempts to output this value into the console:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-KeyNotFoundException.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Regular readers of the blog may be able to guess what is happening - &lt;a class="link" href="/the-benefits-of-using-getattributevalue-to-access-crm-attributes-late-bound-c" &gt;as part of one of my previous posts looking at the GetAttributeValue method&lt;/a&gt;, we looked at the danger of accessing attributes via the &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/microsoft.xrm.sdk.entity.aspx" target="_blank" rel="noopener"
&gt;Entity class&lt;/a&gt;, particularly when these attributes may end up containing blank values. In this particular example, there is another factor at play too - when a QueryExpression attempts to bring back all of the requested attributes, any attribute(s) that do not contain a value in the CRM database (i.e. are NULL) are not returned at all. This fact is useful in ensuring that our code can run as optimally as possible, but in this case, is our downfall - because our Entity object has no Contact attribute with a First Name value, no value is available to return, so our code panics and throws an error; for the simple reason that it is attempting to access something that does not exist.&lt;/p&gt;
&lt;p&gt;So how can we get around both of these issues? First of all, we need to alter the code so that the actual value of the &lt;strong&gt;First Name&lt;/strong&gt; and &lt;strong&gt;Last Name&lt;/strong&gt; fields are displayed correctly. One way of executing this is to explicitly cast our attribute values as AliasedValues, access the inner properties of the object and then cast to string the value of the attribute. An updated version of our code would, therefore, look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;account name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primary contact first name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;AliasedValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primary contact last name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;AliasedValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running this against our Sample Account/Contact results returns what we expect, which is good 🙂&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/Windows-CommandLine-AliasedValueToStringExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;But, unfortunately, does not give us a complete solution to the above as we still hit a &amp;ldquo;The given key was not present in the dictionary.&amp;rdquo; error message as before, for the same reasons:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-AliasedValueToStringKeyNotFoundException.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The above method is not satisfactory then, as we would need to include additional lines of code to handle the fact that the attribute value is not present - an &lt;strong&gt;if&amp;hellip;else&lt;/strong&gt; statement or a &lt;strong&gt;try&amp;hellip;catch&lt;/strong&gt; block. If we forget to put this in, then another issue surfaces in bad code potentially seeping into a Production environment - causing errors for end-users and hours of unnecessary debugging.&lt;/p&gt;
&lt;p&gt;Our old friend GetAttributeValue has saved the day for us previously; can it do again? We can try by using the code snippet below - specifying the fact that we are returning an AliasedValue object and then getting the inner attribute Value:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;account name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primary contact first name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AliasedValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primary contact last name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AliasedValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The code errors again, unfortunately, with a different error message, indicating that a NULL value is attempting to be accessed:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-AliasedValueNullReferenceException.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;In this case, we must rely on our knowledge of C# to save the day, with a few options at our disposal. I&amp;rsquo;ve already suggested two possible options, but another could be considered, which would reduce the number of lines in our code. By using the &lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/ty67wk28.aspx" target="_blank" rel="noopener"
&gt;conditional operator (?:)&lt;/a&gt;, we can &amp;ldquo;test&amp;rdquo; for a NULL value in our GetAttributeValue and, if a NULL value is present, substitute it for an empty string or a value of our choice. Our final, error-free code, would look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;account name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primary contact first name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AliasedValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AliasedValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primary contact last name:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AliasedValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AliasedValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;primarycontact.lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, just to be sure, we run a quick test and confirm everything works as expected:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/Windows-CommandLine-AliasedValueWorkingExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Now we can rejoice that our code is error free and that we&amp;rsquo;ve found another good example of how the GetAttributeValue method should always be used when working with CRM attributes. It is a shame though that the code above, provided by Microsoft as part of the SDK, has such a significant error within it. Hopefully, it will be addressed as part of a future version of the SDK and we should be thankful that we at least have all of the sample code in the SDK in the first place; it gives developers and CRM customisers a great starting point to start developing consistent and supported code.&lt;/p&gt;</description></item><item><title>What's the best way of learning CRM Development?</title><link>/whats-the-best-way-of-learning-crm-development/</link><pubDate>Sun, 28 Aug 2016 00:00:00 +0000</pubDate><guid>/whats-the-best-way-of-learning-crm-development/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post What's the best way of learning CRM Development?" /&gt;&lt;p&gt;A colleague recently asked me this question, and I&amp;rsquo;ll admit that it took me a few minutes to think about the answer. Learning how to write code that extends functionality within or outside of CRM is not something that you can just pick up from scratch. You usually need to have good experience with coding first, before you can safely venture into writing your first plugin or form level JScript function. Fundamental, and arguably, crucial knowledge of the CRM platform is essential too, as this ensures that you don&amp;rsquo;t put forward solutions that the application can handle natively. In this week&amp;rsquo;s blog post, I will first clarify what CRM Development actually means, before outlining  my &amp;ldquo;top tips&amp;rdquo; on how you can develop your skills to become a superstar CRM Developer.&lt;/p&gt;
&lt;h2 id="so-what-iscrm-development-and-is-it-the-same-as-crm-customisation"&gt;So what is CRM Development, and is it the same as CRM Customisation?
&lt;/h2&gt;&lt;p&gt;It&amp;rsquo;s important that we first clarify what the difference is between these two types of activities, as although there is some cross-over, often they are split out into two distinct roles - a CRM Customiser and CRM Developer. Someone who occupies the first of these roles frequently spends the majority of their time working with CRM Solutions and the Customizations area of CRM. Customisers will commonly be involved in the creation of new entities, fields, system views, processes, business rule &amp;amp; workflows, to name a few. As a consequence, they will more often than not have a great deal knowledge of what the platform is capable of and are generally in the best position to offer support and mentoring to colleagues who are struggling with something in CRM (for example, how to create a personal view).&lt;/p&gt;
&lt;p&gt;In comparison, a CRM Developer may spend very little time working with solutions and customisations; although they will be expected to have a general awareness of what the platform is capable of doing,  they will mostly only ever be concerned with modifying plug-ins, plug-in steps and web resources from within solutions. CRM Development instead encompasses a broad canvas of work, all of which is geared towards extending the native functionality of the application. An example list may include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing form level JScript, for scenarios where a Business Rule can&amp;rsquo;t achieve the desired results (&lt;a class="link" href="/why-crm-developers-should-use-business-rules-more" &gt;we&amp;rsquo;ve already learned the importance of considering Business Rules as a first step option in these scenarios&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Developing custom plug-ins in C#/VB.NET to execute at specific trigger points within the underlying database transaction e.g. after a Contact record has been updated.&lt;/li&gt;
&lt;li&gt;Building custom workflow assemblies in C#/VB.NET to further enhance the options available as part of a workflow or dialog.&lt;/li&gt;
&lt;li&gt;Setting up custom Web Resources in HTML/Silverlight, that can be embedded within CRM forms or dashboards.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A good way of remembering the difference is to remember that CRM Customisation can all be done from within the application itself, whereas CRM Development involves work created outside the application to achieve specific business requirements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now that we&amp;rsquo;ve got that out of the way, here&amp;rsquo;s my top 5 list on how you can learn CRM Development:&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="learn-c-first"&gt;Learn C# First
&lt;/h2&gt;&lt;p&gt;As well as providing you with everything you would ever need from a plug-in/custom workflow development perspective, having a good grasp of C# can make learning JScript a lot more easier. Both languages have a lot of similarity, with some important differences that require noting. First, JScript is largely indifferent when it comes to working with data types, whereas C# is very fussy when it comes to declaring and casting your data types correctly. Secondly, whereas C# development work can be assisted via the use of early-bound class files, JScript can be annoyingly unsympathetic when you write code, with errors only cropping up when you attempt to run your code. Putting aside these differences though, being able to say that you have a good grasp of C# on your C.V. can assist greatly when seeking out roles involving CRM, particularly given such roles will be looking for experience of integrating CRM with third party applications; C# is your Swiss army knife in these situations.&lt;/p&gt;
&lt;h2 id="the-sdk-is-your-treasure-trove"&gt;The SDK is your treasure trove.
&lt;/h2&gt;&lt;p&gt;There are countless number of code examples &amp;amp; snippets enclosed within the SDK, which include all of the languages that you would use to extend CRM - JScript, C# and even VB.NET! These are typically in a state where you can easily deploy them to a test CRM environment, execute them and then playback within Visual Studio via the &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/hh372952.aspx" target="_blank" rel="noopener"
&gt;Plugin Profiler&lt;/a&gt;, so you can understand what they are doing.  The enclosed help file (which is replicated fully on the MSDN website) is also really detailed in explaining what you can do when developing for CRM. You can download the latest version of the SDK (updated recently for the 2016 Spring Wave) &lt;a class="link" href="https://www.microsoft.com/en-us/download/details.aspx?id=50032" target="_blank" rel="noopener"
&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="get-an-msdn-subscription"&gt;Get an MSDN Subscription
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="/utilising-prepost-entity-images-in-a-dynamics-crm-plugin" &gt;I have extolled the virtues of what an MSDN subscription can provide to Microsoft professionals previously&lt;/a&gt;, so I won&amp;rsquo;t cover old ground. What I will highlight from this is that the Imagine Academy, included as part of a subscription, contains nearly all of the courses found on the Dynamics Learning Portal (available to CRM partners as a learning resource &amp;ldquo;hub&amp;rdquo; for all Dynamics products). It also gives you access to a number of important, developer-focused resources that you add to your arsenal and use to further enhance your knowledge of C#, JScript etc. If you&amp;rsquo;re fortunate enough to have enough money to obtain an Enterprise MSDN Subscription, or your employer has a few spare licenses, then you will be able to get your hands on a coveted CRM On-Premise license key as well. Working with the application in whatever capacity you can is the best and surest way to learn, as opposed to simply watching videos and reading online articles.&lt;/p&gt;
&lt;h2 id="pass-those-exams"&gt;Pass those Exams
&lt;/h2&gt;&lt;p&gt;There are a wide plethora of different CRM exams available to take currently, and it can be quite confusing deciding which ones will benefit you best on your road to become a CRM Developer. I would suggest that the best exams to target a passing mark on would be the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.microsoft.com/en-sg/learning/exam-MB2-712.aspx" target="_blank" rel="noopener"
&gt;MB2-712: Microsoft Dynamics CRM 2016 Customization and Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.microsoft.com/en-gb/learning/exam-mb2-701.aspx" target="_blank" rel="noopener"
&gt;MB2-701: Extending Microsoft Dynamics CRM 2013&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The question you may be asking though is &amp;ldquo;How important are exams, compared with actual work experience?&amp;quot;. I have heard many debates surrounding the importance of certification, on both sides of the argument; one criticism is that they are generally not a good way equipping candidates with the practical, real-life knowledge and experience that ultimately must come to the fore when working with CRM on a day-to-day basis. Another argument against them is that they can sometimes draw you towards focusing on features of a particular application that is either not very good or is done much better by an alternative product. Notwithstanding this, I think exams hold an important place in demonstrating to colleagues and potential recruiters just how serious you are about your career and in ensuring that you keep yourself up-to-date with the appropriate technology - in these modern times, staying off the ball for as little as a month can put you behind! Going back to the original purpose of this post, the curriculum on both of these exams will leave you in a position where you have achieved a good balance of knowledge: both of what CRM, as a platform, is capable of out of the box, and what you can do to develop further solutions for the application.&lt;/p&gt;
&lt;h2 id="and-finally-believe-in-yourself"&gt;And finally, believe in yourself
&lt;/h2&gt;&lt;p&gt;This last tip may sound a little bit clichéd, but achieving your desire to become good at CRM Development is something that only you have control over. The journey may be hard, and you will often fail more than you succeed at first; but if you keep working at it, never give up and, most importantly, trust in yourself and your abilities, then you will succeed in increasing your knowledge and expertise in CRM.&lt;/p&gt;</description></item><item><title>Utilising Pre/Post Entity Images in a Dynamics CRM Plugin</title><link>/utilising-prepost-entity-images-in-a-dynamics-crm-plugin/</link><pubDate>Sun, 21 Aug 2016 00:00:00 +0000</pubDate><guid>/utilising-prepost-entity-images-in-a-dynamics-crm-plugin/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Utilising Pre/Post Entity Images in a Dynamics CRM Plugin" /&gt;&lt;p&gt;One of the challenges when first working with CRM Plugins is understanding how the execution context works. To briefly summarise, this contains the information relating to how and when the plugin is executed. It can give you answers to some of the questions you may wish to &amp;ldquo;ask&amp;rdquo; your CRM - for example, what record has triggered this plugin? Which CRM User forced the plugin to execute? You may also assume that the context will contain all of the fields of that entity that you can then access. This is not always the case - typically, as part of an Update request, only the fields that triggered the update will be made available. Or consider an &lt;strong&gt;Associate&lt;/strong&gt;/&lt;strong&gt;Disassociate&lt;/strong&gt; request (i.e. when someone relates/unrelates two records in CRM). As part of a one-to-many (1:N) relationship, only one field has changed; so that is the only field that is contained within the execution context.&lt;/p&gt;
&lt;p&gt;The above being the case, what options do you have if you need to access fields that are not included in the context? You have two choices available to you:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg309673.aspx#bkmk_access" target="_blank" rel="noopener"
&gt;Obtain a reference to Organisation Service within your plugin&lt;/a&gt;, and then use a &lt;strong&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/microsoft.xrm.sdk.iorganizationservice.retrieve.aspx" target="_blank" rel="noopener"
&gt;Retrieve&lt;/a&gt;&lt;/strong&gt; request to return the fields you need from the plugin. As the context will always contain the GUID for the record that has changed, this is generally the most common way you will see this done.&lt;/li&gt;
&lt;li&gt;Utilise either a Pre or Post Entity Image of the record, which contains the attributes that you need to access.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the past, I would always end up going down the first route. Recently though, I have been evaluating Entity Images more and more, and have begun to actively use them as part of my plugins. Entity Images are, essentially, snapshots of the CRM record that are stored on the platform either before the database operation has completed or straight after - you can decide which one you want to use, depending on what your plugin is doing. They are configured as part of deploying your plugin to your target CRM instance, and the steps involved are actually quite simple - I think its generally the case that they are not well-understood or utilised by developers who are learning about CRM for the first time.&lt;/p&gt;
&lt;h2 id="so-why-should-you-go-to-the-extra-effort-to-use-them-within-your-plugins"&gt;So why should you go to the extra effort to use them within your plugins?
&lt;/h2&gt;&lt;p&gt;As alluded to above, using Pre Entity Images means you can get a snapshot of your CRM data &lt;em&gt;before&lt;/em&gt; the data was changed. This may prove to be particularly invaluable in cases where you need to perform a before/after comparison on a particular field, and then execute a specific action either way. The only non-entity image way of doing this within CRM would be via hidden field that stores the current value of your field in question, which is referenced and updated once your business logic has completed. A slightly in-elegant solution, and one that is questionable, given that we can utilise Entity Images instead. Having ready access to the attributes which may not necessarily be exposed to the plugin when it is executed is particularly invaluable, given that this avoids a scenario where you would have to go down option 1). Disadvantages of this approach is the potential for unnecessary delays in your plugin completing and problems with your CRM instance as a whole, if your CRM&amp;rsquo;s web services are already accessed to breaking point.&lt;/p&gt;
&lt;h2 id="there-must-be-a-catch-surely"&gt;There must be a catch, surely&amp;hellip;
&lt;/h2&gt;&lt;p&gt;On the whole, it doesn&amp;rsquo;t look like it, but you do need to aware of a few things. As you may have already guessed, if your plugin runs on the &lt;strong&gt;Create&lt;/strong&gt; message, you won&amp;rsquo;t be able to access any pre-image of the record; likewise, for &lt;strong&gt;Delete&lt;/strong&gt; message plugins, the post-image will not be available. It should be fairly obvious why this is the case. You are also restricted with the number of Messages that support Pre/Post Images. &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg309673.aspx#bkmk_preandpost" target="_blank" rel="noopener"
&gt;The full list can be found here&lt;/a&gt;, but to summarise the most important Message types, only &lt;strong&gt;Update&lt;/strong&gt;, &lt;strong&gt;Assign&lt;/strong&gt;, &lt;strong&gt;SetState&lt;/strong&gt; &amp;amp; &lt;strong&gt;Merge&lt;/strong&gt; support both Image types. Bear in mind too the additional &amp;ldquo;gotchas&amp;rdquo;, which this article touches upon. If in doubt, then boot up your sandbox CRM environment and cry havoc with your test code.&lt;/p&gt;
&lt;h2 id="lets-take-a-closer-look-at-how-pre-and-post-images-can-be-implemented-as-part-of-a-crm-plugin"&gt;Lets take a closer look at how Pre and Post Images can be implemented as part of a CRM Plugin&amp;hellip;
&lt;/h2&gt;&lt;p&gt;The below example will compare the Pre and Post Image values of the Lead Company Name field and, if they have changed, send an email message to a Sales Manager user to alert them of this fact. Be sure to add references to the Microsoft.Xrm.Sdk and Microsoft.Crm.Sdk.Proxy .dlls from the SDK:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Extract the tracing service for use in debugging sandboxed plug-ins.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TracingService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Implemented tracing service succesfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Obtain the execution context from the service provider.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Get a reference to the Organization service.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrganizationService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Confirm that Target is actually an Entity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;_userID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InitiatingUserId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Retrieve the name of the user (used later)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;systemuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_userID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ColumnSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fullname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;lead&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;preLead&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PreEntityImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Image&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;postLead&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PostEntityImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Image&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;preCompanyName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;preLead&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;companyname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;postCompanyName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;postLead&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;companyname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Pre-Company Name: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;preCompanyName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; Post-Company Name: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;postCompanyName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preCompanyName&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;postCompanyName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Pre-Company Name does not match Post-Company Name, alerting sales manager...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Queue ID for our Sales Manager&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;_salesManagerQueueID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;41b22ba9-c866-e611-80c9-00155d02dd0d&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;fromParty&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;activityparty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;toParty&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;activityparty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Email body text is in HTML&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;emailBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;lt;html lang=&amp;#39;en&amp;#39;&amp;gt;&amp;lt;head&amp;gt;&amp;lt;meta charset=&amp;#39;UTF-8&amp;#39;&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;Hello,&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Please be advised that I have just changed the Company Name of a Lead record in CRM:&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Lead Record URL: &amp;lt;a href=&amp;#39;http://mycrm/MyCrmInstance/main.aspx?etn=lead&amp;amp;pagetype=entityrecord&amp;amp;id=%7B&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;%7D&amp;#39;&amp;gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;postCompanyName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Old Company Name Value: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;preCompanyName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;New Company Name Value: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;postCompanyName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;Kind Regards&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;fromParty&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;partyid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;systemuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_userID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;toParty&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;partyid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;queue&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_salesManagerQueueID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;email&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;from&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fromParty&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;to&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;toParty&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Lead Company Name Changed&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;directioncode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emailBody&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//This bit just creates the e-mail record and gives us the GUID for the new record...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;_emailID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Email record &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;_emailID&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; succesfully created.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//...to actually send it, we need to use SendEmailRequest &amp;amp; SendEmailResponse, using the _emailID to reference the record&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SendEmailRequest&lt;/span&gt; &lt;span class="n"&gt;sendEmailreq&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SendEmailRequest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;EmailId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_emailID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;TrackingToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IssueSend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SendEmailResponse&lt;/span&gt; &lt;span class="n"&gt;sendEmailResp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SendEmailResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sendEmailreq&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Email record &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;_emailID&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; queued succesfully.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Company Name does not appear to have changed, is this correct?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Ending plugin execution.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once we have written our code and built our solution, we deploy our plugin in the normal way via the Plugin Registration Tool - ensuring that we configure our step to fire on the correct message:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolImages.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Next, we need to configure our Pre/Post Images manually. Just because we have referenced them in our code above doesn&amp;rsquo;t mean they will automatically become available to us as our plugin is executed. Fortunately, adding them on is not too difficult and we can do it directly within the Plugin Registration Tool. First, highlight our new plugin step and select &lt;strong&gt;Register New Image&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolRegisterNewImage.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;One good thing about this is that we can configure both our Pre and Post Images in the one screen. We just confirm that our intended plugin step is selected, tick both of the boxes and ensure that the following details are completed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: Specify a name for this image. This can be anything you want it to be, but I would recommend using the same value as &lt;strong&gt;Entity Alias&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entity Alias&lt;/strong&gt;: This is the name that is used in our code above to reference the image. This must match exactly against this in order for the code to work correctly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parameters&lt;/strong&gt;: Here you specify which attributes will be made available within the image. By default, all attributes are included, but you should specify only the attributes you need to work with in your plugin. For our example plugin, we only need the Company Name field, so this is the only attribute we will select.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your settings should look something like the below:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-SDK-PluginRegistrationToolPrePostImage.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;With everything setup, we can now test our plugin. In this case, I have changed one of the sample data leads to force the plugin to execute:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-PrePostImageSampleBefore.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-PrePostImageSampleAfter.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;We can then see that our Email record is successfully created, which is able to reference the value of the Company Name field before the change:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-PrePostImageEmailSample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Playing back the plugin within Visual Studio demonstrates that our Pre and Post images are Entity objects, meaning that we can interact with them the usual way - nothing new to learn or master, which is good 🙂&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-D365PreImage.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="conclusions---or-wot-i-think"&gt;Conclusions - or Wot I Think
&lt;/h2&gt;&lt;p&gt;Like most things with CRM, Entity Images have a time and place. If you have a desire to query additional data concerning record relationship attributes etc. as part of your plugin, then a &lt;strong&gt;Retrieve&lt;/strong&gt; request is still going to be the only way you can accomplish this. There is also some additional administrative head-room required when working with Images - if, for example, you forget to specify your Pre &amp;amp; Post Images when deploying your plugin, then you are going to encounter immediate problems within your CRM. Having said that, I think there is an excellent case to be made to using Entity Images as much as feasibly possible in your code. A Retrieve request on a particular busy CRM platform just to return one attribute value could store up problems for your CRM instance in the long-haul; having this one value stored as part of an entity Image seems a much more sensible and logical approach. I am further struck by how useful entity images can be if you need to reference data changes before and after a record change - going back to our example above, where we would instead look at creating custom field within CRM to store this value, having it made available as part of an Entity Image could score a major time saving. Finally, you are not just restricted to using the one Pre/Post Image - you can setup multiple ones that contain different fields from your entity, that are accessed in different parts of your code, depending on your logic. I think developers working with CRM definitely owe it to themselves to check out Entity Images at least once - I think they will be pleasantly surprised at their capabilities and, one would hope, the increased performance of their CRM instance as a consequence of using them!&lt;/p&gt;</description></item><item><title>The Benefits of Using GetAttributeValue to Access CRM Attributes (Late-Bound, C#)</title><link>/the-benefits-of-using-getattributevalue-to-access-crm-attributes-late-bound-c/</link><pubDate>Sun, 14 Aug 2016 00:00:00 +0000</pubDate><guid>/the-benefits-of-using-getattributevalue-to-access-crm-attributes-late-bound-c/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post The Benefits of Using GetAttributeValue to Access CRM Attributes (Late-Bound, C#)" /&gt;&lt;p&gt;When you first begin working with the Dynamics CRM SDK, there is a lot of specific terminology, concepts and methods that need to be grasped firmly. The importance of this is twofold: it enables you to judge the best approach when developing your bespoke solution that fits in within CRM and allows you to gain a very good understanding of the underlying CRM platform. The terms &amp;ldquo;early-bound&amp;rdquo; and &amp;ldquo;late-bound&amp;rdquo; are, arguably, the most important of these terms/concepts to fully understand, so it is useful to first explain what each of these refer to and the benefits &amp;amp; drawbacks of each, before we get into this weeks blog post properly:&lt;/p&gt;
&lt;h2 id="early-bound"&gt;Early Bound
&lt;/h2&gt;&lt;p&gt;Early bound refers to when you are using a generated class file to access all of the customization data for your CRM within your code. The SDK Bin folder contains an executable file called &lt;strong&gt;CrmSvcUtil&lt;/strong&gt;, which can be used to generate this file. &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg327844.aspx" target="_blank" rel="noopener"
&gt;There is a great MSDN article that goes through the steps involved as part of this&lt;/a&gt;; once you&amp;rsquo;ve got the file, simply add it into your Visual Studio project and Intellisense will automatically detect your entity, relationship etc. names! Suffice to say, going down the early bound route can significantly ease your development work, as your strongly-typed class file will contain &lt;em&gt;everything&lt;/em&gt; you would require regarding your CRM entities. As such, you will be able to ensure that your code is accessing the correct attributes, relationships and other objects within CRM at all times.&lt;/p&gt;
&lt;p&gt;Given that it makes a developers jobs ten times easier, why wouldn&amp;rsquo;t you want to use Early Bound in your code all the time? Your strongly-typed class file is essentially a snapshot of your current CRM instance, at the date and time when you ran the &lt;strong&gt;CrmSvcUtil&lt;/strong&gt;. As soon as someone makes a change within CRM, your class file may no longer be correct and you may encounter major problems when executing your code against your target CRM environment. This problem can also be compounded if you are developing an ISV solution that is executed against a varied number of environments, where there could be entities/attributes present that your code has no reasonable way to anticipate; in this case, it becomes absolutely essential for you to consider using late-binding instead within your code.&lt;/p&gt;
&lt;h2 id="late-bound"&gt;Late Bound
&lt;/h2&gt;&lt;p&gt;Late binding is the exact opposite of early binding. To access your CRM entities via the late-bound route, you use the &lt;strong&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-gb/library/microsoft.xrm.sdk.entity.aspx" target="_blank" rel="noopener"
&gt;Microsoft.Xrm.Sdk.Entity&lt;/a&gt;&lt;/strong&gt; class to declare the new or existing entity that you wish to work with within your code. Typically, you will need to have your CRM Solution open in front of you as part of using late-binding, so that you can reference the logical names of your entities &amp;amp; attributes. You are therefore not &amp;ldquo;restricted&amp;rdquo; in the same way that you are with early-binding - you can declare any possible logical name for your CRM objects that you want, which, as mentioned already, is essential if you are blind to the CRM instance(s) in question. There is also a performance benefit to using the late-bound Entiy class, depending on the number of records your code is working with. &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg509027.aspx" target="_blank" rel="noopener"
&gt;According to the following Microsoft best practice article&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In addition, if your custom code works with thousands of entity records, use of the &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.entity.aspx" target="_blank" rel="noopener"
&gt;Entity&lt;/a&gt; class results in slightly better performance than the early-bound entity types.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the major drawbacks of using late binding is the increased chance of errors in your code, as you will need to ensure that your logical names are typed correctly; any such mistakes, as we will demonstrate further below, may cause your code to fall over straight away and lead to hours of frustrating debugging in order to resolve.&lt;/p&gt;
&lt;h2 id="now-to-the-heart-of-the-matter"&gt;Now, to the heart of the matter&amp;hellip;
&lt;/h2&gt;&lt;p&gt;I recently had a conversation with a developer colleague, who gave me some advice in relation to some plugin code I had written. Within my code, I had attempted to access the value of a Single Line of Text Entity attribute, using late-bound classes, in the following manner:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;myAttribute&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myEntity&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;myattribute&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;They recommended instead that I look at using the &lt;strong&gt;&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg326129.aspx" target="_blank" rel="noopener"
&gt;GetAttributeValue&lt;/a&gt;&lt;/strong&gt; method instead, which in this case, would be expressed in the following manner&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;myAttribute&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myEntity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;myattribute&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My colleague elaborated on a few reasons why this approach is preferential (which I will discuss at the end of this post), but I was interested in dissecting this further myself, to see how it works in practice. In my test CRM instance, I created a plugin for the Contact entity, that would fire on the Post-Operation event of the Update Message, for the First Name field. The plugin very simply accesses the value of this field using the two different approaches, which can be done like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//First, initialize your Contact entity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Now we can access our attributes - the first way is like this...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;contactField1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//The second way...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;contactField2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we play back the plugin execution in Visual Studio, we can see that this returns our expected values. In this particular example, we have attempted to rename our &amp;ldquo;Homer Simpson&amp;rdquo; Contact record to &amp;ldquo;Bart Simpson&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-D365LateBoundExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-D365GetAttributeValueExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;So, at this stage, there does not appear to be a clear benefit of using one snippet over the other. But what happens if we attempt to access an attribute that does not exist? We can test this by adding the following lines of code to our plugin:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Next, we test what happens if there is a typo - first, we try GetAttributeValue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;contactField3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;thiswillerror&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Then, the alternate way&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;contactField4&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;thiswillerror&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we use our &lt;strong&gt;GetAttributeValue&lt;/strong&gt; approach, our contactField3 returns a null value&amp;hellip; :&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-D365GetAttributeValueNullExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Whereas our contactField4 instantly causes an error, which would also be returned to the user within CRM&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/VisualStudio-CSharp-D365LateBoundNullExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Where possible, we always want to try and prevent an Exception from being passed back to CRM and build in the appropriate error handling within our code, and this was one of the benefits that my colleague highlighted in this approach. So, for example, you can build in an &lt;strong&gt;if&amp;hellip;else&lt;/strong&gt; statement as part of the above example that checks whether the &lt;strong&gt;GetAttributeValue&lt;/strong&gt; is Null and then perform the appropriate action, depending on the result. Having spent time working with the method more closely, I can also now see a clear benefit in relation to code readability - it is definitely more obvious what &lt;strong&gt;GetAttributeValue&lt;/strong&gt; is doing within a code example, compared with the alternative approach, as well as making it obvious what the data type of the attribute is within CRM. Keep in mind however that you still need to ensure that you are using your correct Data Types, both when creating your C# variables and referencing your CRM attributes - for example, you cannot return the contactid field as a string, as this will generate an &lt;strong&gt;InvalidCastException&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To finish off, &lt;a class="link" href="http://www.crmanswers.net/2015/04/getattributevalue-demystified.html" target="_blank" rel="noopener"
&gt;I would invite you to look through this excellent article from Guido Preite&lt;/a&gt;, that takes a deep-dive look at the &lt;strong&gt;GetAttributeValue&lt;/strong&gt; method in a variety of different scenarios. Definitely one to save to your bookmarks 🙂&lt;/p&gt;</description></item><item><title>Implementing Tracing in your CRM Plug-ins</title><link>/implementing-tracing-in-your-crm-plug-ins/</link><pubDate>Sun, 31 Jul 2016 00:00:00 +0000</pubDate><guid>/implementing-tracing-in-your-crm-plug-ins/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Implementing Tracing in your CRM Plug-ins" /&gt;&lt;p&gt;The ability to implement trace logging within CRM plug-ins has been around since CRM 2011, so it&amp;rsquo;s something that CRM developers should be well aware of. Writing to the trace log is useful for when a plug-in has failed or hit an exception, as within the ErrorDetails.txt file (available to download from the error message box window) will be a list of everything that has been written to the log, up to that point. One issue with this is, if a user encounters an error and does not choose to download this file, then this file is lost - not so much of an issue if the exception can be re-produced, but this may not always the case.&lt;/p&gt;
&lt;p&gt;For those who are now working on CRM Online 2015 Update 1 or CRM 2016, then a new feature has been added which further expands this feature - the &lt;strong&gt;Plug-in Trace Log&lt;/strong&gt;. Now, plug-in exceptions can be configured to write to a new system entity, containing full details of the exception, that can be accessed at any time in order to support retroactive debugging. The introduction of this feature means now is the best time to start using trace logging within your plugins, if you are not already. This weeks blog post will take a look at the feature in more detail, assessing its pros &amp;amp; cons and providing an example of how it works in practice.&lt;/p&gt;
&lt;h2 id="so-before-we-begin-why-you-would-want-to-implement-tracing-in-the-first-place"&gt;So, before we begin, why you would want to implement tracing in the first place?
&lt;/h2&gt;&lt;p&gt;Using tracing as part of CRM Online deployments makes sense, given that your options from a debugging point of view are restricted compared to an On-Premise Deployment. It is also, potentially, a lot more straightforward then using the Plug-in Registration Tool to debug your plugins after the event, particularly if you do not have ready access to the SDK or to Visual Studio. Tracing is also useful in providing a degree of debugging from within CRM itself, by posting either your own custom error messages or feeding actual error messages through to the tracing service.&lt;/p&gt;
&lt;h2 id="just-remember-the-following"&gt;Just remember the following&amp;hellip;
&lt;/h2&gt;&lt;p&gt;Writing to the tracing service does add an extra step that your plug-in has to overcome. Not so much of an issue if your plugin is relatively small, but the longer it gets, and more frequent you are writing to the service, means there is a potential performance impact. You should use your best judgement when writing to the service; not &lt;em&gt;every&lt;/em&gt; time you do something within the plugin, but where there is a potential for an error to occur. Writing to the tracing log can also have an impact on your CRM storage capacity, something we will take a look at later on in this post.&lt;/p&gt;
&lt;h2 id="now-that-we-have-got-that-out-of-the-way-lets-begin-by-setting-up-an-example-plugin"&gt;Now that we have got that out of the way, lets begin by setting up an example plugin!
&lt;/h2&gt;&lt;p&gt;To start writing to the Tracing service depends on how you are implementing your plugin. If you have used the Visual Studio template, then simply use this line of code within the &amp;ldquo;TODO: Implement your custom Plug-In business logic.&amp;rdquo; section:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TracingService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Otherwise, you will need to ensure that your plugin is calling the IServiceProvider, and then use a slightly longer code snippet to implement the service. An example of the code that you&amp;rsquo;d need to use to setup this is as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;//Be sure to add references to Microsoft.Xrm.Sdk in order to use this namespace!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Xrm.Sdk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyPluginProject&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyPlugin&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPlugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Extract the tracing service for use in debugging sandboxed plug-ins. &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITracingService&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once you&amp;rsquo;ve implemented the ITracingService within your code, you can then write to Trace Log at any time in your code using the following snippet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Insert your text here...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="activating-tracing"&gt;Activating Tracing
&lt;/h2&gt;&lt;p&gt;Even though we have configured our plugin for tracing, this does not automatically mean that our plugin will start writing to the log. First, we must configure the &lt;strong&gt;Plug-in and custom workflow activity tracing&lt;/strong&gt; setting within the System Settings page:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-EnableTraceLogging.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;You have three options that you can set:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Off - Nothing will be written to the trace log, even if the plugin encounters an exception.&lt;/li&gt;
&lt;li&gt;Exception - When the plugin hits an exception, then a trace will be written to the log.&lt;/li&gt;
&lt;li&gt;All - Whenever the plugin is executed and the trace log is called, then a trace log record will be created. This is equivalent to Verbose logging.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As mentioned earlier, individual records will be written to CRM whenever the tracing service is called. It is therefore recommended only to turn on &amp;lsquo;All&amp;rsquo; for temporary periods; leaving it on for &amp;lsquo;Exception&amp;rsquo; may be useful when attempting to initially diagnose plugin errors. Review the amount of storage available to you on your CRM Online/On-Premise deployment in order to determine the best course of action.&lt;/p&gt;
&lt;h2 id="tracing-in-practice"&gt;Tracing in Practice
&lt;/h2&gt;&lt;p&gt;Now that we&amp;rsquo;ve configured tracing on our CRM and we know how to use the Tracing, lets take a look at an example plugin. The below plugin will be set to fire on the Post-Operation event of the Update message on the Account entity. It will create a new contact record, associate this Contact record to the Account and then populate the Description field on the Contact with some information from the Account record:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;ExecutePostAccountUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LocalPluginContext&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;localContext&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;localContext&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Extract the tracing service for use in debugging sandboxed plug-ins.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ITracingService&lt;/span&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TracingService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Implemented tracing service succesfully!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Obtain the execution context from the service provider.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IPluginExecutionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PluginExecutionContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Get a reference to the Organization service.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IOrganizationService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;localContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrganizationService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Confirm that Target is actually an Entity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;contactID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InputParameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Target&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Succesfully obtained Account record&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Attempting to obtain Phone value...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;telephone1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Failed to obtain Phone field. Error Details: &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;InvalidPluginExecutionException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;A problem has occurred. Please press OK to continue using the application.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//Build our contact record to create.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;contact&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Ned&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;lastname&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Flanders&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;parentcustomerid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EntityReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Ned&amp;#39;s work number is &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;contactID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Succesfully created Contact record &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;contactID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Done!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tracingService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Phone number was empty, Contact record was not created.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After registering our plugin and with tracing configured for &amp;ldquo;All&amp;rdquo; in our CRM instance, we can now see our custom messages are being written to the Trace Log - when we both update the A. Datum Corporation (sample) record Phone field to a new value and when we clear the field value:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-TracingPluginExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-TracingPluginTraceLogExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-TracingPluginTraceLogAdditionalExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Most importantly, we can also see that our test Contact record is being created successfully when we populate the Phone field with data 🙂&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-TracingPluginContactExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Now, to see what happens when an error is invoked, I have modified the code above so that it is expecting a field that doesn&amp;rsquo;t exist on the Account entity:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-TracingPluginForcingError.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Now, when we attempt to update our Account record, we receive a customised Business Process Error message and window:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-TracingPluginBusinessProcessError.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;And we can also see that the precise error message has been written to the trace log, at the point we specified:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-TracingPluginTraceLogErrorExample.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="last-but-not-least-for-on-premise-deployments"&gt;Last, but not least, for On-Premise deployments&amp;hellip;
&lt;/h2&gt;&lt;p&gt;One thing to point out is, if you are using On-Premise CRM 2016 (both 8.0 and 8.1), then for some reason the trace log will not work if you do not run you plugin within sandbox isolation mode. &lt;a class="link" href="https://community.dynamics.com/crm/f/117/t/189346" target="_blank" rel="noopener"
&gt;I&amp;rsquo;m not the only one experiencing this, according to this post on the Dynamics CRM Community forum.&lt;/a&gt; Switching my test plugin to sandbox isolation resolved this issue. A bit of a strange one, and as Srikanth mentions on the post, it is not clear if this a bug or not.&lt;/p&gt;
&lt;h2 id="conclusions-or-wot-i-think"&gt;Conclusions or Wot I Think
&lt;/h2&gt;&lt;p&gt;Trace logging is one of those things where time and place matter greatly. Implementing them within your code obsessively does not return much benefit, and could actually be detrimental to your CRM deployment. Used prudently and effectively though, they can prove to be incredibly useful. The scenarios where I can see them returning the most benefit is if your plugin is making a call to an external system and, if an error is encountered during this process, you can use the Trace Log to capture and store the external application error message within CRM for further investigation. Trace logging can also prove useful in scenarios where an issue cannot be readily replicated within the system, by outputting error messages and the steps leading up to them within the Trace Log.&lt;/p&gt;
&lt;p&gt;In summary, when used in conjunction with other debugging options available to you via the SDK, Trace Logging can be a powerful weapon to add to your arsenal when debugging your code issues in CRM.&lt;/p&gt;</description></item><item><title>Modifying System/Custom Views FetchXML Query in Dynamics CRM</title><link>/modifying-systemcustom-views-fetchxml-query-in-dynamics-crm/</link><pubDate>Sun, 06 Mar 2016 00:00:00 +0000</pubDate><guid>/modifying-systemcustom-views-fetchxml-query-in-dynamics-crm/</guid><description>&lt;img src="/images/D365-FI.jpg" alt="Featured image of post Modifying System/Custom Views FetchXML Query in Dynamics CRM" /&gt;&lt;p&gt;Working with Dynamics CRM can present some interesting challenges. What you tend to find is that you can pretty much say &amp;ldquo;Yes!&amp;rdquo; when it comes to doing most things you would expect from a CRM/database system, but there is a learning curve involved in figuring out the best approach to take. Often, as well, you may  over-complicate matters and overlook a much easier solution to achieve what you need.&lt;/p&gt;
&lt;p&gt;Take, for example, modifying the FetchXML queries in a Public View that you have created programmatically. Let&amp;rsquo;s say you&amp;rsquo;ve created your own view within CRM using the following C# code snippet (&lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg594431.aspx" target="_blank" rel="noopener"
&gt;adapted from the SDK sample&lt;/a&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SavedQuery&lt;/span&gt; &lt;span class="n"&gt;sq&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SavedQuery&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;My New View&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;My view created in C# for the Account entity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ReturnedTypeCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FetchXml&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fetchXml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;LayoutXml&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layoutXml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;QueryType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;_customViewId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_serviceProxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sq&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;A new view with the name {0} was created.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A few things to point out first with the above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In order for this code to work, you would need to declare System.String values for fetchXml and layoutXml, as well as first connecting to CRM using the OrganizationServiceProxy (_serviceProxy).&lt;/li&gt;
&lt;li&gt;As well as specifying the FetchXML query you would like to use, you also have to specify a LayoutXML as a parameter in order to. &lt;a class="link" href="https://msdn.microsoft.com/en-us/library/gg334522.aspx" target="_blank" rel="noopener"
&gt;Although Microsoft do have dedicated articles on MSDN that goes over the schema for this&lt;/a&gt;, there is a potential learning curve involved here for those who are unfamiliar with working with XML.&lt;/li&gt;
&lt;li&gt;ReturnedTypeCode is your entity logical name, which will need changing depending on the entity you are attempting to query&lt;/li&gt;
&lt;li&gt;Be sure to add in the appropriate namespace references, otherwise this code will not work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code example above is all very well and good if you are just wanting to create a brand new view. But what happens if you need to change it in the future? We can modify the base properties of a view (Name, Description etc.) as well as the column layout via the CRM GUI, but when we attempt to modify the filter criteria (i.e. the FetchXML query), we will notice that the option is not available to use:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/D365-Classic-ViewNoFilterCriteria.png"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;The next logical step would therefore be to look at creating some C# code that would take the existing view and modify the fetchXML query property. Unfortunately, Microsoft have not provided code examples on how this can be done, although it is in theory possible via the many methods at your disposal through the SDK.&lt;/p&gt;
&lt;p&gt;Rather then spend days and potentially weeks writing a bespoke piece of code to do the job, it was then that I realised that I was being a little dense (as tends to happen) and that the Solution was sitting right in front of me. See what I did there?&lt;/p&gt;
&lt;p&gt;Whilst the general rule of thumb is &amp;ldquo;DON&amp;rsquo;T DO IT!!&amp;rdquo; when it comes to modifying an exported solution file, it is possible to do and pretty much anything within a solution file can be changed or modified to suit a particular requirement. And, as luck would have it, modifying Public Views (either ones created by yourself or system ones) is a supported task that you can perform on the solution file:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Definitions of views for entities are included in the customizations.xml file and may be manually edited. The view editor in the application is the most commonly used tool for this purpose. Editing customizations.xml is an alternative method&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source: https://msdn.microsoft.com/en-gb/library/gg328486.aspx&lt;/p&gt;
&lt;p&gt;So, in order to modify a custom Public Views FetchXML query, all you would need to do is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a temporary, unmanaged solution file containing the entity with the custom Public View you want to change.&lt;/li&gt;
&lt;li&gt;Export as an unmanaged solution, unzip and open the customizations.xml file either in Notepad, Visual Studio or the XML editor program of your choice&lt;/li&gt;
&lt;li&gt;Use Ctrl + F to locate the savedquery node of the view you wish to change. It should look like this:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;savedquery&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;IsCustomizable&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/IsCustomizable&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;CanBeDeleted&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/CanBeDeleted&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;isquickfindquery&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/isquickfindquery&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;isprivate&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/isprivate&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;isdefault&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/isdefault&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;returnedtypecode&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/returnedtypecode&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;savedqueryid&amp;gt;&lt;/span&gt;{8e736028-47c7-e511-8107-3863bb345ac8}&lt;span class="nt"&gt;&amp;lt;/savedqueryid&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;layoutxml&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;grid&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;resultset&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;object=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;jump=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;firstname&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;preview=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;icon=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;row&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;result&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;accountid&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;cell&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;name&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;150&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;cell&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;statecode&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;150&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;cell&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;statuscode&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;150&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;cell&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ownerid&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;150&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;cell&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;createdon&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;150&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/row&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/grid&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/layoutxml&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;querytype&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/querytype&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;fetchxml&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;fetch&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;1.0&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;output-format=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;xml-platform&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;mapping=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;logical&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;distinct=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;entity&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;account&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;createdon&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;statuscode&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ownerid&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;statecode&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;accountid&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;order&lt;/span&gt; &lt;span class="na"&gt;attribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;descending=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;false&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;link-entity&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;from=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;regardingobjectid&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;accountid&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;alias=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ab&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;link-type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;outer&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;regardingobjectid&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/link-entity&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;link-entity&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;lead&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;from=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;parentaccountid&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;accountid&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;alias=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;al&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;link-type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;outer&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;link-entity&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;from=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;regardingobjectid&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;leadid&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;alias=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;lp&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;link-type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;outer&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;attribute&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;regardingobjectid&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/link-entity&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/link-entity&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;filter&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;and&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;condition&lt;/span&gt; &lt;span class="na"&gt;entityname=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ab&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;attribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;regardingobjectid&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;operator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;null&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;condition&lt;/span&gt; &lt;span class="na"&gt;entityname=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;lp&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;attribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;regardingobjectid&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;operator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;null&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;filter&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;or&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;condition&lt;/span&gt; &lt;span class="na"&gt;entityname=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ab&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;attribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;createdon&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;operator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;olderthan-x-weeks&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;1&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;condition&lt;/span&gt; &lt;span class="na"&gt;entityname=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ab&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;attribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;createdon&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;operator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;null&amp;#39;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/entity&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/fetch&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/fetchxml&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;IntroducedVersion&amp;gt;&lt;/span&gt;1.0&lt;span class="nt"&gt;&amp;lt;/IntroducedVersion&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;LocalizedNames&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;LocalizedName&lt;/span&gt; &lt;span class="na"&gt;description=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;My New View&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;languagecode=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1033&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/LocalizedNames&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Descriptions&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;Description&lt;/span&gt; &lt;span class="na"&gt;description=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;My view created in C# for the Account entity&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;languagecode=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1033&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/Descriptions&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/savedquery&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="4"&gt;
&lt;li&gt;Modify the FetchXML query within the &lt;fetchxml&gt; node to your updated query&lt;/li&gt;
&lt;li&gt;(Optional) If your FetchXML query is simply making changes to the filter criteria, you can skip this step. Otherwise, if you have new fields that you would like to be displayed as part of the changes, you will also need to modify the &lt;layoutxml&gt; node so that it contains your new fields.&lt;/li&gt;
&lt;li&gt;Save the changes back into the solution file and then import the solution back into CRM.&lt;/li&gt;
&lt;li&gt;Test your view by opening it within the application and confirm everything looks OK.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;rsquo;m sure you&amp;rsquo;ll agree that this is definitely a much easier and simple way to make changes to your view. Just be careful when working within the solution file that you don&amp;rsquo;t accidentally delete/overwrite something!&lt;/p&gt;</description></item></channel></rss>