DEV Community

Cover image for Building a C# Blazor App with NoSQL and SQL Using HarperDB
Tawanda Nyahuye
Tawanda Nyahuye

Posted on

Building a C# Blazor App with NoSQL and SQL Using HarperDB

This tutorial describes how to use HarperDB Database and 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.

What is required to follow along this tutorial

Why HarperDB?

HarperDB 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
  2. Go to the HarperDB Studio
  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 cloud

Creating our project

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

Image description

  1. Click Next

Image description

  1. Name your Project **MyPets** and click Next

Image description

  1. Select .Net Core 5 and configurations then click create

Image description

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

<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>
Enter fullscreen mode Exit fullscreen mode

After running the project, our app looks like this

Image description

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

Image description

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

<SurveyPage Title="How is Blazor working for you?" />
Enter fullscreen mode Exit fullscreen mode

To

 <HomePage Title="Explore" />
Enter fullscreen mode Exit fullscreen mode

Adding important imports

Image description
Open _Imports.razor and add the following imports

@using MyPets
@using MyPets.Shared
@using MyPets.Helpers;
@using System.Text.Json
Enter fullscreen mode Exit fullscreen mode

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

Add the following code to your pet class

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; }
    }
}
Enter fullscreen mode Exit fullscreen mode

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
  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

@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>

Enter fullscreen mode Exit fullscreen mode

C# Code Section

@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();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

** 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
  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

@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>
}

Enter fullscreen mode Exit fullscreen mode

C# Code Section

@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();
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Test addition and Display functionality

Let's test out what we have so far:
Start your project in Visual Studio

Image description

Image description

** 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
  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

<td><button class="btn btn-danger" @onclick="() => DeletePet(pet.id)">Delete</button></td>
Enter fullscreen mode Exit fullscreen mode

After adding the line your page should look like the one below

@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>
}
Enter fullscreen mode Exit fullscreen mode

Add the following DeletePet() method to your @code section under OnInitializedAsync()

 //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();
        }

    }
Enter fullscreen mode Exit fullscreen mode

Test Deletion

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

Image description

Image description

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

Image description
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#.

Discussion (0)