Building a C# Blazor App with NoSQL and SQL Using HarperDB
Tags: csharp, blazor, harperdb, database
Published: 2022-03-01 14:29:13

This tutorial describes how to use **[HarperDB](https://harperdb.io/)** Database and **[Blazor](https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor)**. For this tutorial, we are going to build a simple **Blazor** .Net Core app using HarperDB. The final source code for this tutorial can be found on this [GitHub repository](https://github.com/Towernter/HarperDB_BlazorAPP).

## What is required to follow along this tutorial 

- Basic knowledge of [C#](https://docs.microsoft.com/en-us/dotnet/csharp/)
- [Visual studio](https://visualstudio.microsoft.com/) (in my case I am using Visual Studio 2019)
- [HarperDB](https://studio.harperdb.io/sign-up) account

## Why HarperDB?

[HarperDB](https://harperdb.io/docs/overview/) has an easy to use REST API which supports both **SQL** and **NoSQL**. It is very simple to use with a wide range of tutorials, support and documentation in different languages like `Python`, `Javascript` and `CSharp`. 

## Setting up our HarperDB database 

1. Create your [HarperDB account](https://studio.harperdb.io/sign-up) 
2. Go to the [HarperDB Studio](https://studio.harperdb.io/sign-up)
3. Create your Organisation
4. Create new HarperDB Cloud instance
5. Create a Schema dev
6. Create two tables dog and breed and set the `hash attr` to `id`

> **NB:** To make it simple, for our pets app we are going to use dogs only

Video tutorial on how to setup your [HarperDB](https://www.youtube.com/watch?v=W4pvuyp-2tk&t=314s) cloud

## Creating our project

1. Open Visual Studio 
2. Click: Create a new Project -> Blazor Web Assembly App

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4rqht9x8p6rf96sl82r.jpg)
3. Click Next

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qc4xjhx66ryfzzj47fgf.jpg)
4. Name your Project `**MyPets**` and click Next

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxj6sk9cfad0z5zei0i9.jpg)
5. Select .Net Core 5 and configurations then click create

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hz0kd8irtmctayv0bymf.jpg)

## Configuring our project

1. Edit Navigation menu (`NavMenu.razor`)
Let’s edit our `MyPets` navigation App by opening the `NavMenu.razor` in the `Shared` folder. We want to add three options, our `Home`, `Add Pets` and lastly the page to `Display Pets`

**Edit the URLs as shown below**

```HTML
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="AddPet">
                <span class="oi oi-plus" aria-hidden="true"></span> Add Pets
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="fetchdata">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Display Pets
            </NavLink>
        </li>
    </ul>
</div>
```
After running the project, our app looks like this

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yabedumq787qjober72o.jpg)

2. Setting up a Home page
Let's rename the `SurveyPrompt.razor` to `HomePage` as follows


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wzx9w9eaw95rividgp5w.jpg)

Change the last line of `Index.razor`. `Index.razor` is found under pages as shown above

```csharp
<SurveyPage Title="How is Blazor working for you?" />
```

To 
```csharp
 <HomePage Title="Explore" />
```

## Adding important imports

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38av8t5xivh5scroz1k1.jpg)
Open `_Imports.razor` and add the following imports 
```csharp
@using MyPets
@using MyPets.Shared
@using MyPets.Helpers;
@using System.Text.Json
```

## Create a Pet class to help us pass the object data from DB

1. Right click your project -> add folder
2. Name the folder `Helpers`
3. Right click `Helpers` folder and add a new Class
4. Name it `Pet`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gekf4ivku48ewkdytcuz.jpg)

