Microsoft Dynamics 365 CRM is a powerful platform for customer relationship management, but it becomes even more powerful when extended with custom apps. In this blog post, we’ll walk through how to create central CRM use cases in a backend system with .NET 9, connect securely to CRM, and expose functionality through a Blazor frontend.

By the end, you’ll know how to:

  • Access CRM data in a .NET 9 backend service
  • Display CRM records in a Blazor UI
  • Trigger central CRM processes from your Blazor application

Let’s dive in!


1. Setting Up Access to Microsoft Dynamics CRM in .NET 9

First, we need to connect to CRM securely using OAuth 2.0 and the Microsoft.PowerPlatform.Dataverse.Client package (formerly Common Data Service SDK).

Install the Required Packages

bashKopierenBearbeitendotnet add package Microsoft.PowerPlatform.Dataverse.Client --version 1.0.29
dotnet add package Microsoft.Identity.Client --version 4.56.0

Authentication Setup

You’ll authenticate via a registered Azure App (Client Credentials flow).

var connectionString = @"
AuthType=ClientSecret;
Url=https://yourorg.crm.dynamics.com;
ClientId=your-client-id;
ClientSecret=your-client-secret;
TenantId=your-tenant-id;
";

var serviceClient = new ServiceClient(connectionString);

Make sure your app registration in Azure AD has the necessary permissions (Dynamics CRM API access).


2. Accessing CRM Data in the Backend

Once connected, you can fetch CRM data easily. Let’s retrieve a list of Active Contacts.

<code>var query = new QueryExpression("contact")<br>{<br>    ColumnSet = new ColumnSet("firstname", "lastname", "emailaddress1")<br>};<br>query.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0); 
// Active<br><br>var contacts = serviceClient.RetrieveMultiple(query);<br><br>foreach (var contact in contacts.Entities)<br>{<br>    Console.WriteLine($"{contact["firstname"]} {contact["lastname"]} - {contact["emailaddress1"]}");<br>}<br></code>

You can also trigger workflows, create or update entities, and more via the serviceClient.


3. Building the Blazor UI

Next, let’s expose this data in a simple Blazor WebAssembly frontend.

We will build:

  • A Contacts List component
  • A Start Workflow button

Backend API

First, expose an API in your backend:

[ApiController]
[Route("api/[controller]")]
public class ContactsController : ControllerBase
{
private readonly ServiceClient _serviceClient;

public ContactsController(ServiceClient serviceClient)
{
_serviceClient = serviceClient;
}

[HttpGet]
public IActionResult GetContacts()
{
var query = new QueryExpression("contact")
{
ColumnSet = new ColumnSet("contactid", "firstname", "lastname", "emailaddress1")
};
query.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0);

var contacts = _serviceClient.RetrieveMultiple(query);

var result = contacts.Entities.Select(e => new
{
Id = e.Id,
FirstName = e.GetAttributeValue<string>("firstname"),
LastName = e.GetAttributeValue<string>("lastname"),
Email = e.GetAttributeValue<string>("emailaddress1")
}).ToList();

return Ok(result);
}

[HttpPost("{contactId}/start-process")]
public IActionResult StartProcess(Guid contactId)
{
// Trigger a workflow or custom process
var request = new OrganizationRequest("your_custom_action_name")
{
["Target"] = new EntityReference("contact", contactId)
};

_serviceClient.Execute(request);

return Ok();
}
}

Blazor Frontend

Install HttpClient if you haven’t:

bashKopierenBearbeitendotnet add package Microsoft.AspNetCore.Components.WebAssembly

Contacts.razor

<code>@page "/contacts"<br>@inject HttpClient Http<br><br><h3>Contacts</h3><br><br>@if (contacts == null)<br>{<br>    <p><em>Loading...</em></p><br>}<br>else<br>{<br>    <ul><br>        @foreach (var contact in contacts)<br>        {<br>            <li><br>                @contact.FirstName @contact.LastName (@contact.Email)<br>                <button @onclick="() => StartProcess(contact.Id)">Start Process</button><br>            </li><br>        }<br>    </ul><br>}<br><br>@code {<br>    private List<ContactDto> contacts;<br><br>    protected override async Task OnInitializedAsync()<br>    {<br>        contacts = await Http.GetFromJsonAsync<List<ContactDto>>("api/contacts");<br>    }<br><br>    private async Task StartProcess(Guid contactId)<br>    {<br>        await Http.PostAsync($"api/contacts/{contactId}/start-process", null);<br>    }<br><br>    public class ContactDto<br>    {<br>        public Guid Id { get; set; }<br>        public string FirstName { get; set; }<br>        public string LastName { get; set; }<br>        public string Email { get; set; }<br>    }<br>}<br></code>

This Blazor component fetches contacts from your backend API and displays them with a button to start a CRM process per contact.


4. Securing the Application

You should secure both:

  • The backend API (e.g., with Azure AD authentication)
  • The Blazor frontend (by authenticating users and passing access tokens)

Integrate Microsoft.Identity.Web to secure your backend APIs easily.

bashKopierenBearbeitendotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

And protect your API controllers with [Authorize] attributes.


Summary

Extending Microsoft Dynamics CRM with external apps is a great way to centralize your business processes. With .NET 9, a modern backend connects seamlessly to Dynamics using the Dataverse Client, while Blazor provides a slick, reactive frontend UI.

In this tutorial, we covered:

  • Connecting to CRM securely in .NET 9
  • Fetching CRM data in the backend
  • Building a Blazor frontend to display and act on CRM data
  • Starting CRM work processes from the Blazor UI

By integrating these pieces, you enable centralized control over your CRM system without requiring users to navigate the native CRM UI for every action. This improves both productivity and user experience!

Views: 111

Building Central Microsoft Dynamics CRM Use Cases with .NET 9 and Blazor

Johannes Rest


.NET Architekt und Entwickler


Beitragsnavigation


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert