<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Enlighten with Amit</title><link>https://www.amitk.net/tags/serverless/</link><description>Expert insights from a Solution Architect on enterprise digital strategy, microservices architecture, and modern headless solutions (Sitecore XM Cloud, Next.js). Focused on driving business impact through scalable technology.</description><image><url>https://www.amitk.net/images/amit-kumar.jpeg</url><title>Enlighten with Amit</title><link>https://www.amitk.net/</link></image><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>amit@amitk.net (Amit Kumar)</managingEditor><webMaster>amit@amitk.net (Amit Kumar)</webMaster><lastBuildDate>Mon, 20 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.amitk.net/tags/serverless/index.xml" rel="self" type="application/rss+xml"/><item><title>Azure Functions for Dataverse CRUD in .NET</title><link>https://www.amitk.net/blog/sitecoreai-azure-functions-dataverse-crud/</link><pubDate>Mon, 20 Jul 2026 00:00:00 +0000</pubDate><author>amit@amitk.net (Amit Kumar)</author><guid>https://www.amitk.net/blog/sitecoreai-azure-functions-dataverse-crud/</guid><media:content url="https://www.amitk.net/images/sitecoreai-dataverse-integration-dotnet/azure-functions-dataverse-crud.gif" medium="image" type="image/gif"/><description>
Build production-ready Azure Functions in .NET for Microsoft Dataverse CRUD operations, ready for SitecoreAI, Next.js and MCP workflows.</description><content:encoded><![CDATA[







<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-azure-functions-for-microsoft-dataverse-crud" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">⚡ Azure Functions for Microsoft Dataverse CRUD</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<p>In the previous article of this series, we covered how to set up authentication and a secure connection between <strong>SitecoreAI (Sitecore XM Cloud)</strong> and Microsoft Dataverse. If you haven&rsquo;t read that yet, start with <a href="https://www.amitk.net/blog/sitecoreai-dataverse-authentication-connection/" target="_blank" rel="noopener">SitecoreAI Dataverse Authentication and Connection</a>
.</p>
<p>This session moves from connection setup to actual implementation. We&rsquo;ll build a production-ready Azure Functions backend that exposes clean CRUD operations against Microsoft Dataverse.</p>
<p>The goal is straightforward:</p>
<div class="alert-box info">
                    <span class="icon">i</span>
                    <div class="alert-content">
                            Build a secure, reusable, serverless .NET API layer that SitecoreAI (Sitecore XM Cloud), Next.js, automation tools, and future MCP tools can call without touching Dataverse directly.
                    </div>
                </div>
<p>HTTP-triggered Azure Functions are a natural fit here - Microsoft&rsquo;s documentation describes the HTTP trigger as a way to invoke a function with an HTTP request, which is exactly what&rsquo;s needed to build a lightweight serverless API. For the Dataverse side, we&rsquo;ll use the modern <code>Microsoft.PowerPlatform.Dataverse.Client</code> package and its <code>ServiceClient</code> class, which Microsoft positions as the primary implementation for Dataverse operations and which authenticates through MSAL rather than the older ADAL-based clients.</p>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-why-this-matters" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">💡 Why This Matters</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<p>Once you have a working Dataverse connection, the next question is usually: how should a website, a SitecoreAI workflow, or an AI agent safely create, update, and delete Dataverse records?</p>
<p>Calling Dataverse directly from a frontend is rarely the right production pattern - it exposes too much implementation detail, complicates validation, and makes security harder to reason about. A better approach keeps Dataverse behind a controlled backend layer, where each function represents one business operation rather than a generic table endpoint.</p>
<p>This pattern is a good fit when:</p>
<ul class="numbered-list primary">
<li>SitecoreAI (Sitecore XM Cloud) needs to submit structured data into Dataverse.</li>
<li>A Next.js frontend needs a secure backend endpoint.</li>
<li>An internal workflow needs lightweight automation.</li>
<li>A future MCP tool needs predictable, auditable server-side operations.</li>
<li>You want Dataverse credentials and business rules kept away from the browser.</li>
</ul>
<br/>
<div class="callout warning">
    <div class="callout-head"><svg height=1.2em class="hx:inline-block hx:align-middle" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73.0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898.0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"></path></svg><p>CRITICAL</p>
    </div>
    <div class="callout-body">
        <p><strong><span class="dark:text-gray-300 font-semibold gradient-text-sea-salt">For the runtime model, Microsoft&rsquo;s guidance is unambiguous going into the second half of 2026: the in-process .NET model reaches end of support on <strong>November 10, 2026</strong>, and the isolated worker model is the only path forward for .NET 9, .NET 10, and beyond. It also gives full process control, standard dependency injection, and independent versioning from the Functions host - all useful properties for a service that has to manage its own Dataverse client lifecycle.</span></strong></p>
    </div>
</div>
<p>That makes the isolated worker model the right choice for a production-grade Dataverse integration today.</p>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-background" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">📖 Background</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<p>This article is part of a practical Dataverse integration series:</p>
<ul class="numbered-list">
<li>Architecture and integration concept.</li>
<li>Authentication and secure connection between SitecoreAI (Sitecore XM Cloud) and Dataverse.</li>
<li>Azure Functions for CRUD operations against Dataverse (this article).</li>
<li>Calling the Azure Functions from SitecoreAI, Next.js, or MCP workflows.</li>
</ul>
<br/>
<p>In the previous article we focused on getting the connection model right. This article builds the operational layer on top of it.</p>





















  
  
    
    <img
      title="Microsoft Dataverse: Azure Functions Dataverse CRUD"
      loading="lazy"
      decoding="async"
      src="https://www.amitk.net/images/sitecoreai-dataverse-integration-dotnet/dataverse-crud-with-azure-functions-sitecore-mvp-amit.png"
      alt="Microsoft Dataverse: Azure Functions Dataverse CRUD"
      class="img justify-self-center  "
      width=""
      height="" />
  
  













<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-architecture-overview" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">🧱 Architecture Overview</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<p>The production pattern has four layers:</p>



<div class="table-wrapper">
<table class="style-table"><thead>
        <tr><th>Layer</th><th>Responsibility</th></tr>
      </thead><tbody><tr><td><strong>API layer</strong></td><td>Azure Functions expose HTTP endpoints for create, update, and delete operations</td></tr><tr><td><strong>Validation layer</strong></td><td>Validates incoming payloads before calling Dataverse</td></tr><tr><td><strong>Service layer</strong></td><td>Wraps Dataverse <code>ServiceClient</code> operations</td></tr><tr><td><strong>Observability layer</strong></td><td>Uses <code>ILogger</code> and Application Insights for tracing and troubleshooting</td></tr></tbody>
  
</table>
</div>
<p>Azure Functions integrate directly with Application Insights, which collects the logs, performance data, and errors generated by the function app - this becomes important once you have several CRUD endpoints running in production.</p>
<p>For secrets, Azure Functions can reference values stored in Azure Key Vault as application settings, so the running code reads them like any other configuration value while the actual secret material stays in the vault.</p>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-architecture-overview" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">🗄️ Architecture Overview</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<p>For this article, assume we&rsquo;re storing a simple business enquiry in Dataverse.</p>
<p>Example Dataverse table:</p>



<div class="table-wrapper">
<table class="style-table"><thead>
        <tr><th>Display Name</th><th>Logical Name</th><th>Type</th><th>Required</th></tr>
      </thead><tbody><tr><td>Name</td><td><code>crf51_newcolumn</code></td><td>Text</td><td>Yes</td></tr><tr><td>Email</td><td><code>crf51_email</code></td><td>Text</td><td>Yes</td></tr><tr><td>Message</td><td><code>crf51_messag</code></td><td>Multiline Text</td><td>No</td></tr><tr><td>Source</td><td><code>crf51_source</code></td><td>Text</td><td>No</td></tr></tbody>
  
</table>
</div>
<p>Example table logical name: <strong>crf51_sitecoreenquiry</strong></p>
<p>In a real implementation, confirm the table logical name, column logical names, required fields, choice values, and security roles directly against your own Dataverse environment before wiring up code.</p>
<p>Dataverse&rsquo;s Web API basic-operations documentation walks through the same create, retrieve, update, and delete pattern we&rsquo;re implementing here, just via HTTP rather than the SDK. We&rsquo;re using the .NET <code>ServiceClient</code> instead because Microsoft explicitly positions the <code>Dataverse.Client</code> package as the client applications should transition to, replacing the older <code>CrmServiceClient</code>.</p>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-implementation" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">⚙️ Implementation</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<br/>
<h3 id="step-1-create-the-azure-functions-project">Step 1: Create the Azure Functions Project</h3>
<p>Create a .NET isolated worker Functions project:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>func init SitecoreAI-Dataverse-Azure-Functions --worker-runtime dotnet-isolated --target-framework net9.0
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">cd</span> SitecoreAI-Dataverse-Azure-Functions
</span></span></code></pre></div><p>Add HTTP trigger functions inside <code>Functions</code> folder:</p>
<ul class="checklist check">
<li>
<p><strong>CreateDataverseRecord</strong></p>
<p>Azure Function for creating new enquiry records in Microsoft Dataverse.</p>
</li>
<li>
<p><strong>UpdateDataverseRecord</strong></p>
<p>Azure Function for updating existing enquiry records in Microsoft Dataverse.</p>
</li>
<li>
<p><strong>DeleteDataverseRecord</strong></p>
<p>Azure Function for deleting enquiry records from Microsoft Dataverse.</p>
</li>
<li>
<p><strong>GetEnquiriesFunction</strong></p>
<p>Azure Function for retrieving multiple enquiry records from Microsoft Dataverse.</p>
</li>
<li>
<p><strong>GetEnquiryFunction</strong></p>
<p>Azure Function for retrieving a single enquiry record by ID from Microsoft Dataverse.</p>
</li>
<li>
<p><strong>GetEnquiriesByEmailFunction</strong></p>
<p>Azure Function for retrieving enquiry records filtered by email address from Microsoft Dataverse.</p>
</li>
</ul>
<br/>
<div class="callout danger">
    <div class="callout-head"><svg height=1.2em class="hx:inline-block hx:align-middle" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73.0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898.0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"></path></svg><p>Security Updates</p>
    </div>
    <div class="callout-body">
        <p>Scaffold new projects with <code>--worker-runtime dotnet-isolated</code> rather than <code>dotnet</code>. The in-process model is pinned at .NET 8 and stops receiving security updates after November 10, 2026, so there&rsquo;s no good reason to start a new project on it today.</p>
    </div>
</div>
<hr>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h3 id="step-2-add-nuget-packages" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">Step 2: Add NuGet Packages</h3>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>dotnet add package Microsoft.Azure.Functions.Worker
</span></span><span style="display:flex;"><span>dotnet add package Microsoft.Azure.Functions.Worker.OpenTelemetry
</span></span><span style="display:flex;"><span>dotnet add package Microsoft.Data.SqlClient
</span></span><span style="display:flex;"><span>dotnet add package Microsoft.PowerPlatform.Dataverse.Client
</span></span><span style="display:flex;"><span>dotnet add package OpenTelemetry.Extensions.Hosting
</span></span><span style="display:flex;"><span>dotnet add package Azure.Monitor.OpenTelemetry.Exporte
</span></span><span style="display:flex;"><span>dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
</span></span><span style="display:flex;"><span>dotnet add package Microsoft.Azure.Functions.Worker.Sdk
</span></span></code></pre></div><div class="callout info">
    <div class="callout-head"><svg height=1.2em class="hx:inline-block hx:align-middle" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75.0 011.063.852l-.708 2.836a.75.75.0 001.063.853l.041-.021M21 12A9 9 0 113 12a9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"></path></svg><p>Microsoft.PowerPlatform.Dataverse.Client</p>
    </div>
    <div class="callout-body">
        <p><code>Microsoft.PowerPlatform.Dataverse.Client</code> contains the .NET <code>ServiceClient</code> used to connect to Microsoft Dataverse, and it&rsquo;s actively maintained - the package shipped an update as recently as July 2026 with retry-logic improvements for throttling responses.</p>
    </div>
</div>
<hr>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h3 id="step-3-configure-application-settings" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">Step 3: Configure Application Settings</h3>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<p>For local development, use <code>local.settings.json</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">&#34;IsEncrypted&#34;</span>: <span style="color:#ff79c6">false</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#ff79c6">&#34;Values&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">&#34;AzureWebJobsStorage&#34;</span>: <span style="color:#f1fa8c">&#34;UseDevelopmentStorage=true&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">&#34;FUNCTIONS_WORKER_RUNTIME&#34;</span>: <span style="color:#f1fa8c">&#34;dotnet-isolated&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">&#34;DataverseEnvironment&#34;</span>: <span style="color:#f1fa8c">&#34;YOUR-DATAVERSE-ENVIRONMENT&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">&#34;ClientId&#34;</span>: <span style="color:#f1fa8c">&#34;YOUR-CLIENT-ID&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#ff79c6">&#34;ClientSecret&#34;</span>: <span style="color:#f1fa8c">&#34;YOUR-CLIENT-SECRET&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><div class="alert-box warning">
                    <span class="icon">i</span>
                    <div class="alert-content">
                            For production, don&rsquo;t store secrets directly in plain application settings. Use a Key Vault reference so the secret lives in the vault and the Function App only holds a pointer to it:
                    </div>
                </div>
<hr>
<h3 id="step-4-configure-dependency-injection">Step 4: Configure Dependency Injection</h3>
<p><code>Program.cs</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-csharp" data-lang="csharp"><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Azure.Functions.Worker.Builder;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Extensions.DependencyInjection;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Extensions.Hosting;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> SitecoreAI.Dataverse.AzureFunctions.Services;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">// Create and configure the Azure Functions application builder</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd">var</span> builder = FunctionsApplication.CreateBuilder(args);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">// Configure the Functions Web Application middleware</span>
</span></span><span style="display:flex;"><span>builder.ConfigureFunctionsWebApplication();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">// Register application services for dependency injection</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">// IDataverseService: Service for interacting with Microsoft Dataverse</span>
</span></span><span style="display:flex;"><span>builder.Services.AddSingleton&lt;IDataverseService, DataverseService&gt;();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">// Build and run the application</span>
</span></span><span style="display:flex;"><span>builder.Build().Run();
</span></span></code></pre></div><p>Standard .NET dependency injection is one of the concrete advantages the isolated worker model gives you over in-process-you get full control of the startup pipeline instead of relying on the Functions host&rsquo;s binding infrastructure.</p>
<hr>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-code-examples" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">💻 Code Examples</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<h3 id="request-models">Request Models</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-csharp" data-lang="csharp"><span style="display:flex;"><span>﻿<span style="color:#ff79c6">using</span> System;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> System.Collections.Generic;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> System.Linq;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> System.Text;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> System.Threading.Tasks;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">namespace</span> SitecoreAI.Dataverse.AzureFunctions.Models;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// &lt;summary&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// Response model representing an enquiry retrieved from Dataverse.</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// &lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#8be9fd;font-style:italic">sealed</span> <span style="color:#ff79c6">class</span> <span style="color:#50fa7b">EnquiryResponse</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;Gets or sets the unique identifier of the enquiry.&lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> Guid Id { <span style="color:#ff79c6">get</span>; <span style="color:#ff79c6">set</span>; }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;Gets or sets the name of the person submitting the enquiry.&lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#8be9fd">string?</span> Name { <span style="color:#ff79c6">get</span>; <span style="color:#ff79c6">set</span>; }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;Gets or sets the email address of the person submitting the enquiry.&lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#8be9fd">string?</span> Email { <span style="color:#ff79c6">get</span>; <span style="color:#ff79c6">set</span>; }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;Gets or sets the message content of the enquiry.&lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#8be9fd">string?</span> Message { <span style="color:#ff79c6">get</span>; <span style="color:#ff79c6">set</span>; }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;Gets or sets the source system from which the enquiry originated.&lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#8be9fd">string?</span> Source { <span style="color:#ff79c6">get</span>; <span style="color:#ff79c6">set</span>; }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;Gets or sets the date and time when the enquiry was created.&lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> DateTime? CreatedOn { <span style="color:#ff79c6">get</span>; <span style="color:#ff79c6">set</span>; }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;Gets or sets the date and time when the enquiry was last modified.&lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> DateTime? ModifiedOn { <span style="color:#ff79c6">get</span>; <span style="color:#ff79c6">set</span>; }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#6272a4">// Scan the QR code below to view and access the complete code repository.</span>
</span></span></code></pre></div><hr>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h3 id="dataverse-service-layer" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">Dataverse Service Layer</h3>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-csharp" data-lang="csharp"><span style="display:flex;"><span><span style="color:#ff79c6">namespace</span> SitecoreAI.Dataverse.AzureFunctions.Services;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// &lt;summary&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// Service interface for managing enquiry records in Microsoft Dataverse.</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// Provides CRUD operations and query capabilities for enquiry data.</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// &lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#ff79c6">interface</span> <span style="color:#50fa7b">IDataverseService</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// Creates a new enquiry record in Dataverse.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;param name=&#34;request&#34;&gt;The request containing enquiry details to create.&lt;/param&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;param name=&#34;cancellationToken&#34;&gt;Token to cancel the operation.&lt;/param&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;returns&gt;The unique identifier (GUID) of the newly created enquiry.&lt;/returns&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;exception cref=&#34;ArgumentException&#34;&gt;Thrown when validation fails or field lengths exceed maximum allowed values.&lt;/exception&gt;</span>
</span></span><span style="display:flex;"><span>    Task&lt;Guid&gt; CreateEnquiryAsync(CreateEnquiryRequest request, CancellationToken cancellationToken);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#6272a4">// Scan the QR code below to view and access the complete code repository.</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-csharp" data-lang="csharp"><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Extensions.Configuration;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Extensions.Logging;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.PowerPlatform.Dataverse.Client;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Xrm.Sdk;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Xrm.Sdk.Query;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> SitecoreAI.Dataverse.AzureFunctions.Models;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">namespace</span> SitecoreAI.Dataverse.AzureFunctions.Services;
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// &lt;summary&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// Service implementation for managing enquiry records in Microsoft Dataverse.</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// Provides CRUD operations, validation, and data mapping for enquiry entities.</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// &lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#8be9fd;font-style:italic">sealed</span> <span style="color:#ff79c6">class</span> <span style="color:#50fa7b">DataverseService</span> : IDataverseService
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">private</span> <span style="color:#ff79c6">readonly</span> IConfiguration _configuration;
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">private</span> <span style="color:#ff79c6">readonly</span> ILogger&lt;DataverseService&gt; _logger;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#6272a4">// Scan the QR code below to view and access the complete code repository.</span>
</span></span></code></pre></div><hr>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h3 id="create-function" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">Create Function</h3>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-csharp" data-lang="csharp"><span style="display:flex;"><span><span style="color:#ff79c6">using</span> SitecoreAI.Dataverse.AzureFunctions.Services;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Azure.Functions.Worker;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Azure.Functions.Worker.Http;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> Microsoft.Extensions.Logging;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> System.Net;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> System.Text.Json;
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">using</span> SitecoreAI.Dataverse.AzureFunctions.Models;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff79c6">namespace</span> SitecoreAI.Dataverse.AzureFunctions.Functions;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// &lt;summary&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// Azure Function for creating new enquiry records in Microsoft Dataverse.</span>
</span></span><span style="display:flex;"><span><span style="color:#6272a4">/// &lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span><span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#8be9fd;font-style:italic">sealed</span> <span style="color:#ff79c6">class</span> <span style="color:#50fa7b">CreateDataverseRecord</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">private</span> <span style="color:#ff79c6">readonly</span> IDataverseService _dataverseService;
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">private</span> <span style="color:#ff79c6">readonly</span> ILogger&lt;CreateDataverseRecord&gt; _logger;
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// Initializes a new instance of the &lt;see cref=&#34;CreateDataverseRecord&#34;/&gt; class.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;param name=&#34;dataverseService&#34;&gt;Service for interacting with Dataverse.&lt;/param&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;param name=&#34;logger&#34;&gt;Logger for tracking function execution.&lt;/param&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> CreateDataverseRecord(
</span></span><span style="display:flex;"><span>        IDataverseService dataverseService,
</span></span><span style="display:flex;"><span>        ILogger&lt;CreateDataverseRecord&gt; logger)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        _dataverseService = dataverseService;
</span></span><span style="display:flex;"><span>        _logger = logger;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// HTTP-triggered function that creates a new enquiry record in Dataverse.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;/summary&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;param name=&#34;req&#34;&gt;The HTTP request containing the enquiry data in the body.&lt;/param&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;param name=&#34;executionContext&#34;&gt;The function execution context.&lt;/param&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#6272a4">/// &lt;returns&gt;An HTTP response with the created record ID or an error message.&lt;/returns&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#50fa7b">    [Function(&#34;CreateDataverseRecord&#34;)]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8be9fd;font-style:italic">public</span> <span style="color:#8be9fd;font-style:italic">async</span> Task&lt;HttpResponseData&gt; Run(
</span></span><span style="display:flex;"><span><span style="color:#50fa7b">        [HttpTrigger(AuthorizationLevel.Function, &#34;post&#34;, Route = &#34;dataverse/enquiries&#34;)]</span>
</span></span><span style="display:flex;"><span>        HttpRequestData req,
</span></span><span style="display:flex;"><span>        FunctionContext executionContext)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#8be9fd">var</span> cancellationToken = executionContext.CancellationToken;
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span>        
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The update and delete functions follow the same shape - an HTTP trigger, a thin validation step, a call into <code>IDataverseService</code>, and a structured JSON response. Update binds the route parameter to <code>{id:guid}</code> and issues a <code>PATCH</code>; delete binds the same route and issues a <code>DELETE</code>.</p>
<p><div class="callout info">
    <div class="callout-head"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"/></svg><p>Explore More & Share Your Feedback</p>
    </div>
    <div class="callout-body">
        <p><p><span class="dark:text-gray-300 font-semibold gradient-text-aqua">📱 Scan to access the complete SitecoreAI Dataverse Azure Functions repository</span>
<br/>
<span class="dark:text-gray-300 font-semibold gradient-text-par-four">💻 Azure Functions integration, .NET 8 code, authentication setup &amp; CRUD examples</span></p>
<img src="https://www.amitk.net/images/sitecoreai-dataverse-integration-dotnet/sitecoreai-dataverse-azure-functions-dotnet-Sitecore-MVP-Amit-Kumar.png" class="img justify-self-center medium-zoom-image" style="max-width: 40%;"/>
<p><br/><br/>
<strong><em>Share your feedback or contribute to support the Sitecore developer community!</em></strong></p>
</p>
    </div>
</div>
<div class="github-card-wrapper">
    <a id="github-056f2ddc8b277b03a78c5cde00100d39" target="_blank" href="https://github.com/AmitKumar-AK/sitecoreai-dataverse-connector" class="cursor-pointer">
      <div
        class="w-full md:w-auto p-0 m-0 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl"><div class="w-full nozoom">
            <img
              src="https://opengraph.githubassets.com/0/AmitKumar-AK/sitecoreai-dataverse-connector"
              alt="GitHub Repository Thumbnail"
              class="nozoom mt-0 mb-0 w-full h-full object-cover">
          </div><div class="w-full md:w-auto pt-3 p-5">
          <div class="flex items-center">
            <span class="text-2xl text-neutral-800 dark:text-gray-300 me-2"><svg height=1.2em class="hx:inline-block hx:align-middle" fill="currentColor" viewBox="3 3 18 18">
  <path d="M12 3C7.0275 3 3 7.12937 3 12.2276C3 16.3109 5.57625 19.7597 9.15374 20.9824C9.60374 21.0631 9.77249 20.7863 9.77249 20.5441C9.77249 20.3249 9.76125 19.5982 9.76125 18.8254C7.5 19.2522 6.915 18.2602 6.735 17.7412C6.63375 17.4759 6.19499 16.6569 5.8125 16.4378C5.4975 16.2647 5.0475 15.838 5.80124 15.8264C6.51 15.8149 7.01625 16.4954 7.18499 16.7723C7.99499 18.1679 9.28875 17.7758 9.80625 17.5335C9.885 16.9337 10.1212 16.53 10.38 16.2993C8.3775 16.0687 6.285 15.2728 6.285 11.7432C6.285 10.7397 6.63375 9.9092 7.20749 9.26326C7.1175 9.03257 6.8025 8.08674 7.2975 6.81794C7.2975 6.81794 8.05125 6.57571 9.77249 7.76377C10.4925 7.55615 11.2575 7.45234 12.0225 7.45234C12.7875 7.45234 13.5525 7.55615 14.2725 7.76377C15.9937 6.56418 16.7475 6.81794 16.7475 6.81794C17.2424 8.08674 16.9275 9.03257 16.8375 9.26326C17.4113 9.9092 17.76 10.7281 17.76 11.7432C17.76 15.2843 15.6563 16.0687 13.6537 16.2993C13.98 16.5877 14.2613 17.1414 14.2613 18.0065C14.2613 19.2407 14.25 20.2326 14.25 20.5441C14.25 20.7863 14.4188 21.0746 14.8688 20.9824C16.6554 20.364 18.2079 19.1866 19.3078 17.6162C20.4077 16.0457 20.9995 14.1611 21 12.2276C21 7.12937 16.9725 3 12 3Z"></path>
</svg>
</span>
            <div
              id="github-056f2ddc8b277b03a78c5cde00100d39-full_name"
              class="m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-gray-300">
              AmitKumar-AK/sitecoreai-dataverse-connector
            </div>
          </div>

          <p id="github-056f2ddc8b277b03a78c5cde00100d39-description" class="m-0 mt-2 text-md text-neutral-800 dark:text-gray-300">
            Azure Functions-based integration connecting SitecoreAI (XM Cloud) forms to Microsoft Dataverse.  Includes certificate-based authentication, CRUD operations, and console app demos.
          </p>

          <div class="m-0 mt-2 flex items-center">
            <span class="mr-1 inline-block h-3 w-3 rounded-full language-dot" data-language="C#"></span>
            <div class="m-0 mr-5 text-md text-neutral-800 dark:text-gray-300">
              C#
            </div>

            <span class="text-md mr-1 text-neutral-800 dark:text-gray-300"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"/></svg></span>
            <div id="github-056f2ddc8b277b03a78c5cde00100d39-stargazers" class="m-0 mr-5 text-md text-neutral-800 dark:text-gray-300">
              0
            </div>

            <span class="text-md mr-1 text-neutral-800 dark:text-gray-300"><svg height=1.2em class="hx:inline-block hx:align-middle" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M7 5C7 3.89543 7.89543 3 9 3C10.1046 3 11 3.89543 11 5C11 5.74028 10.5978 6.38663 10 6.73244V14.0396H11.7915C12.8961 14.0396 13.7915 13.1441 13.7915 12.0396V10.7838C13.1823 10.4411 12.7708 9.78837 12.7708 9.03955C12.7708 7.93498 13.6662 7.03955 14.7708 7.03955C15.8753 7.03955 16.7708 7.93498 16.7708 9.03955C16.7708 9.77123 16.3778 10.4111 15.7915 10.7598V12.0396C15.7915 14.2487 14.0006 16.0396 11.7915 16.0396H10V17.2676C10.5978 17.6134 11 18.2597 11 19C11 20.1046 10.1046 21 9 21C7.89543 21 7 20.1046 7 19C7 18.2597 7.4022 17.6134 8 17.2676V6.73244C7.4022 6.38663 7 5.74028 7 5Z" fill="#000000"></path> </g></svg></span>
            <div id="github-056f2ddc8b277b03a78c5cde00100d39-forks" class="m-0 mr-5 text-md text-neutral-800 dark:text-gray-300">
              0
            </div>
          </div>
        </div>
      </div>
      
      
      <script
        async
        type="text/javascript"
        src="/js/fetch-repo.min.dc5533c50cefd50405344b235937142271f26229fe39cbee27fd4960e8bb897a0beebfad77a1091ca91cd0d1fb14e70fc37cc114dd9674fb2c32e0ab512ec8a4.js"
        integrity="sha512-3FUzxQzv1QQFNEsjWTcUInHyYin&#43;OcvuJ/1JYOi7iXoL7r&#43;td6EJHKkc0NH7FOcPw3zBFN2WdPssMuCrUS7IpA=="
        data-repo-url="https://api.github.com/repos/AmitKumar-AK/sitecoreai-dataverse-connector"
        data-repo-id="github-056f2ddc8b277b03a78c5cde00100d39"></script>
    </a>
  </div>
<br/></p>
<p>







<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-best-practices" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">✅ Best Practices</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<br/>
<ul class="checklist check">
<li>
<p><strong>Keep functions business-focused.</strong> Avoid a single generic <code>POST /api/dataverse/{tableName}</code> endpoint - it exposes too much Dataverse implementation detail. Prefer purpose-built routes like <code>/api/dataverse/enquiries</code>.</p>
</li>
<li>
<p><strong>Validate before calling Dataverse.</strong> Check required fields, email format, field lengths, and choice values before the SDK call, not after.</p>
</li>
<li>
<p><strong>Keep secrets in Key Vault.</strong> Give the Function App&rsquo;s managed identity read access to the secret rather than pasting connection strings into plain app settings.</p>
</li>
<li>
<p><strong>Log with Application Insights.</strong> Capture operation name, correlation ID, Dataverse record ID, and execution duration so failed submissions are traceable.</p>
</li>
<li>
<p><strong>Return structured responses.</strong> MCP tools and AI agents work far better against predictable JSON shapes than raw exception text.</p>
</li>
<li>
<p><strong>Update only changed fields.</strong> Sending every retrieved property back on update can unnecessarily trigger Dataverse business logic, plugins, and audit history even when values haven&rsquo;t changed.</p>
</li>
</ul></p>
<br/>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-frequent-errors" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">⚠️ Frequent errors</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>



<div class="table-wrapper">
<table class="style-table"><thead>
        <tr><th>Errors</th><th>Why It Hurts</th><th>Better Approach</th></tr>
      </thead><tbody><tr><td>Calling Dataverse directly from the frontend</td><td>Exposes implementation detail and increases security risk</td><td>Route through Azure Functions</td></tr><tr><td>One generic CRUD endpoint for every table</td><td>Harder to secure and validate</td><td>Business-specific endpoints</td></tr><tr><td>Returning raw Dataverse exceptions</td><td>Not friendly for users or AI tools</td><td>Structured <code>ApiResponse&lt;T&gt;</code> payloads</td></tr><tr><td>Updating every field on every request</td><td>Can trigger unnecessary plugins and audit noise</td><td>Update only changed fields</td></tr><tr><td>Secrets in plain app settings</td><td>Increases operational risk</td><td>Key Vault references</td></tr><tr><td>Staying on the in-process model</td><td>Loses support after November 10, 2026</td><td>Scaffold new projects as <code>dotnet-isolated</code></td></tr></tbody>
  
</table>
</div>
<p>







<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-performance-considerations" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">📈 Performance Considerations</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<br/>
<ul class="numbered-list">
<li>Reuse <code>ServiceClient</code> connection pooling where possible rather than reconnecting per call.</li>
<li>Prefer async patterns throughout, and log dependency latency via Application Insights.</li>
<li>Add retry handling only where it&rsquo;s safe - the current ServiceClient already respects server-specified Retry-After values for throttling, so avoid layering an additional blind retry loop on top.</li>
<li>Use idempotency keys for operations where a duplicate write would matter.</li>
</ul></p>
<br/>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-security-considerations" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">🛡️ Security Considerations</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<p>A production-ready setup should include:</p>
<ul class="checklist accent check">
<li>Function-level authentication, or API Management in front of the Functions app.</li>
<li>Managed identity for Key Vault access instead of static secrets where feasible.</li>
<li>Least-privilege Dataverse application user permissions.</li>
<li>Input validation and request size limits.</li>
<li>Environment-specific app registrations for dev, test, and production.</li>
<li>Logging that never includes sensitive payload data.</li>
</ul>
<br/>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-real-world-example" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">🌍 Real-World Example</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<ul>
<li>
<p>Imagine a SitecoreAI (Sitecore XM Cloud) landing page capturing interest in a product demo. The form collects a name, email, company, message, and campaign source.</p>
</li>
<li>
<p>Instead of calling Dataverse directly, the page calls <code>POST /api/dataverse/enquiries</code>. The Azure Function validates the payload, maps fields to Dataverse columns, creates the row, logs the operation, and returns a structured response.</p>
</li>
<li>
<p>Later, a support workflow - or an MCP tool - can update the same record with <code>PATCH /api/dataverse/enquiries/{id}</code>, and an authorised cleanup process can remove test data with <code>DELETE /api/dataverse/enquiries/{id}</code>. One backend now safely serves SitecoreAI, Next.js, automation scripts, and future AI agents.</p>
</li>
</ul>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-faq" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">💬 FAQ</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<br/>


          
          
          

          <div class="not-prose accordion-group " data-accordion-mode="single"
            data-first-open="true">
            



  
  
  
  
  

  
  

  <div class="accordion-item" data-open="">
    <h3 class="m-0"><button type="button" class="accordion-header" data-accordion-header aria-expanded="false"><span
      class="accordion-title font-display text-xl md:text-2xl font-bold gradient-text-amitk-aurora">Why use Azure Functions with Microsoft Dataverse?</span><svg class="accordion-icon"
      viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <path fill="currentColor"
        d="M505.755,123.592c-8.341-8.341-21.824-8.341-30.165,0L256.005,343.176L36.421,123.592c-8.341-8.341-21.824-8.341-30.165,0 s-8.341,21.824,0,30.165l234.667,234.667c4.16,4.16,9.621,6.251,15.083,6.251c5.462,0,10.923-2.091,15.083-6.251l234.667-234.667 C514.096,145.416,514.096,131.933,505.755,123.592z">
      </path>
    </svg></button></h3>
    
    <div class="accordion-panel">
      <div>
        <div class="accordion-body pb-4 pr-8 text-base md:text-lg leading-relaxed text-gray-700 dark:text-gray-300">
          Azure Functions give you a lightweight, serverless API layer so SitecoreAI, Next.js, or MCP tools can create, update, or delete Dataverse rows without touching Dataverse directly.
        </div>
      </div>
    </div>
  </div>



  
  
  
  
  

  
  

  <div class="accordion-item" data-open="">
    <h3 class="m-0"><button type="button" class="accordion-header" data-accordion-header aria-expanded="false"><span
      class="accordion-title font-display text-xl md:text-2xl font-bold gradient-text-amitk-midnight-violet">Should I use the Dataverse Web API or ServiceClient?</span><svg class="accordion-icon"
      viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <path fill="currentColor"
        d="M505.755,123.592c-8.341-8.341-21.824-8.341-30.165,0L256.005,343.176L36.421,123.592c-8.341-8.341-21.824-8.341-30.165,0 s-8.341,21.824,0,30.165l234.667,234.667c4.16,4.16,9.621,6.251,15.083,6.251c5.462,0,10.923-2.091,15.083-6.251l234.667-234.667 C514.096,145.416,514.096,131.933,505.755,123.592z">
      </path>
    </svg></button></h3>
    
    <div class="accordion-panel">
      <div>
        <div class="accordion-body pb-4 pr-8 text-base md:text-lg leading-relaxed text-gray-700 dark:text-gray-300">
          Both are valid. For .NET server-side code, <code>Microsoft.PowerPlatform.Dataverse.Client.ServiceClient</code> is the client Microsoft recommends applications transition to, and it authenticates via MSAL.
        </div>
      </div>
    </div>
  </div>



  
  
  
  
  

  
  

  <div class="accordion-item" data-open="">
    <h3 class="m-0"><button type="button" class="accordion-header" data-accordion-header aria-expanded="false"><span
      class="accordion-title font-display text-xl md:text-2xl font-bold gradient-text-sea-salt">Is the in-process Azure Functions model still an option for new projects?</span><svg class="accordion-icon"
      viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <path fill="currentColor"
        d="M505.755,123.592c-8.341-8.341-21.824-8.341-30.165,0L256.005,343.176L36.421,123.592c-8.341-8.341-21.824-8.341-30.165,0 s-8.341,21.824,0,30.165l234.667,234.667c4.16,4.16,9.621,6.251,15.083,6.251c5.462,0,10.923-2.091,15.083-6.251l234.667-234.667 C514.096,145.416,514.096,131.933,505.755,123.592z">
      </path>
    </svg></button></h3>
    
    <div class="accordion-panel">
      <div>
        <div class="accordion-body pb-4 pr-8 text-base md:text-lg leading-relaxed text-gray-700 dark:text-gray-300">
          Not really. In-process support ends November 10, 2026, and it&rsquo;s capped at .NET 8. New projects should scaffold with <code>--worker-runtime dotnet-isolated</code>.
        </div>
      </div>
    </div>
  </div>



  
  
  
  
  

  
  

  <div class="accordion-item" data-open="">
    <h3 class="m-0"><button type="button" class="accordion-header" data-accordion-header aria-expanded="false"><span
      class="accordion-title font-display text-xl md:text-2xl font-bold gradient-text-ooey-gooey">Can these functions become MCP tools later?</span><svg class="accordion-icon"
      viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <path fill="currentColor"
        d="M505.755,123.592c-8.341-8.341-21.824-8.341-30.165,0L256.005,343.176L36.421,123.592c-8.341-8.341-21.824-8.341-30.165,0 s-8.341,21.824,0,30.165l234.667,234.667c4.16,4.16,9.621,6.251,15.083,6.251c5.462,0,10.923-2.091,15.083-6.251l234.667-234.667 C514.096,145.416,514.096,131.933,505.755,123.592z">
      </path>
    </svg></button></h3>
    
    <div class="accordion-panel">
      <div>
        <div class="accordion-body pb-4 pr-8 text-base md:text-lg leading-relaxed text-gray-700 dark:text-gray-300">
          Yes - the same business-focused endpoints can later be wrapped as MCP tools so an AI assistant calls a controlled operation like <code>create_enquiry</code> instead of touching Dataverse directly.
        </div>
      </div>
    </div>
  </div>



  
  
  
  
  

  
  

  <div class="accordion-item" data-open="">
    <h3 class="m-0"><button type="button" class="accordion-header" data-accordion-header aria-expanded="false"><span
      class="accordion-title font-display text-xl md:text-2xl font-bold gradient-text-vital-ocean">Should Dataverse credentials live in `local.settings.json`?</span><svg class="accordion-icon"
      viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <path fill="currentColor"
        d="M505.755,123.592c-8.341-8.341-21.824-8.341-30.165,0L256.005,343.176L36.421,123.592c-8.341-8.341-21.824-8.341-30.165,0 s-8.341,21.824,0,30.165l234.667,234.667c4.16,4.16,9.621,6.251,15.083,6.251c5.462,0,10.923-2.091,15.083-6.251l234.667-234.667 C514.096,145.416,514.096,131.933,505.755,123.592z">
      </path>
    </svg></button></h3>
    
    <div class="accordion-panel">
      <div>
        <div class="accordion-body pb-4 pr-8 text-base md:text-lg leading-relaxed text-gray-700 dark:text-gray-300">
          Only for local development. In production, use Key Vault references or managed identity.
        </div>
      </div>
    </div>
  </div>


          </div>

          
          
          

          
<p>







<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-summary" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">🧾 Summary</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<br/>

















<section
    class="not-prose relative overflow-hidden rounded-xl bg-gradient-to-br from-slate-9001 to-blue-8001 from-main-color-1-dark px-6 py-9 text-white mb-10 dark:ring-1 dark:ring-white/10 hero-banner">

    
    <div class="pointer-events-none absolute -right-16 -top-20 h-72 w-72 rounded-full bg-white/10 blur-3xl"
        aria-hidden="true"></div>

    <div class="relative">
        <h2 class="font-display text-xl md:text-2xl font-medium mb-3 leading-snug"></h2>
        <p class="text-[15.5px] leading-relaxed text-white/90 max-w-4xl">We built a production-ready pattern for using Azure Functions as a Dataverse CRUD backend on the isolated worker model: separate create, update, and delete endpoints, a shared Dataverse service layer using <strong>ServiceClient</strong>, structured request and response models, Application Insights logging, and Key Vault-ready configuration - an architecture that can support SitecoreAI (Sitecore XM Cloud), Next.js, and MCP tools going forward.</p>

        
    </div>
</section></p>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="-next-steps" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">👣 Next Steps</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>
<p>In the next article, we&rsquo;ll explore how to connect these Azure Functions with SitecoreAI and store the processed records in Microsoft Dataverse.</p>
<p><strong>Stay tuned!</strong> 👀</p>
<div class="callout info">
    <div class="callout-head"><svg height=1.2em class="hx:inline-block hx:align-middle" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75.0 011.063.852l-.708 2.836a.75.75.0 001.063.853l.041-.021M21 12A9 9 0 113 12a9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"></path></svg><p>SitecoreAI and Microsoft Dataverse integrations</p>
    </div>
    <div class="callout-body">
        <p><strong><span class="dark:text-gray-300 font-semibold gradient-text-sea-salt">If you&rsquo;re building SitecoreAI and Microsoft Dataverse integrations, start with a clean backend boundary. Don&rsquo;t expose Dataverse complexity to the frontend or AI layer - use Azure Functions to create a secure, observable, MCP-ready service layer instead.</strong>
<br/><br/>
Read the previous article in this series here: <a href="https://www.amitk.net/blog/sitecoreai-dataverse-authentication-connection/" target="_blank" rel="noopener">SitecoreAI Dataverse Authentication and Connection</a>
</span></p>
    </div>
</div>








<div class="flex items-center gap-2 flex-wrap mt-0 !mt-0 p-0" style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">
  
    <h2 id="creditreferences" class="mt-0 !mt-0 pt-0 pb-0 " style="margin-top:0.5em!important;margin-bottom:-0.3em!important;padding-top:0!important;">🧾Credit/References</h2>
  
  
    <span class="go-to-top">
      <a class="go-to-top-a " href="#TableOfContents" title="Go to Top"><svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 11l5-5m0 0l5 5m-5-5v12"/></svg></a>      
    </span>
  
</div>



<div class="table-wrapper">
<table class="style-table"><tbody><tr><td><a href="https://www.amitk.net/blog/sitecoreai-dataverse-integration-dotnet/" target="_blank" rel="noopener"><strong>Introduction to SitecoreAI and Microsoft Dataverse Integration</strong></a>
 Complete architecture guide for connecting SitecoreAI, .NET, Azure Functions, and Microsoft Dataverse</td><td><a href="https://www.amitk.net/blog/sitecoreai-dataverse-authentication-connection/" target="_blank" rel="noopener"><strong>SitecoreAI Dataverse Authentication and Connection</strong></a>
 Configure secure authentication and application access between SitecoreAI and Dataverse</td><td><a href="https://doc.sitecore.com/sai/en/developers/sitecoreai/sitecoreai.html" target="_blank" rel="noopener"><strong>SitecoreAI Documentation for Developers</strong></a>
 Official developer documentation covering SitecoreAI architecture and capabilities</td></tr><tr><td><a href="https://www.amitk.net/blog/build-custom-mcp-server-dotnet-csharp/" target="_blank" rel="noopener"><strong>Building Custom Sitecore MCP Tools in .NET</strong></a>
 Learn how to build custom Model Context Protocol tools using .NET</td><td><a href="https://www.amitk.net/blog/sitecore-marketer-mcp-vscode-integration/" target="_blank" rel="noopener"><strong>Sitecore Marketer MCP Integration with VS Code</strong></a>
 Explore Sitecore MCP capabilities and AI-assisted development workflows</td><td><a href="https://www.amitk.net/blog/mcp-server-vs-copilot-genai-agentic-ai/" target="_blank" rel="noopener"><strong>MCP Server vs Copilot vs GenAI Agentic AI</strong></a>
 Understand differences between MCP servers, copilots, and AI agents</td></tr><tr><td><a href="https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger" target="_blank" rel="noopener"><strong>Azure Functions HTTP Trigger</strong></a>
 Build HTTP-based serverless integrations for SitecoreAI and external systems</td><td><a href="https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide" target="_blank" rel="noopener"><strong>Guide for running C# Azure Functions in the isolated worker model</strong></a>
 Implement modern .NET Azure Functions using isolated worker architecture</td><td><a href="https://learn.microsoft.com/en-us/power-apps/developer/data-platform/sdk-client-transition" target="_blank" rel="noopener"><strong>Dataverse ServiceClient SDK for .NET</strong></a>
 Use Microsoft.PowerPlatform.Dataverse.Client for enterprise Dataverse integrations</td></tr><tr><td><a href="https://www.nuget.org/packages/Microsoft.PowerPlatform.Dataverse.Client/" target="_blank" rel="noopener"><strong>Microsoft.PowerPlatform.Dataverse.Client NuGet Package</strong></a>
 Official .NET SDK package for connecting applications with Microsoft Dataverse</td><td><a href="https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/web-api-basic-operations-sample" target="_blank" rel="noopener"><strong>Dataverse Web API Basic Operations Sample</strong></a>
 Learn CRUD operations using Dataverse Web API</td><td><a href="https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/update-delete-entities-using-web-api" target="_blank" rel="noopener"><strong>Update and Delete Dataverse Records Using Web API</strong></a>
 Manage Dataverse records through REST APIs</td></tr><tr><td><a href="https://doc.sitecore.com/sai/en/developers/sitecoreai/deploying-sitecoreai/deploying-sitecoreai.html" target="_blank" rel="noopener"><strong>SitecoreAI Deployment and Environment Management</strong></a>
 Understand SitecoreAI deployment workflows and environment management</td><td><a href="https://doc.sitecore.com/sai/en/developers/sitecoreai/xm-cloud-plugin.html" target="_blank" rel="noopener"><strong>SitecoreAI XM Cloud Plugin</strong></a>
 Automate SitecoreAI projects using Sitecore CLI tooling</td><td><a href="https://developers.sitecore.com/learn/accelerate/sitecoreai/xmc-quick-reference" target="_blank" rel="noopener"><strong>SitecoreAI Quick Reference Guide</strong></a>
 Practical guidance for planning and implementing SitecoreAI solutions</td></tr><tr><td><a href="https://learn.microsoft.com/en-us/azure/app-service/app-service-key-vault-references" target="_blank" rel="noopener"><strong>Azure Key Vault References for Application Settings</strong></a>
 Secure SitecoreAI integration secrets using Azure Key Vault</td><td><a href="https://learn.microsoft.com/en-us/azure/azure-functions/configure-monitoring" target="_blank" rel="noopener"><strong>Configure Monitoring for Azure Functions</strong></a>
 Monitor serverless integrations with logging and diagnostics</td><td><a href="https://learn.microsoft.com/en-us/azure/architecture/" target="_blank" rel="noopener"><strong>Azure Architecture Center</strong></a>
 Enterprise architecture patterns for Azure cloud solutions</td></tr></tbody>
  
</table>
</div>
]]></content:encoded></item></channel></rss>