Connect a C# ASP.NET Core Blazor Application to Zoho CRM

This guide walks you through the process of integrating your ASP.NET Core Blazor application with Zoho CRM using dotConnect for Zoho CRM — a powerful ADO.NET provider from Devart. You'll set up OAuth authentication, connect to the CRM API, and perform basic data operations (read, insert, delete) directly from your Blazor frontend or backend logic.

Why dotConnect for Zoho CRM?

  • Leverages full ADO.NET support (e.g., ZohoConnection, ZohoCommand).
  • Integrates with EF Core and uses visual modeling with Entity Developer.
  • Works seamlessly across platforms, including .NET MAUI.

Prerequisites

Before starting, ensure you have the following prerequisites in place:

  • Visual Studio 2022: The IDE we use. If you don't have it on your computer, go to the official website to download and install it. We'll use the Community edition.
  • dotConnect for Zoho CRM: A feature-rich ADO.NET provider with Entity Framework, NHibernate, and EF Core support. For installation instructions, refer to the next section.
  • Access to a Zoho CRM account: Required for API access and OAuth credentials.

Download and activate dotConnect for Zoho CRM

30-day free trial version

Download and install dotConnect for Zoho CRM directly on your machine, or use the Devart.Data.Zoho NuGet package.

No license key is required — you can start exploring the product immediately.

Full version

After purchasing the full version, go to your profile's Licenses page. Choose your product and click Details. Here, you'll find the license details and the activation key.

The Licenses page displays license details and the activation key

To activate a connection in your application, add the activation key to the connection string.

Create a .NET project

1. Open your IDE, select Create a new project > Blazor Web App, and click Next.

2. Name your project, for example, ZohoBlazor, specify its location, and click Next.

3. To create the project, click Create.

4. In the Solution Explorer, right-click the created project and select Manage NuGet Packages.

5. On the Browse tab, search for the Devart.Data.Zoho package and install it. Optionally, you can run this command:

dotnet add package Devart.Data.Zoho

Check Zoho CRM objects

1. To connect to Zoho CRM using the built-in Data Explorer, navigate to Tools > Connect to Database.

The Connect to Database option lets connect to Zoho CRM

2. Then, select the Zoho CRM data source, enter a Zoho domain, and click Web Login.

The Add Connection window requires Zoho CRM credentials to establish a connection

3. Log in to your Zoho account and grant access to your Zoho CRM organization.

Devart ADO.NET Provider requests access to your Zoho account

4. After that, select the tables and fields you want to work with, and retrieve the data.

Visual Studio displays data from the selected tables

Get Zoho CRM tokens

OAuth tokens are required to authenticate and connect to Zoho CRM. For more details, refer to the Zoho CRM official documentation.

1. To interact with the Zoho API, you need to obtain a token that grants access to the client service. To do this, go to the Zoho API Console and sign in using your Zoho account credentials.

2. Click Add Client and select Self Client.

3. Fill in the Scope and Scope Description fields.

Zoho API Console interface shows the Self Client configuration screen

4. To get the code, click Create.

The Generated code window provides the Zoho CRM code

5. Copy the generated code, paste it into the appropriate field in the Zoho Console, and click Send. The Refresh Token will be generated automatically.

The Zoho Console allows generating the Refresh token

Establish the connection

In this section, you can find sample code to set up and connect to Zoho CRM, which you can use as is or modify according to your needs.

The following parameters require values:

  • Domain
  • API Version
  • Client ID
  • Client Secret
  • Refresh Token
  • License Key

The code looks as follows; replace the placeholders with your valid Zoho CRM credentials.

string domain = "crm.zoho.com";
string clientId = "**********";
string clientSecret = "**********";
string refreshToken = "**********";
string licenseKey = "**********";

string connectionString = $"Domain={domain};API Version=v2;Client Id={clientId};Client Secret={clientSecret};Refresh Token={refreshToken};License Key={licenseKey}";

