Uncategorized

Ditch CrmServiceClient—Embrace ServiceClient for Better Dataverse Performance!!

Recently, we faced performance issues in our custom C# application that was using CrmServiceClient to connect to Dataverse.

Upon investigation, we discovered that CrmServiceClient internally uses the Organization Service—i.e., the legacy OData V2 endpoint—for Create and Update operations.

According to Microsoft’s official documentation, use of the old OData V2 endpoints is discouraged. While the documentation mainly references client-side code, the same guidance applies to server-side implementations as well.

Microsoft recommends switching to OData V4 (Web API) even for server-side integrations. Although we initially believed that CrmServiceClient, being part of the Microsoft.Xrm.Tooling.Connector NuGet package, would abstract and handle any underlying changes automatically via DLL updates, we realized this was not the case—even when using the latest version.

We later came across an alternative: the ServiceClient class from the Microsoft.PowerPlatform.Dataverse.Client namespace. This client supports a property called UseWebApi, which defaults to false. We explicitly set it to true, and modified our connection logic to use ServiceClient instead of CrmServiceClient.

Upon testing (verified via Fiddler), we confirmed that Create, Update, and Execute operations were now using the OData V4 (Web API) endpoint. This allowed us to retain most of our existing codebase without rewriting it entirely for Web API usage with HttpClient.

Based on this experience, I strongly recommend using ServiceClient for any new tools or executables that interact with Dataverse. It offers better performance, modern authentication support, and a more future-proof architecture.

Hope this helps if you encounter a similar situation.

Uncategorized

Tip-Generate PDFs using Fonts through Azure Function using PDFsharp FontResolver and C#

Recently we had a requirement to change our existing console application to Azure function. The challenging part here was to use the specific fonts which we had installed in the server machine to run the console application and generate the PDF file in desired Font Format.

We created Azure Function of Timer type to run every 10 minutes and copy the supported code in Azure function. Problem was how to reference the specific Fonts in Azure functions.

In order to make the Fonts available in Azure function we uploaded the required Font files of “.ttf” type as you in the Azure Blob container named “sidcon1” as shown below-

After that we created the Environment Variable “BlobConnectionString” in the Azure Function to store the connection string to get the font file as below-

After adding that now we need to set the GlobalFontSettings.FontResolver with the FontResolver object as documented here – https://www.pdfsharp.net/wiki/FontResolver-sample.ashx?AspxAutoDetectCookieSupport=1

So we just added below line in the code along with implementation of FontResolver class.

 var fontResolver = new FontResolver(connectionString, templateBlobContainerName);
 GlobalFontSettings.FontResolver = fontResolver;

One most important thing here I saw was, as the code referenced the FontResolver multiple times we started getting below error in the Azure Functions –

FontResolver – ‘Must not change font resolver after is was once used.’

So after spending couple of hours with the error we figure our that using C# lock mechanism we could get the object set only once, so we added below code to set the GlobalFontSettings as below which ensured that FontResolver was assigned value only once.

(In above code for testing purpose the timer trigger was set to run every 2 minutes)

Below I will add the FontResolver class which I had created in my application to get and set the Fonts from Azure Blob containers while generating PDF

using Azure.Storage.Blobs;
using PdfSharp.Fonts;
using System;
using System.IO;

namespace TrialFunctionApp
{
    // Custom FontResolver implementation
    public class FontResolver : IFontResolver
    {
        string connectionString = string.Empty;
        string containerName = string.Empty;
        public FontResolver(string connectionstring,string containername)
        {
            connectionString = connectionstring ?? string.Empty;
            containerName = containername ?? string.Empty;
        }
        public byte[] GetFont(string faceName)
        {
            // This implementation provides Arial font. You can modify it to load your desired font.
            if (faceName.Contains("Sarabun"))
            {
                return FontHelper.GetFont(connectionString,containerName, "Sarabun-Bold.ttf");
            }
           
            else
            {
                return null;
            }
        }

        public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
        {
            return new FontResolverInfo(familyName,isBold,isItalic);
        }


    }

    // Helper class to load font data
    public static class FontHelper
    {
        public static byte[] GetFont(string connectionString, string containerName, string fontFileName)
        {
            // Create BlobServiceClient using the connection string
            BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);

            // Get a reference to the container
            BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);

            // Get a reference to the font file blob
            BlobClient blobClient = containerClient.GetBlobClient(fontFileName);

            // Download the font file to a memory stream
            MemoryStream memoryStream = new MemoryStream();
            blobClient.DownloadTo(memoryStream);

            // Return the font data as byte array
            return memoryStream.ToArray();
        }
    }

}

The above code ensured that the Fonts were correctly referenced in the Azure functions to generate PDF file.

The PDF generation code remains the standard code as specified by PDFsharp references as below-

https://www.pdfsharp.net/wiki/PDFsharpSamples.ashx

In this blog I have specifically added the Font setting part using custom FontResolver class to help others trying to meet similar requirement.

Hope this helps !!