Jul 10, 2026

Call Azure Function directly from Plugin

This is step by step guide to explain how to call an Azure Function directly from a Plugin. When I say diretly, we do it in the code level. Other way of doing it is via  webhook. Lets jump in.

Scenario

When we create a Contact in Dataverse (model-driven app), I need to register the contact in the financial system which is best done using an Azure Function. So Approach is I am writing a pre create plugin for Contact which should call Azure Function to get the registration done. For this I am passing Contacts' full name to the function and expecting registration numbers to be passed back to Dataverse.

Create Azure Function

(Refer: https://www.youtube.com/watch?v=NhhmLt0YGqY&t=218s for step by step create of function app)

Here I retrieve name and returning registered number back. (Registering logic is not implemented but to ocestrate the action I am generating a randon number as registration number)

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace Sume4FunctionApp;

public class SumeFunction1
{
    private readonly ILogger<SumeFunction1> _logger;

    public SumeFunction1(ILogger<SumeFunction1> logger)
    {
        _logger = logger;
    }

    [Function("SumeFunction1")]
    public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
    {
        // Retrieve Value
        string name = req.Query["name"];
        _logger.LogInformation($"Azure Function retrieved: {name}");

        // Logic
        // TODO - Register name in Financial System
        string FSID = Guid.NewGuid().ToString("N")[..10];

        // Retern Reg Number 
        return new OkObjectResult(FSID);
    }
}

After local testing, publish the Azure Function in Azure.


Now you can see the Azure Function under Function App.


Under Function Keys, you can retrieve the code which will be used in Plugin code.


Create Plugin

Now its time to call the Azure Function from Plugin code. Plugin is registered in Pre Create with below settings.


Notice how I compile the full name to be passed to function. Also how I retrieve the registration number and set to relevant field which will be populated (since we are in pre-stage just assigning is enough). Notice below steps;

  • We create a class with contact name as attribute to be passed to serializer
  • Serviceurl consist of below 3 components
    • Site Address (from Azure registration of Function App)
    • Function name (As we know from the code)
    • Code (read from function)
(Refer https://www.youtube.com/watch?v=KdGZ2Oo-4L8 to get explanation of steps)

if (execCtx.InputParameters.Contains("Target") && execCtx.InputParameters["Target"] is Entity target 
    && target.LogicalName == "contact")
{
    // Retrieve Name
    var contactDetail = new ContactDetail();
    string firstName = target.Contains("firstname") ? target.GetAttributeValue<string>("firstname") : string.Empty;
    string lastName = target.Contains("lastname") ? target.GetAttributeValue<string>("lastname") : string.Empty;
    ctx.Trace($"Contact Created - First Name: {firstName}, Last Name: {lastName}");
    contactDetail.name = firstName + " " + lastName;

    // Call Azure Function and Pass Contact Name
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ContactDetail));
    MemoryStream memoryStream = new MemoryStream();
    serializer.WriteObject(memoryStream, contactDetail);
    var jsonObject = Encoding.Default.GetString(memoryStream.ToArray());
    var webClient = new WebClient();
    webClient.Headers[HttpRequestHeader.ContentType] = "application/json";
    var code = "eAy22Izpd6kF5VTNHyArUu-I86MkbpVWOJYG9k8M-3L1AzFuGBtDxA==";
    var serviceUrl = "https://sume4functionapp.azurewebsites.net/api/SumeFunction1?code=" + code;
    string response = webClient.UploadString(serviceUrl, jsonObject);

    // Set the retrurned value (Financial system bymber) back to Contact record
    ctx.Trace($"response {response}");
    if (response != null)
        target.Attributes["so_financialsystemid"] = response;
    else
        throw new InvalidPluginExecutionException("Failed registering to FS via Azure Fuction");
}
        public class ContactDetail
        {
            public string name { get; set; }
        }

How it works

Now create Contacts and see how Financial System Id is being populated.


We can monitor this in two places of Azure.

1) Under Invocation of Azure Function as below.     


2) Under Log Stream of Function App. 


This is just a simple example, but hope this gives idea on what needs to do in each component and the sequance. 

Jun 11, 2026

Email Template to populate dynamic values from any entity

 Email Templates of Dynamics 365/ Dataverse is very useful yet its one big limitation is it only can dynamically populate values of a one Entity type. Word Document templates don't have that limitation but it is actually for generation of a document not to use in Email content. Alternatively, Word Document Templates can be used to generate a document and attach to email which is widely done.

Today we will see how to programmatically enhance the usual Email Template to have any value. Below are the steps we do.

1) When creating Email Template, introduce special tags for dynamics values we plan to populate from other entities

2) Create email with Template in Draft status.

3) Replace special tags we introduce (Template will have many other dynamic fields as usual from specific Entity type it designed to fetch data from)

4) Send the Email

Please refer Programmatically create a draft Email using Email Template (C#) for steps 2 and 4.

Lets check how code would flow with the newly introduced method. Obviously values you need to populate should be query first to replace the tags.

// Step 2: Create Draft Email
// email object is defined here

// Step 3: Replace special tags
ReplaceEmailContent(email, "{{Coordinator}}", <Value need to populate>);
ReplaceEmailContent(email, "{{ContractId}}", <Value need to populate>);

// Step 4: Send Email

// Method to call
public Entity ReplaceEmailContent(Entity email, string tagName, string tagValue)
{
    var secondValue = email.Attributes.Values.ElementAt(1);
    if (secondValue is string strValue)
    {
        var replaced = strValue.Replace(tagName, tagValue);
        var key = email.Attributes.Keys.ElementAt(1);
        email.Attributes[key] = replaced;
    }
    return email;
}

Same way, if we need to add dynamics tags to Subject of the email, that's also possible. For that, use below method.

public Entity ReplaceEmailSubject(Entity email, string tagName, string tagValue)
{
    var secondValue = email.Attributes.Values.ElementAt(0);
    if (secondValue is string strValue)
    {
        var replaced = strValue.Replace(tagName, tagValue);
        var key = email.Attributes.Keys.ElementAt(0);
        email.Attributes[key] = replaced;
    }
    return email;
}