Add the following code to your `pet` class

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyPets.Helpers
{
    public class Pet
    {
        public int id { get; set; }
        public string dog_name { get; set; }
        public int breed_id { get; set; }

        public int age { get; set; }
    }
}
```
> NB: To setup your database, DB URL and token can be found in the HarperDB studio account under `config` tab
To find your DB URL and token:

1. Login to [HarperDB Studio](https://studio.harperdb.io/)
2. Click on your instance (if you do not have any instances, click `Create New HarperDB Cloud Instance` to create a new instance
3. Click on the `config` tab
4. Your **HDB URL** is the `Instance URL`
5. Your **Authentication token** is the `Instance API Auth Header (this user)`

## Adding pets to our database
We are going to make use of the existing pages created by our default Razor app. Rename `Counter.Razor`  to `AddPet.razor` in the `Pages` folder and edit it as shown below:
**HTML Section**
```HTML
@page "/AddPet"

<h1>Add a new Dog</h1>
<div class="form-group">
    <input class="form-control" Placeholder="Id" @bind-value="@id"/>
</div>
<div class="form-group">
    <input class="form-control" Placeholder="Dog Name" @bind-value="@dog_name"/>
</div>
<div class="form-group">
    <input class="form-control" Placeholder="BreedID" @bind-value="@breed_id"/>
</div>
<div class="form-group">
    <input class="form-control" Placeholder="Age" @bind-value="@age"/>
</div>
<p>@result</p>
<button class="btn btn-primary" @onclick="AddPets">Add New Pet</button>

```
**C# Code Section**
```csharp
@code {
   //Variables for our inputs
    int id;
    string dog_name;
    int breed_id;
    int age;
    private string result = "";
   //Request and response variables
    HttpRequestMessage requestMessage;
    HttpResponseMessage responseMessage;
    HttpClient http;

    private async void AddPets()
    {
        try
        {
            var postBody = new //our request body
            {

                operation =  "insert",
                schema= "dev",
                table =  "dog",
                records = new[] { new
                {
                    id = id,
                    dog_name = dog_name,
                    breed_id = breed_id,
                    age = age
                    }

                }
            };
            http = new HttpClient();
            requestMessage = new HttpRequestMessage
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri(@"YOUR_HDB_URL_HERE") //DB URl
            };

            requestMessage.Content = JsonContent.Create(postBody);
            http.DefaultRequestHeaders.Add("Authorization", "Basic put_your_token_here");
            responseMessage = await http.SendAsync(requestMessage);
            if (responseMessage.IsSuccessStatusCode)
            {
                result = "New pet added";
            }
        }
        catch (Exception)
        {
            result =responseMessage.ToString();
        }
    }
}
```
> ** NB: **To setup your database, DB URL and token can be found in the HarperDB studio account under `config` tab
To find your DB URL and token:

1. Login to [HarperDB Studio](https://studio.harperdb.io/)
2. Click on your instance (if you do not have any instances, click `Create New HarperDB Cloud Instance` to create a new instance
3. Click on the `config` tab
4. Your **HDB URL** is the `Instance URL`
5. Your **Authentication token** is the `Instance API Auth Header (this user)`

## Display Pets from the database
Edit the code in `FetchData.razor` in the `Pages` folder as shown below 

> **NB:** For this section we will use the HarperDB SQL functionality

**HTML Section**
```HTML
@page "/fetchdata"

<h1>Dogs</h1>
<p>This section demonstrates fetching data from HarperDB</p>
<p> @result</p>
@if (pets == null) //display nothing when our DB is empty
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Dog Name</th>
                <th>Breed</th>
                <th>Age</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var pet in pets)
            {
                <tr>
                    <td>@pet.id</td>
                    <td>@pet.dog_name</td>
                    <td>@pet.breed_id</td>
                    <td>@pet.age</td>
               </tr>
            }
        </tbody>
    </table>
}

