Create a Web application to read the data

In the previous post, we created a .NET console app to load data in Azure Cosmos DB for NoSQL. In this post, we are going to create an ASP.NET web application to display data from the database.

Note: This series is a part of the Festive Tech Calendar, C# Advent Calendar, and .NET Advent Calendar. Be sure to check them out!

We are using an ASP.NET web application to display the records from Azure Cosmos DB for NoSQL. We first want to run this on localhost, and we want to do this with no passwords involved. What does this look like?

Create the Web App and add dependencies

We are using the .NET 6.0 SDK for this example due to its LTS state. However, you can achieve this with .NET 7 as well. First, create the web app:

dotnet new webapp

Once the project is created, then add references to two dependencies – the Azure Identity package and the Azure Cosmos SDK for .NET.

dotnet add package Azure.Identity --version=1.*
dotnet add package Microsoft.Azure.Cosmos

Create the Creatures model

In our web application, we want to display creatures. Our creatures have the following properties:

  • CreatureId
  • Name
  • Description
  • IsNaughty

We will create a Creature class to represent our creatures.

  1. In the project, create a folder called Models.
  2. In the Models folder, add a file named Creature.cs.
  3. Add the following code to this new file:
using Newtonsoft.Json;

public class Creature {
    [JsonProperty("id")]
    public string CreatureId {get;set; } = Guid.NewGuid().ToString();
    public string Name {get; set;} = "";
    public string Description {get;set;} = "";
    public bool IsNaughty { get;set; } = false;
    public Creature() {

    }

    public Creature(string name, string description){
        Name = name;
        Description = description;
    }
}

We need to mark the CreatureId field as a JsonProperty to assist in converting from JSON to a Creature object.

Add a Service layer

We will create a service layer to handle calling to Azure Cosmos DB to get the data. When we create the service layer, we will have 2 files:

  • CosmosHelper – to assist with setting up the connection to Azure Cosmos DB. This is the same CosmosHelper.cs file we used for the .NET console app for loading the data.
  • CreateHelper – to handle the queries to the Creature database

We will store our services in a folder called Services.

  1. In the root of the project, create a folder named Services.
  2. Within the Services folder, create a file named CosmosHelper.cs.
  3. Copy the following code into CosmosHelper.cs:
using Azure.Identity;
using Microsoft.Azure.Cosmos;

public class CosmosHelper
{
    CosmosClient client;

    private static string CosmosUri => Environment.GetEnvironmentVariable("COSMOS_URI") ?? throw new ArgumentException("Missing env var: COSMOS_URI");
    private static string DatabaseName = "HolidayCreatures";
    private static string ContainerName = "Creatures";
    private static string PartitionKey = "/id";

    public CosmosHelper()
    {
        ChainedTokenCredential credential = new ChainedTokenCredential(new AzureCliCredential(),new ManagedIdentityCredential());

        client = new(
            accountEndpoint: CosmosUri,
            tokenCredential: credential);
    }

    async public Task<Database> GetDatabase()
    {
        Database database = await client.CreateDatabaseIfNotExistsAsync(
            id: DatabaseName
        );

        return database;
    }

    async public Task<Container> GetContainer()
    {
        Database database = await GetDatabase();

        Container container = await database.CreateContainerIfNotExistsAsync(
            id: ContainerName,
            partitionKeyPath: PartitionKey,
            throughput: 400
        );

        return container;
    }        
}

4. Also within the Services folder, create a file named CreatureHelper.cs.
5. Copy the following code for CreatureHelper.cs:

using Microsoft.Azure.Cosmos;

public class CreatureHelper{

    public CreatureHelper(){}

    public async static Task<IEnumerable<Creature>> RetrieveAllCreaturesAsync(){
        CosmosHelper cosmosHelper = new();
        Container container = cosmosHelper.GetContainer().Result;
        List<Creature> creatures = new();
        using FeedIterator<Creature> feed = container.GetItemQueryIterator<Creature>(
            queryText: "SELECT * FROM Creatures"
        );
        while (feed.HasMoreResults)
        {
            FeedResponse<Creature> response = await feed.ReadNextAsync();

            // Iterate query results
            foreach (Creature creature in response)
            {
                creatures.Add(creature);
            }
        }
        return creatures;
    }
}

The CosmosHelper will use the COSMOS_URI environment variable that we set up for the .NET console application. If you want to try read-only access, you can try updating the value with the read-only URI for use with the web application.

Now that we have our helpers in our service folder, let’s call them from the web app.

Update the Index model

Let’s add a list of creatures to our Index model so that we can display them on the site.

  1. Open Pages/Index.cshtml.cs.
  2. Within the IndexModel class, add a property called Creatures of type List<Creature>.
public List<Creature> Creatures = new();

3. In the OnGet() method, add a link to populate this list of creatures using the CreatureHelper.RetrieveAllCreaturesAsync() method. Your OnGet() message should look like this:

public void OnGet()
    {
        Creatures = CreatureHelper.RetrieveAllCreaturesAsync().Result.ToList();
    }

Update the Index Razor syntax

Once you’re getting data back, you need to update the Razor syntax to display the creature values. We’re using a table, though if you have any front-end creativity, feel free to edit it.

This is our Pages/Index.cshtml file:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}
<style>
    th, td {
        text-align: left;
    }
</style>
<div class="text-center">
    <h1 class="display-4">Holiday Creatures</h1>
    <hr />
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Description</th>
            </tr>
        </thead>
        <tbody>
            @foreach (Creature creature in Model.Creatures){
                <tr>
                    <td>@creature.Name</td>
                    <td>@creature.Description</td>
                </tr>
            }
        </tbody>
    </table>
</div>

Run the website locally

At this point, you should be able to run the website locally. As we are using a ChainedTokenCredential with the Azure Cosmos DB client, it will try to use the Azure CLI credentials for the command session where we call dotnet run.

Run the app with:

dotnet run

When the site loads, the creatures should appear from the Azure Cosmos DB for NoSQL database.

In the next post, we will deploy this code to Azure App Service and connect to Azure Cosmos DB with our read-only role and the App Service’s managed identity.

By sadukie

3 thoughts on “Create a Web application to read the data”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.