How to Connect .NET Blazor App to QuickBooks Online
The integration of QuickBooks Online into your .NET Blazor application allows for easy access to financial data, which enhances the efficient management of customer information, invoices, and more.
This tutorial demonstrates how to connect a Blazor Server App to QuickBooks Online using dotConnect for QuickBooks Online, with a particular focus on performing CRUD operations within the Customer table.
Why dotConnect for QuickBooks Online?
dotConnect for QuickBooks Online is a high-performance ADO.NET data provider that simplifies integration with QuickBooks Online.
The key benefits of this data provider include:
- Standard ADO.NET Interface: Utilizes familiar ADO.NET classes like QuickBooksConnection, QuickBooksCommand, and QuickBooksDataReader, thus reducing the learning curve.
- SQL Support: Allows execution of SQL queries directly against QuickBooks data, which eliminates the need for navigating complex APIs.
- Visual Studio Integration: Offers design-time support and integration with Visual Studio, enhancing developer productivity.
- Broad Compatibility: Supports various .NET platforms, including Blazor, WPF, MAUI, and Windows Forms.
- ORM Support: Includes support for Entity Framework Core, Dapper, NHibernate, and more.
Prerequisites
To get started, you will need the following prerequisites:
- Visual Studio 2022: Our IDE of choice for .NET and C++ developers on Windows. If you do not have it on your machine, go to the official website to download and install it. We will be using the Community version, so you can get it as well.
- dotConnect for QuickBooks Online: A feature-rich ADO.NET provider with EF Core, NHibernate, and LinqConnect support.
- QuickBooks Online account: An active QBO account to access your financial data.
Download and activate dotConnect for QuickBooks Online
30-day free trial version
Download and install dotConnect for QuickBooks Online directly on your machine, or install the Devart.Data.QuickBooks NuGet package.
No license key is required, and you can start exploring the product immediately.
Full version
After purchasing the full software 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.
To activate a connection in your application, add the License Key to your connection string.
Set up a QuickBooks workspace and create an app
This tutorial provides step-by-step instructions to create a QuickBooks workspace and set up a new app within the Intuit Developer platform. Follow the steps below to get started.
1. Go to the Intuit Developer portal, log in to your account, and create a new workspace if you don't have one.
2. To proceed, create a new app in your workspace by following the prompts.
3. Enter a name for your app and confirm the creation.
Once your app is ready, you will be able to get the credentials required for the connection.
4. In the Create a new app window, turn on the Show credentials toggle to view your development credentials.
Get QuickBooks credentials
Once you’ve set up your workspace and app, you need to get the necessary credentials to connect to your application.
The following instructions will walk you through the process of obtaining your QuickBooks credentials using the OAuth 2.0 Playground.
1. First, select your workspace and app.
Now, you will see your Client ID and Client Secret displayed.
2. Click Get authorization code.
3. When prompted, select Connect to confirm the connection to your app.
4. Select Get tokens to retrieve the access token.
And finally, the last thing you will need for a successful connection is the refresh token.
5. Copy the refresh token for use in your application.
For detailed guidance, we suggest visiting Intuit's official Get started documentation page.
Create a .NET project
Here, we’ll show you how to create a new .NET Blazor project using Visual Studio and install the necessary NuGet packages to enable communication with QuickBooks data services.
1. Open your IDE (here, we will be using Visual Studio) and select Create a new Blazor project.
2. Name your project, for example, QBOBlazor.
3. In Solution Explorer, right-click the project and select Manage NuGet Packages.
4. Search for and install the following packages: Devart.Data.QuickBooks.
Alternatively, you can run the following command in the terminal:
dotnet add package Devart.Data.QuickBooks
Verify data source objects using Data Explorer
Below, you will find the instructions on how to check your QuickBooks data source using the built-in Data Explorer tool that comes with Visual Studio.
1. To connect to QuickBooks through the Data Explorer, right-click Data Connections and choose Add Connection.
2. In the Add Connection dialog, select QuickBooks Online Data Source as the data source, and click the Web Login button to get the credentials.
3. To finalize, click Test Connection to verify the connectivity.
4. In case the connection test is successful, click OK to save it.
Once connected, you can browse QuickBooks tables, execute queries, and manage data directly in Data Explorer.
Create a connection
Upon completing the previous steps, you will have all the necessary components to establish a connection. Here, you'll find the sample code that will help you connect to QuickBooks Online. Execute this code by applying the following credentials: Client Id, Company Id, Client Secret, Refresh token, and License key. Additionally, set Sandbox to true, if you are using the sandbox application type.
Update appsettings.json
Store your QuickBooks Online credentials securely in the appsettings.json file for use in your Blazor application by running the code shown below.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"QuickBooks": {
"ClientId": "**********",
"CompanyId": "**********",
"ClientSecret": "**********",
"RefreshToken": "**********",
"LicenseKey": "**********"
}
}
Create a configuration class
Create a class to map the QuickBooks settings from the appsettings.json file. This class enables your application to read and use the stored credentials. To proceed, add the following code to define the QuickBooksSettings class.
namespace QBOBlazor
{
public class QuickBooksSettings
{
public string ClientId { get; set; } = string.Empty;
public string CompanyId { get; set; } = string.Empty;
public string ClientSecret { get; set; } = string.Empty;
public string RefreshToken { get; set; } = string.Empty;
public string LicenseKey { get; set; } = string.Empty;
}
}
Further in this tutorial, we are going to use our project to illustrate the Read, Insert, and Delete operations.
Read QuickBooks data
In the following sections of this tutorial, we’ll give you step-by-step instructions for creating a service to connect to QuickBooks, accessing customer data, registering the service, building a Blazor component to display the data, and adding navigation for user access.
Create a service to connect to QuickBooks
Add a new class QuickBooksService.cs for QuickBooks data access by executing the following code.
using System;
using System.Collections.Generic;
using System.Data;
using Devart.Data.QuickBooks;
using Microsoft.Extensions.Configuration;
namespace QBOBlazor.Services
{
public class QuickBooksService
{
private readonly QuickBooksSettings _settings;
public QuickBooksService(IConfiguration configuration)
{
_settings = configuration.GetSection("QuickBooks").Get < QuickBooksSettings > () ?? new QuickBooksSettings();
}
public bool CheckConnection()
{
try
{
using (var connection = new QuickBooksConnection())
{
connection.ConnectionString = $"ClientId={_settings.ClientId};CompanyId={_settings.CompanyId};ClientSecret={_settings.ClientSecret};RefreshToken={_settings.RefreshToken};LicenseKey={_settings.LicenseKey};Sandbox=true;";
connection.Open();
return true;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
public List < Dictionary < string, object >> GetCustomers()
{
var customers = new List < Dictionary < string, object >>();
using (var connection = new QuickBooksConnection())
{
connection.ConnectionString = $"ClientId={_settings.ClientId};CompanyId={_settings.CompanyId};ClientSecret={_settings.ClientSecret};RefreshToken={_settings.RefreshToken};LicenseKey={_settings.LicenseKey};Sandbox=true;";
connection.Open();
using (var command = new QuickBooksCommand("SELECT Id, DisplayName, PrimaryPhone_FreeFormNumber, PrimaryEmailAddr_Address, BillAddr_City FROM Customer", connection))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var customer = new Dictionary < string, object >
{
{ "Id", reader["Id"] },
{ "DisplayName", reader["DisplayName"] },
{ "PrimaryPhone", reader["PrimaryPhone_FreeFormNumber"] },
{ "PrimaryEmail", reader["PrimaryEmailAddr_Address"] },
{ "BillAddrCity", reader["BillAddr_City"] }
};
customers.Add(customer);
}
}
}
}
return customers;
}
}
}
The CheckConnection method
This approach aims to establish a connection returning true upon success and false if it fails.
The GetCustomers method
This method executes a SQL query to fetch the first 100 customers and returns the results as List < Dictionary < string, object >>.
Register the service in Program.cs
You will register QuickBooksService as a singleton service in the Program.cs file, which configures the services and middleware for the application. To achieve this, execute the code that follows.
builder.Services.AddSingleton<QuickBooksService>();
Create a Blazor component to display customers
For creating a new CustomerList.razor component in the Pages folder, run this code.
@page "/customers"
@inject QBOBlazor.Services.QuickBooksService QuickBooksService
<h1>Customers</h1>
@if (isConnected)
{
<table class="table">
<thead>
<tr>
<th>Display Name</th>
<th>Primary Phone</th>
<th>Primary Email</th>
<th>Billing City</th>
</tr>
</thead>
<tbody>
@foreach (var customer in customers)
{
<tr>
<td>@customer["DisplayName"]</td>
<td>@customer["PrimaryPhone"]</td>
<td>@customer["PrimaryEmail"]</td>
<td>@customer["BillAddrCity"]</td>
</tr>
}
</tbody>
</table>
}
else
{
<p>Failed to connect to QuickBooks.</p>
}
@code {
private bool isConnected = false;
private List<Dictionary<string, object>> customers = new List<Dictionary<string, object>>();
protected override async Task OnInitializedAsync()
{
isConnected = QuickBooksService.CheckConnection();
if (isConnected)
{
customers = QuickBooksService.GetCustomers();
}
}
}
Add navigation to the Customers page
Here, we will show you how to add a NavLink to the NavMenu.razor component, which creates a link to the Customers page. Therefore, you need to update the NavMenu.razor component to include a link to the Customers page. To achieve this, run the command below.
<div class="nav-item px-3">
<NavLink class="nav-link" href="customers">
<span class="oi oi-list-rich" aria-hidden="true"></span> Customers
</NavLink>
</div>
Build and run your application
The following example provides a basic setup to connect to QuickBooks Online and fetch data from the Customers table in a Blazor Server application. Make sure to handle exceptions and errors appropriately in a production environment beforehand.
Insert data
To add a form that inserts a new customer into the QuickBooks Online database, you can create a method in the QuickBooksService class to handle the insertion. Then, you can add a form in the CustomerList.razor component to trigger this insertion.
Update QuickBooksService.cs
Add a method to insert a new customer into the QuickBooks Online database:
public bool InsertCustomer(string displayName)
{
try
{
using (var connection = new QuickBooksConnection())
{
connection.ConnectionString = $"ClientId={_settings.ClientId};CompanyId={_settings.CompanyId};ClientSecret={_settings.ClientSecret};RefreshToken={_settings.RefreshToken};LicenseKey={_settings.LicenseKey};Sandbox=true;";
connection.Open();
using (var command = new QuickBooksCommand(
"INSERT INTO Customer (DisplayName) VALUES (:DisplayName)", connection))
{
command.Parameters.AddWithValue(":DisplayName", displayName);
command.ExecuteNonQuery();
return true;
}
}
}
catch (Exception ex) when (ex.Message.Contains("The name supplied already exists"))
{
Console.WriteLine("Customer with the same name already exists.");
return false;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
Update CustomerList.razor
Add a form to insert a new customer and display the result of the insertion:
@page "/customers"
@inject QBOBlazor.Services.QuickBooksService QuickBooksService
@inject IJSRuntime JSRuntime
<h1>Customers</h1>
<form id="insertCustomerForm" onsubmit="event.preventDefault(); insertCustomer();">
<input type="text" id="newCustomerName" placeholder="Enter customer name" required />
<button type="submit">Insert Customer</button>
</form>
@if (isConnected)
{
<table class="table">
<thead>
<tr>
<th>Display Name</th>
<th>Primary Phone</th>
<th>Primary Email</th>
<th>Billing City</th>
</tr>
</thead>
<tbody>
@foreach (var customer in customers)
{
<tr>
<td>@customer["DisplayName"]</td>
<td>@customer["PrimaryPhone"]</td>
<td>@customer["PrimaryEmail"]</td>
<td>@customer["BillAddrCity"]</td>
</tr>
}
</tbody>
</table>
}
else
{
<p>Failed to connect to QuickBooks.</p>
}
<script>
async function insertCustomer() {
const newCustomerName = document.getElementById('newCustomerName').value;
const response = await fetch(`/customers/insert?newCustomer=${newCustomerName}`);
const message = await response.text();
alert(message);
if (message.includes("successfully")) {
window.location.href = "/customers";
}
}
</script>
@code {
private bool isConnected = false;
private List<Dictionary<string, object>> customers = new List<Dictionary<string, object>>();
protected override void OnInitialized()
{
isConnected = QuickBooksService.CheckConnection();
if (isConnected)
{
customers = QuickBooksService.GetCustomers();
}
}
}
Update Program.cs
In Blazor Server, you can create a custom endpoint. Modify the Program.cs file to add a custom endpoint for handling the GET request:
app.MapGet("/customers/insert", async (HttpContext context, QuickBooksService quickBooksService) =>
{
if (context.Request.Query.TryGetValue("newCustomer", out var newCustomer))
{
bool success = quickBooksService.InsertCustomer(newCustomer);
string message = success ? "Customer inserted successfully." : "Failed to insert customer. Customer may already exist.";
await context.Response.WriteAsync(message);
}
});
At this configuration stage, you can run the application.
Now, add a new customer. To do this, enter a new customer name and click Insert Customer.
In case of a successful outcome of this action, a corresponding message appears.
Remove data
To add a remove method and a remove link to each row in the table, you'll need to modify the QuickBooksService class to include a method for deleting a customer by their ID. Then, you'll update the CustomerList.razor component to include a remove link for each row in the table.
Update QuickBooksService.cs
Add a method to delete a customer by their ID:
public bool DeleteCustomer(string customerId)
{
try
{
using (var connection = new QuickBooksConnection())
{
connection.ConnectionString = $"ClientId={_settings.ClientId};CompanyId={_settings.CompanyId};ClientSecret={_settings.ClientSecret};RefreshToken={_settings.RefreshToken};LicenseKey={_settings.LicenseKey};Sandbox=true;";
connection.Open();
using (var command = new QuickBooksCommand(
"DELETE FROM Customer WHERE Id = :Id", connection))
{
command.Parameters.AddWithValue(":Id", customerId);
command.ExecuteNonQuery();
return true;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
Update Program.cs
Modify the Program.cs file to add a custom endpoint for handling DELETE request:
app.MapGet("/customers/delete", async (HttpContext context, QuickBooksService quickBooksService) =>
{
if (context.Request.Query.TryGetValue("customerId", out var customerId))
{
bool success = quickBooksService.DeleteCustomer(customerId);
string message = success ? "Customer deleted successfully." : "Failed to delete customer.";
await context.Response.WriteAsync(message);
}
});
Update CustomerList.razor
Add a remove link to each row in the table and handle the removal using JavaScript:
@page "/customers"
@inject QBOBlazor.Services.QuickBooksService QuickBooksService
@inject IJSRuntime JSRuntime
<h1>Customers</h1>
<form id="insertCustomerForm" onsubmit="event.preventDefault(); insertCustomer();">
<input type="text" id="newCustomerName" placeholder="Enter customer name" required />
<button type="submit">Insert Customer</button>
</form>
@if (isConnected)
{
<table class="table">
<thead>
<tr>
<th>Display Name</th>
<th>Primary Phone</th>
<th>Primary Email</th>
<th>Billing City</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach (var customer in customers)
{
<tr>
<td>@customer["DisplayName"]</td>
<td>@customer["PrimaryPhone"]</td>
<td>@customer["PrimaryEmail"]</td>
<td>@customer["BillAddrCity"]</td>
<td>
<a href="#" onclick="event.preventDefault(); deleteCustomer('@customer["Id"]');">Remove</a>
</td>
</tr>
}
</tbody>
</table>
}
else
{
<p>Failed to connect to QuickBooks.</p>
}
<script>
async function insertCustomer() {
const newCustomerName = document.getElementById('newCustomerName').value;
const response = await fetch(`/customers/insert?newCustomer=${newCustomerName}`);
const message = await response.text();
alert(message);
if (message.includes("successfully")) {
window.location.href = "/customers";
}
}
async function deleteCustomer(customerId) {
const response = await fetch(`/customers/delete?customerId=${customerId}`);
const message = await response.text();
alert(message);
if (message.includes("successfully")) {
window.location.href = "/customers";
}
}
</script>
@code {
private bool isConnected = false;
private List<Dictionary<string, object>> customers = new List<Dictionary<string, object>>();
protected override void OnInitialized()
{
isConnected = QuickBooksService.CheckConnection();
if (isConnected)
{
customers = QuickBooksService.GetCustomers();
}
}
}
This setup adds a remove method to the QuickBooksService class and a remove link to each row in the table. The JavaScript function deleteCustomer handles the removal by sending a DELETE request to the custom endpoint /customers/delete.
To proceed, let’s run the application.
Now, you can delete a customer from the table.
Conclusion
By following the steps outlined in this tutorial, you can integrate your .NET Blazor application with QuickBooks Online using dotConnect for QuickBooks Online. Here, you’ve learned how to establish a secure connection, query customer data, add new records, and delete entries—all using standard ADO.NET interfaces with minimal overhead.
If you want to get some firsthand experience, feel free to download dotConnect for QuickBooks Online for a free 30-day trial and give it a try under the real workload. To help you get started as quickly and efficiently as possible, we recommend referring to our documentation, which contains valuable tips and walkthroughs.