Read Zoho CRM data

Now, let's see how to retrieve and display data from Zoho CRM.

Create the AppConfig class

Create a new class file named AppConfig.cs in your project to store the connection string and other configuration settings:

namespace ZohoBlazor
{
    public class AppConfig
    {
        public string Domain { get; }
        public string ClientId { get; }
        public string ClientSecret { get; }
        public string RefreshToken { get; }
        public string LicenseKey { get; }

        public AppConfig()
        {
            Domain = "your-domain";
            ClientId = "your-client-id";
            ClientSecret = "your-client-secret";
            RefreshToken = "your-refresh-token";
            LicenseKey = "your-license-key";
        }

        public string GetConnectionString()
        {
            return $"Domain={Domain};API Version=v2;Client Id={ClientId};Client Secret={ClientSecret};Refresh Token={RefreshToken};License Key={LicenseKey}";
        }
    }
}

Create a service to connect to Zoho CRM

Create ZohoCrmService.cs to manage the connection and data retrieval from Zoho CRM.

using System;
using System.Data;
using Devart.Data.Zoho;

namespace ZohoBlazor {
  public class ZohoCrmService {
    private readonly AppConfig _config;

    public ZohoCrmService(AppConfig config) {
      _config = config;
    }

    public bool CheckConnection() {
      try {
        using(var connection = new ZohoConnection(_config.GetConnectionString())) {
          connection.Open();
          return true;
        }
      } catch (Exception) {
        return false;
      }
    }

    public DataTable GetAccounts() {
      using(var connection = new ZohoConnection(_config.GetConnectionString())) {
        connection.Open();
        var command = new ZohoCommand("SELECT \"Account Name\", Phone, Website, \"Account Type\" FROM Accounts", connection);
        var adapter = new ZohoDataAdapter(command);
        var dataTable = new DataTable();
        adapter.Fill(dataTable);
        return dataTable;
      }
    }
  }
}

The CheckConnection method checks whether a connection to Zoho CRM can be established using the provided configuration. The GetAccounts method retrieves data from the Account table in Zoho CRM. The method initiates the connection to Zoho CRM and executes an SQL command to select specific fields from the table. Also, it uses ZohoDataAdapter to fill DataTable with the results of the query and returns DataTable.

Register the service in Startup.cs

Register ZohoCrmService.cs and AppConfig.cs in the Program.cs file.

// Register AppConfig and ZohoCrmService
builder.Services.AddSingleton<AppConfig>();
builder.Services.AddSingleton<ZohoCrmService>();

Create the Accounts Razor component

Create a new Blazor component named Accounts.razor to display data from the Accounts table.

@page "/accounts"
@using System.Data
@inject ZohoCrmService ZohoCrmService

<h3>Accounts</h3>

@if (isConnected)
{
     <p>Connection Status: <strong>Connected</strong></p>
}
else
{
     <p>Connection Status: <strong>Disconnected</strong></p>
}

@if (accounts != null)
{
     <table class="table">
            <thead>
                   <tr>
                            <th>Account Name</th>
                            <th>Phone</th>
                            <th>Website</th>
                            <th>Account Type</th>
                   </tr>
            </thead>
            <tbody>
                   @foreach (DataRow row in accounts.Rows)
                   {
                        <tr>
                                 <td>@row["Account Name"]</td>
                                 <td>@row["Phone"]</td>
                                 <td>@row["Website"]</td>
                                 <td>@row["Account Type"]</td>
                        </tr>
                   }
           </tbody>
      </table>
}

@code {
     private bool isConnected = false;
     private DataTable accounts;

     protected override void OnInitialized()
     {
         isConnected = ZohoCrmService.CheckConnection();
         if (isConnected)
         {
             accounts = ZohoCrmService.GetAccounts();
         }
     }
}

Add navigation to the Accounts component

Add a navigation link to the Accounts component in the NavMenu.razor component.