```
**C# Code Section**
```csharp
@code {
    HttpRequestMessage requestMessage;
    HttpResponseMessage responseMessage;
    HttpClient http;
    List<Pet> pets; //Pets list to store our pets retrieved from the database
    private string result = "";
    protected override async Task OnInitializedAsync() 
    {
        try
        {
            var postBody = new
            {
                operation = "sql",
                sql = "SELECT * FROM dev.dog WHERE 1"
            };
            http = new HttpClient();
            requestMessage = new HttpRequestMessage
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri(@"YOUR_HDB_URL_HERE")
            };
            requestMessage.Content = JsonContent.Create(postBody);
            http.DefaultRequestHeaders.Add("Authorization", "Basic put_your_token_here");
            responseMessage = await http.SendAsync(requestMessage);
            pets = JsonSerializer.Deserialize // for our HTML table
                    <List<Pet>>(await responseMessage.Content.ReadAsStringAsync());
        }
        catch (Exception)
        {
            result = responseMessage.ToString();
        }
    }
}

```

## Test addition and Display functionality
Let's test out what we have so far:
Start your project in Visual Studio

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xm59ywshgpff0swv6iux.jpg)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rk6odg7kcarkzf532nd3.jpg)

> ** NB: **To setup your database, DB URL and token can be found in the HarperDB studio account under `config` tab
To find your DB URL and token:

1. Login to [HarperDB Studio](https://studio.harperdb.io/)
2. Click on your instance (if you do not have any instances, click `Create New HarperDB Cloud Instance` to create a new instance
3. Click on the `config` tab
4. Your **HDB URL** is the `Instance URL`
5. Your **Authentication token** is the `Instance API Auth Header (this user)`

## Deleting our Pets
We will add the functionality to delete a pet in the display `FetchData.razor` page
Edit the HTML in `FetchData.razor` to add the following table data to your HTML page
```HTML
<td><button class="btn btn-danger" @onclick="() => DeletePet(pet.id)">Delete</button></td>
```
After adding the line your page should look like the one below
```HTML
@page "/fetchdata"

<h1>Dogs</h1>
<p>This section demonstrates fetching data from HarperDB</p>
<p> @result</p>
@if (pets == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Dog Name</th>
                <th>Breed</th>
                <th>Age</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var pet in pets)
            {
                <tr>
                    <td>@pet.id</td>
                    <td>@pet.dog_name</td>
                    <td>@pet.breed_id</td>
                    <td>@pet.age</td>
                    <td><button class="btn btn-danger" @onclick="() => DeletePet(pet.id)">Delete</button></td>
                </tr>
            }
        </tbody>
    </table>
}
```
Add the following `DeletePet()` method to your `@code` section under `OnInitializedAsync()`

```csharp
 //Delete a pet 
    private async void DeletePet(int id)
    {

        try
        {
            var postBody = new
            {

                operation =  "delete",
                schema= "dev",
                table =  "dog",
                hash_values= new[] { id }
            };
            http = new HttpClient();
            requestMessage = new HttpRequestMessage
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri(@"YOUR_HDB_URL_HERE")
            };
            requestMessage.Content = JsonContent.Create(postBody);
            http.DefaultRequestHeaders.Add("Authorization", "Basic put_your_token_here");
            responseMessage = await http.SendAsync(requestMessage);
            if (responseMessage.IsSuccessStatusCode)
            {
                result = "Pet has been deleted";
            }
        }
        catch (Exception)
        {
            result =responseMessage.ToString();
        }

    }
```

## Test Deletion
Start your project in Visual Studio 
Let’s add another pet

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctxfayf1pazgmv2bqoen.jpg)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ii3lw2ixyl84f21qlidl.jpg)

We now have two dogs, test by deleting any of the two


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dfc4oaw2qvv324bo8y8y.jpg)
After deleting Bruno we are now left with one dog (Harper) in the database.

## Conclusion
This tutorial demonstrated how to create a basic C# Blazor app and how to use HarperDB SQL and NoSQL operations in C#.

The Purpose of the `DisplayPets` function was to demonstrate how you can communicate with HarperDB SQL operations and provide an example to make it easy to use other SQL operations provided in the HarperDB API. 

Finally, the `AddPet` and `DeletePet` functions demonstrate how you can add and alter data using HarperDB’s NoSQL operations and to help you get started for any NoSQL reference in HarperDB using C#.