<div class="nav-item px-3">
    <NavLink class="nav-link" href="accounts">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Accounts
    </NavLink>
</div>

Run the application and navigate to the Accounts page to see the connection status and the data from the Accounts table.

The Accounts page displays the current connection status

This example provides a basic setup for connecting to Zoho CRM and displaying data from the table in the Blazor application. Make sure to replace the placeholder values in AppConfig.cs with your Zoho CRM credentials.

Insert new data

To further enhance your Blazor application, we'll create a form that adds a new account to Zoho CRM. We'll also create a custom endpoint to handle the form submission. Here's how to do it.

Step 1. Create a form in Accounts.razor

First, let's add a new form to the Accounts.razor component. This form will allow users to input details for a new account and submit them.

<form id="insertAccountForm" onsubmit="event.preventDefault(); window.insertAccount();">
       <input type="text" id="accountName" placeholder="Account Name" required />
       <input type="text" id="phone" placeholder="Phone" required />
       <input type="text" id="website" placeholder="Website" required />
       <input type="text" id="accountType" placeholder="Account Type" required />
       <button type="submit">Insert Account</button>
</form>

Step 2. Add the JavaScript interop functionality to display alerts

To use JavaScript's alert function from Blazor, you need to inject the IJSRuntime service into your component. Paste this code into the @code section of Accounts.razor.

@inject IJSRuntime JsRuntime

Then, in the Solution Explorer, create the Account.cs class.

namespace ZohoBlazor
{
    public class Account
    {
        public string Name { get; set; }
        public string Phone { get; set; }
        public string Website { get; set; }
        public string Type { get; set; }
    }
}

And add the InsertAccount method to ZohoCrmService.cs.

public bool InsertAccount(Account account)
{
    try
    {
        using (var connection = new ZohoConnection(_config.GetConnectionString()))
        {
            connection.Open();
            var command = new ZohoCommand(
                "INSERT INTO Accounts (\"Account Name\", Phone, Website, \"Account Type\") VALUES (:name, :phone, :website, :type)", connection);
            command.Parameters.AddWithValue("name", account.Name);
            command.Parameters.AddWithValue("phone", account.Phone);
            command.Parameters.AddWithValue("website", account.Website);
            command.Parameters.AddWithValue("type", account.Type);
            int rowsAffected = command.ExecuteNonQuery();
            return rowsAffected > 0;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error inserting account: {ex.Message}");
        return false;
    }
}

Step 3. Create a custom endpoint in Program.cs

Next, let's modify the Program.cs file to add a custom endpoint that handles the POST request for adding a new account.

// Custom endpoint for adding an account
app.MapPost("/accounts/insert", async (HttpContext context, ZohoCrmService zohoCrmService) =>
{
    if (context.Request.Query.TryGetValue("AccountName", out var accountName) &&
        context.Request.Query.TryGetValue("Phone", out var phone) &&
        context.Request.Query.TryGetValue("Website", out var website) &&
        context.Request.Query.TryGetValue("AccountType", out var accountType))
    {
        var account = new Account
        {
            Name = accountName,
            Phone = phone,
            Website = website,
            Type = accountType
        };

        bool success = zohoCrmService.InsertAccount(account);
        string message = success ? "Account inserted successfully." : "Failed to insert account. Account may already exist.";
        await context.Response.WriteAsync(message);
    }
    else
    {
        await context.Response.WriteAsync("Invalid request parameters.");
    }
});

Step 4. Update MainLayout.razor

In the MainLayout.razor file, place the JavaScript function inside the article section. This ensures that the script is loaded and available for all components that use this layout.

<script>
    window.insertAccount = async function () {
        const accountName = document.getElementById('accountName')?.value;
        const phone = document.getElementById('phone')?.value;
        const website = document.getElementById('website')?.value;
        const accountType = document.getElementById('accountType')?.value;

        const response = await fetch(`/accounts/insert?
 AccountName=${encodeURIComponent(accountName)}&Phone=${encodeURIComponent(phone)}&Website=${encodeURIComponent(website)}&AccountType=${encodeURIComponent(accountType)}`,
 {
             method: 'POST'
        });
        const message = await response.text();
        alert(message);
        if (message.includes("successfully")) {
            window.location.href = "/accounts";
        }
    };
</script>

When you add the script to MainLayout.razor, it loads once and works across all components that use the layout. This ensures that the insertAccount function is defined and accessible when the form is submitted.

The form in Accounts.razor calls the window.insertAccount function when submitted. This function is now globally available because it is defined in the layout file.

The Accounts page now includes fields for adding new accounts

Let's try to add a new test account.

The window notifies about the successfully inserted account

Click OK to reload the page and see the result.

The Accounts page demonstrates the added account

Delete data

To add the Delete button next to each row in the table and implement the functionality for removing a row from Zoho CRM, you can follow these steps.

Step1. Update ZohoCrmService.cs to include the Delete method

First, add the method to ZohoCrmService.cs that deletes an account based on the account name.

public bool DeleteAccount(string accountName)
{
    try
    {
        using (var connection = new ZohoConnection(_config.GetConnectionString()))
        {
            connection.Open();
            var command = new ZohoCommand(
                "DELETE FROM Accounts WHERE \"Account Name\" = :name", connection);
            command.Parameters.AddWithValue("name", accountName);
            int rowsAffected = command.ExecuteNonQuery();
            return rowsAffected > 0;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return false;
    }
}

Step 2. Add a custom endpoint for deleting an account

In the Program.cs file, add a custom endpoint to remove an account based on its name.

// Custom endpoint for deleting an account
app.MapDelete("/accounts/delete", async (HttpContext context, ZohoCrmService zohoCrmService) =>
{
    if (context.Request.Query.TryGetValue("AccountName", out var accountName))
    {
        bool success = zohoCrmService.DeleteAccount(accountName);
        string message = success ? "Account deleted successfully." : "Failed to delete account.";
        await context.Response.WriteAsync(message);
    }
    else
    {
        await context.Response.WriteAsync("Invalid request parameters.");
    }
});

Step 3. Update Accounts.razor to include Delete buttons

Modify the Accounts.razor component to implement a delete button next to each row in the table. This button will call a JavaScript function to handle the deletion.

<td>
    <a href="#" onclick="event.preventDefault(); window.deleteAccount('@row["Account Name"]')" style="text-decoration: none; color: inherit;">
                        <span style="cursor: pointer; font-size: 1.2em;">❌</span>
    </a>
</td>

Step 4. Add a JavaScript function to delete an account

Add a JavaScript function to handle account deletion. This function will be called when the delete button is clicked. You can place it in the <script> section of MainLayout.razor.

window.deleteAccount = async function(accountName) {
const response = await fetch(`/accounts/delete?AccountName=${encodeURIComponent(accountName)}`, {
            method: 'DELETE'
        });
        const message = await response.text();
        alert(message);
        if (message.includes("successfully")) {
            window.location.href = "/accounts";
        }
    };

Run the application.

The Accounts page now has Delete buttons

Try to delete the test account.

The window informs that the account is successfully deleted

Click OK to check that the account has been deleted.

The Accounts page no longer contains the previously added account

This setup allows you to remove accounts from Zoho CRM and see the updated list of accounts. The alert indicates the success or failure of the operation.

Conclusion

With dotConnect for Zoho CRM, you can quickly connect a .NET Blazor application to Zoho CRM and perform data operations using familiar ADO.NET interfaces. This approach eliminates the need for custom HTTP request handling or manual token management.

dotConnect for Zoho CRM

Get an enhanced ORM-enabled data provider for Zoho CRM and develop .NET applications working with Zoho CRM data quickly and easily!